From 0f26e35f2c54ab49992a5c502978181e92239078 Mon Sep 17 00:00:00 2001 From: kkerwin Date: Fri, 3 May 2024 00:11:26 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9F=BA=E7=A1=80=E6=95=B0=E6=8D=AE=20&=20?= =?UTF-8?q?=E4=BA=BA=E4=BA=8B=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web-admin-app/README.md | 34 ++- web-admin-app/proxy/devserver.js | 2 +- web-admin-app/src/app/app.config.ts | 20 +- web-admin-app/src/app/app.routes.ts | 85 +++++- ...mponent-basic-category-tree.component.html | 64 ++++ ...mponent-basic-category-tree.component.less | 7 + ...component-basic-category-tree.component.ts | 153 ++++++++++ .../component-org-tree.component.html | 113 +++++++ .../component-org-tree.component.less | 7 + .../component-org-tree.component.ts | 186 ++++++++++++ web-admin-app/src/app/components/index.ts | 8 +- .../components/layout/layout.component.less | 15 - .../app/components/layout/layout.component.ts | 14 - .../select-user-by-org.component.html | 74 +++++ .../select-user-by-org.component.less | 21 ++ .../select-user-by-org.component.ts | 128 ++++++++ web-admin-app/src/app/guards/auth.guard.ts | 23 +- .../component-org-tree.component.html | 23 -- .../component-org-tree.component.ts | 58 ---- .../pages/dashboard/dashboard.component.ts | 3 +- .../basic-category.component.html | 63 ++++ .../basic-category.component.less} | 0 .../basic-category.component.ts | 82 ++++++ .../basic-goods-stock.component.html | 1 + .../basic-goods-stock.component.less} | 0 .../basic-goods-stock.component.ts | 12 + .../basic-maintainer.component.html | 108 +++++++ .../basic-maintainer.component.less} | 0 .../basic-maintainer.component.ts | 136 +++++++++ .../basic-manufacturer.component.html | 75 +++++ .../basic-manufacturer.component.less} | 0 .../basic-manufacturer.component.ts | 130 +++++++++ .../basic-supplier.component.html | 108 +++++++ .../basic-supplier.component.less} | 0 .../basic-supplier.component.ts | 135 +++++++++ .../basic-warehouse.component.html | 77 +++++ .../basic-warehouse.component.less | 0 .../basic-warehouse.component.ts | 125 ++++++++ .../save-position.component.html | 55 ++++ .../save-position.component.less | 0 .../save-position/save-position.component.ts | 122 ++++++++ .../fixed-asset/fixed-asset.component.html | 48 ++- .../fixed-asset/fixed-asset.component.less | 10 +- .../fixed-asset-belong.component.ts | 4 +- .../fixed-asset-category.component.ts | 2 +- .../fixed-asset-employee.component.ts | 2 +- .../fixed-asset-ledger.component.ts | 4 +- .../fixed-asset-myown.component.ts | 2 +- .../fixed-asset-org.component.ts | 2 +- .../fixed-asset-position.component.ts | 2 +- .../fixed-asset-search.component.ts | 2 +- .../fixed-asset-manage-allot.component.ts | 6 +- .../fixed-asset-manage-borrow.component.ts | 6 +- ...xed-asset-manage-distribution.component.ts | 6 +- .../fixed-asset-manage-entry.component.ts | 6 +- .../fixed-asset-manage-return.component.ts | 6 +- .../fixed-asset-manage-revert.component.ts | 6 +- .../fixed-asset-manage-scrap.component.ts | 6 +- .../fixed-asset-manage-transfer.component.ts | 6 +- .../fixed-asset-manage.component.ts | 6 +- .../stockaking-job.component.html | 179 ++++++++++++ .../stockaking-job.component.less | 0 .../stockaking-job.component.ts | 162 ++++++++++ .../stockaking-plan.component.html | 1 + .../stockaking-plan.component.less | 0 .../stockaking-plan.component.ts | 21 ++ .../src/app/pages/login/login.component.less | 7 +- .../src/app/pages/login/login.component.ts | 9 +- .../org-setting/org-setting.component.html | 164 +++++++++-- .../org-setting/org-setting.component.ts | 220 +++++++++----- .../profile-account.component.ts | 34 +-- .../profile-basic/profile-basic.component.ts | 13 +- .../app/pages/profile/profile.component.html | 12 +- .../app/pages/profile/profile.component.ts | 4 +- .../system/{ => index}/system.component.html | 1 + .../pages/system/index/system.component.less | 0 .../system/{ => index}/system.component.ts | 0 .../system-user/system-user.component.html | 1 + .../system-user/system-user.component.less | 0 .../system-user/system-user.component.ts | 11 + web-admin-app/src/app/services/api.dto.ts | 16 +- web-admin-app/src/app/services/api.service.ts | 276 ++++++++---------- .../local-http-interceptor.service.ts | 60 +--- .../app-page/app-page.component.html | 0 .../app-page/app-page.component.less | 0 .../components/app-page/app-page.component.ts | 2 - .../form-error-tips.component.html | 0 .../form-error-tips.component.less | 0 .../form-error-tips.component.ts | 0 .../components/header/header.component.html | 2 +- .../components/header/header.component.less | 0 .../components/header/header.component.ts | 10 +- .../src/app/shared/components/index.ts | 6 + .../components/layout/layout.component.html | 0 .../components/layout/layout.component.less | 15 + .../components/layout/layout.component.ts | 8 + .../range-picker/range-picker.component.html | 0 .../range-picker/range-picker.component.less | 0 .../range-picker/range-picker.component.ts | 0 .../date-query/date-query.component.html | 0 .../date-query/date-query.component.less | 0 .../date-query/date-query.component.ts | 0 .../server-paginated-table/index.ts | 0 .../query-item/query-item.component.html | 0 .../query-item/query-item.component.less | 3 +- .../query-item/query-item.component.ts | 0 .../server-paginated-table.component.html | 35 ++- .../server-paginated-table.component.less | 0 .../server-paginated-table.component.ts | 4 + .../server-paginated-table.module.ts | 0 .../server-paginated-table.service.ts | 0 .../table-action.directive.ts | 0 .../table-form.directive.ts | 0 .../user-form/user-form.component.html | 0 .../user-form/user-form.component.less | 0 .../user-form/user-form.component.ts | 3 +- web-admin-app/src/app/shared/shared.module.ts | 26 +- web-admin-app/src/app/types/http.ts | 4 +- .../src/assets/images/jiluo_logo.png | Bin 0 -> 29332 bytes web-admin-app/src/assets/images/login-bg.jpg | Bin 919450 -> 237434 bytes web-admin-app/src/assets/images/logo.png | Bin 5223 -> 0 bytes web-admin-app/src/styles.less | 13 + 122 files changed, 3132 insertions(+), 589 deletions(-) create mode 100644 web-admin-app/src/app/components/component-basic-category-tree/component-basic-category-tree.component.html create mode 100644 web-admin-app/src/app/components/component-basic-category-tree/component-basic-category-tree.component.less create mode 100644 web-admin-app/src/app/components/component-basic-category-tree/component-basic-category-tree.component.ts create mode 100644 web-admin-app/src/app/components/component-org-tree/component-org-tree.component.html create mode 100644 web-admin-app/src/app/components/component-org-tree/component-org-tree.component.less create mode 100644 web-admin-app/src/app/components/component-org-tree/component-org-tree.component.ts delete mode 100644 web-admin-app/src/app/components/layout/layout.component.less delete mode 100644 web-admin-app/src/app/components/layout/layout.component.ts create mode 100644 web-admin-app/src/app/components/select-user-by-org/select-user-by-org.component.html create mode 100644 web-admin-app/src/app/components/select-user-by-org/select-user-by-org.component.less create mode 100644 web-admin-app/src/app/components/select-user-by-org/select-user-by-org.component.ts delete mode 100644 web-admin-app/src/app/pages/component-org-tree/component-org-tree.component.html delete mode 100644 web-admin-app/src/app/pages/component-org-tree/component-org-tree.component.ts create mode 100644 web-admin-app/src/app/pages/fixed-asset/basic/basic-category/basic-category.component.html rename web-admin-app/src/app/{components/form-error-tips/form-error-tips.component.less => pages/fixed-asset/basic/basic-category/basic-category.component.less} (100%) create mode 100644 web-admin-app/src/app/pages/fixed-asset/basic/basic-category/basic-category.component.ts create mode 100644 web-admin-app/src/app/pages/fixed-asset/basic/basic-goods-stock/basic-goods-stock.component.html rename web-admin-app/src/app/{components/range-picker/range-picker.component.less => pages/fixed-asset/basic/basic-goods-stock/basic-goods-stock.component.less} (100%) create mode 100644 web-admin-app/src/app/pages/fixed-asset/basic/basic-goods-stock/basic-goods-stock.component.ts create mode 100644 web-admin-app/src/app/pages/fixed-asset/basic/basic-maintainer/basic-maintainer.component.html rename web-admin-app/src/app/{components/user-form/user-form.component.less => pages/fixed-asset/basic/basic-maintainer/basic-maintainer.component.less} (100%) create mode 100644 web-admin-app/src/app/pages/fixed-asset/basic/basic-maintainer/basic-maintainer.component.ts create mode 100644 web-admin-app/src/app/pages/fixed-asset/basic/basic-manufacturer/basic-manufacturer.component.html rename web-admin-app/src/app/pages/{component-org-tree/component-org-tree.component.less => fixed-asset/basic/basic-manufacturer/basic-manufacturer.component.less} (100%) create mode 100644 web-admin-app/src/app/pages/fixed-asset/basic/basic-manufacturer/basic-manufacturer.component.ts create mode 100644 web-admin-app/src/app/pages/fixed-asset/basic/basic-supplier/basic-supplier.component.html rename web-admin-app/src/app/pages/{system/system.component.less => fixed-asset/basic/basic-supplier/basic-supplier.component.less} (100%) create mode 100644 web-admin-app/src/app/pages/fixed-asset/basic/basic-supplier/basic-supplier.component.ts create mode 100644 web-admin-app/src/app/pages/fixed-asset/basic/basic-warehouse/basic-warehouse.component.html create mode 100644 web-admin-app/src/app/pages/fixed-asset/basic/basic-warehouse/basic-warehouse.component.less create mode 100644 web-admin-app/src/app/pages/fixed-asset/basic/basic-warehouse/basic-warehouse.component.ts create mode 100644 web-admin-app/src/app/pages/fixed-asset/basic/save-position/save-position.component.html create mode 100644 web-admin-app/src/app/pages/fixed-asset/basic/save-position/save-position.component.less create mode 100644 web-admin-app/src/app/pages/fixed-asset/basic/save-position/save-position.component.ts create mode 100644 web-admin-app/src/app/pages/fixed-asset/stocktaking/stockaking-job/stockaking-job.component.html create mode 100644 web-admin-app/src/app/pages/fixed-asset/stocktaking/stockaking-job/stockaking-job.component.less create mode 100644 web-admin-app/src/app/pages/fixed-asset/stocktaking/stockaking-job/stockaking-job.component.ts create mode 100644 web-admin-app/src/app/pages/fixed-asset/stocktaking/stockaking-plan/stockaking-plan.component.html create mode 100644 web-admin-app/src/app/pages/fixed-asset/stocktaking/stockaking-plan/stockaking-plan.component.less create mode 100644 web-admin-app/src/app/pages/fixed-asset/stocktaking/stockaking-plan/stockaking-plan.component.ts rename web-admin-app/src/app/pages/system/{ => index}/system.component.html (56%) create mode 100644 web-admin-app/src/app/pages/system/index/system.component.less rename web-admin-app/src/app/pages/system/{ => index}/system.component.ts (100%) create mode 100644 web-admin-app/src/app/pages/system/system-user/system-user.component.html create mode 100644 web-admin-app/src/app/pages/system/system-user/system-user.component.less create mode 100644 web-admin-app/src/app/pages/system/system-user/system-user.component.ts rename web-admin-app/src/app/{ => shared}/components/app-page/app-page.component.html (100%) rename web-admin-app/src/app/{ => shared}/components/app-page/app-page.component.less (100%) rename web-admin-app/src/app/{ => shared}/components/app-page/app-page.component.ts (97%) rename web-admin-app/src/app/{ => shared}/components/form-error-tips/form-error-tips.component.html (100%) create mode 100644 web-admin-app/src/app/shared/components/form-error-tips/form-error-tips.component.less rename web-admin-app/src/app/{ => shared}/components/form-error-tips/form-error-tips.component.ts (100%) rename web-admin-app/src/app/{ => shared}/components/header/header.component.html (98%) rename web-admin-app/src/app/{ => shared}/components/header/header.component.less (100%) rename web-admin-app/src/app/{ => shared}/components/header/header.component.ts (82%) create mode 100644 web-admin-app/src/app/shared/components/index.ts rename web-admin-app/src/app/{ => shared}/components/layout/layout.component.html (100%) create mode 100644 web-admin-app/src/app/shared/components/layout/layout.component.less create mode 100644 web-admin-app/src/app/shared/components/layout/layout.component.ts rename web-admin-app/src/app/{ => shared}/components/range-picker/range-picker.component.html (100%) create mode 100644 web-admin-app/src/app/shared/components/range-picker/range-picker.component.less rename web-admin-app/src/app/{ => shared}/components/range-picker/range-picker.component.ts (100%) rename web-admin-app/src/app/{ => shared}/components/server-paginated-table/date-query/date-query.component.html (100%) rename web-admin-app/src/app/{ => shared}/components/server-paginated-table/date-query/date-query.component.less (100%) rename web-admin-app/src/app/{ => shared}/components/server-paginated-table/date-query/date-query.component.ts (100%) rename web-admin-app/src/app/{ => shared}/components/server-paginated-table/index.ts (100%) rename web-admin-app/src/app/{ => shared}/components/server-paginated-table/query-item/query-item.component.html (100%) rename web-admin-app/src/app/{ => shared}/components/server-paginated-table/query-item/query-item.component.less (53%) rename web-admin-app/src/app/{ => shared}/components/server-paginated-table/query-item/query-item.component.ts (100%) rename web-admin-app/src/app/{ => shared}/components/server-paginated-table/server-paginated-table.component.html (86%) rename web-admin-app/src/app/{ => shared}/components/server-paginated-table/server-paginated-table.component.less (100%) rename web-admin-app/src/app/{ => shared}/components/server-paginated-table/server-paginated-table.component.ts (98%) rename web-admin-app/src/app/{ => shared}/components/server-paginated-table/server-paginated-table.module.ts (100%) rename web-admin-app/src/app/{ => shared}/components/server-paginated-table/server-paginated-table.service.ts (100%) rename web-admin-app/src/app/{ => shared}/components/server-paginated-table/table-action.directive.ts (100%) rename web-admin-app/src/app/{ => shared}/components/server-paginated-table/table-form.directive.ts (100%) rename web-admin-app/src/app/{ => shared}/components/user-form/user-form.component.html (100%) create mode 100644 web-admin-app/src/app/shared/components/user-form/user-form.component.less rename web-admin-app/src/app/{ => shared}/components/user-form/user-form.component.ts (96%) create mode 100644 web-admin-app/src/assets/images/jiluo_logo.png delete mode 100644 web-admin-app/src/assets/images/logo.png diff --git a/web-admin-app/README.md b/web-admin-app/README.md index 479743e..e0da971 100644 --- a/web-admin-app/README.md +++ b/web-admin-app/README.md @@ -1,27 +1,31 @@ -# LicenseWebApp -This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 17.0.3. +# Web admin app -## Development server +固资管理 -Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The application will automatically reload if you change any of the source files. +# 接口 +- 资产台账 +- 系统管理 + - 账户 & 人事 +- 故障信息表 +- 资产派发 ? -## Code scaffolding -Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`. +# 问题汇总 -## Build +## 05-02 -Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. +- 【用户表】状态 过滤 +- 【用户表】图片上传地址 下载地址 get +- 【用户表】保存报错 系统异常 但能存;更新 提示 新增用户'admin2'失败,登录账号已存在 +- 【用户表】删除 报错 503 -## Running unit tests +- 【存放位置】 新增必须要 positionId +- 【存放位置】 需要树状结构的接口 -Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). +- 【物品分类】 新增必须要 depth -## Running end-to-end tests +- 【盘点任务】列表 负责人、盘点人 等字段 如果要在列表显示 最好在返回名字,而不是id,前端循环请求 效果不好, 需要新增一个接口 支持前端提交 一个 idList,然后返回对应多个人员的详细信息 -Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To use this command, you need to first add a package that implements end-to-end testing capabilities. +-【基础数据】【物品档案】的接口是那个? -## Further help - -To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page. diff --git a/web-admin-app/proxy/devserver.js b/web-admin-app/proxy/devserver.js index ee7f023..512dd5f 100644 --- a/web-admin-app/proxy/devserver.js +++ b/web-admin-app/proxy/devserver.js @@ -1,6 +1,6 @@ // const remoteTarget = "http://10.168.1.60:8300"; const remoteTarget = 'http://47.109.27.8:8280/' -const localTarget = 'http://localhost:8300' +const localTarget = 'http://47.109.27.8:8280/' const devProxy = (remote) => { let config = {} diff --git a/web-admin-app/src/app/app.config.ts b/web-admin-app/src/app/app.config.ts index 9230a29..85254a7 100644 --- a/web-admin-app/src/app/app.config.ts +++ b/web-admin-app/src/app/app.config.ts @@ -8,19 +8,14 @@ import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http' import { provideAnimations } from '@angular/platform-browser/animations' import { zh_CN, provideNzI18n } from 'ng-zorro-antd/i18n' import { routes } from './app.routes' -import { ServerPaginatedTableService } from './components/server-paginated-table' import { LocalHttpInterceptorService } from './services' import { PermissionModule } from './shared/permission/permission.module' import { TINYMCE_SCRIPT_SRC } from '@tinymce/tinymce-angular' +import { ServerPaginatedTableService } from './shared/components/server-paginated-table' registerLocaleData(zh) -export const APPOINTMENT_FROM = [ - { value: 1, label: '美团' }, - { value: 2, label: '大众点评' }, - { value: 3, label: '小红书' }, - { value: 4, label: '抖音' }, -] +export const MaxPageSize = 10000000 export function initializeApp(configService: ServerPaginatedTableService) { return () => { @@ -28,16 +23,17 @@ export function initializeApp(configService: ServerPaginatedTableService) { configService.setConfig({ formatPaginationData(v) { return { - current: v.pageIndex, + pageNum: v.pageIndex, pageSize: v.pageSize, } }, formatServiceData(v) { - console.log('v', v) + // console.log('【formatServiceData】', v) return { - total: v.data.total, - totalPages: Math.ceil(v.data.records / 5), - data: v.data.records, + total: v.body.total, + // totalPages: Math.ceil(v.body.rows / 5), + totalPages: 0, + data: v.body.rows, } }, }) diff --git a/web-admin-app/src/app/app.routes.ts b/web-admin-app/src/app/app.routes.ts index 7623536..916adfe 100644 --- a/web-admin-app/src/app/app.routes.ts +++ b/web-admin-app/src/app/app.routes.ts @@ -1,6 +1,6 @@ import { Routes } from '@angular/router' +import { LayoutComponent } from './shared/components' import { DashboardComponent } from './pages/dashboard/dashboard.component' -import { LayoutComponent } from './components/layout/layout.component' import { ProfileComponent } from './pages/profile/profile.component' import { ProfileBasicComponent } from './pages/profile-basic/profile-basic.component' import { ProfileAccountComponent } from './pages/profile-account/profile-account.component' @@ -9,7 +9,7 @@ import { authGuard } from './guards' import { permissionGuard } from './shared/permission/permission.guard' import { ForbiddenComponent } from './pages/forbidden/forbidden.component' import { NotfoundComponent } from './pages/notfound/notfound.component' -import { SystemComponent } from './pages/system/system.component' +import { SystemComponent } from './pages/system/index/system.component' import { OrgComponent } from './pages/org/org.component' import { OrgEmployeeComponent } from './pages/org-employee/org-employee.component' import { OrgSettingComponent } from './pages/org-setting/org-setting.component' @@ -31,6 +31,17 @@ import { FixedAssetManageRevertComponent } from './pages/fixed-asset/manage/fixe import { FixedAssetManageAllotComponent } from './pages/fixed-asset/manage/fixed-asset-manage-allot/fixed-asset-manage-allot.component' import { FixedAssetManageTransferComponent } from './pages/fixed-asset/manage/fixed-asset-manage-transfer/fixed-asset-manage-transfer.component' import { FixedAssetManageScrapComponent } from './pages/fixed-asset/manage/fixed-asset-manage-scrap/fixed-asset-manage-scrap.component' +import { SystemUserComponent } from './pages/system/system-user/system-user.component' + +import { SavePositionComponent } from './pages/fixed-asset/basic/save-position/save-position.component' +import { BasicGoodsStockComponent } from './pages/fixed-asset/basic/basic-goods-stock/basic-goods-stock.component' +import { BasicMaintainerComponent } from './pages/fixed-asset/basic/basic-maintainer/basic-maintainer.component' +import { BasicManufacturerComponent } from './pages/fixed-asset/basic/basic-manufacturer/basic-manufacturer.component' +import { BasicWarehouseComponent } from './pages/fixed-asset/basic/basic-warehouse/basic-warehouse.component' +import { BasicSupplierComponent } from './pages/fixed-asset/basic/basic-supplier/basic-supplier.component' +import { BasicCategoryComponent } from './pages/fixed-asset/basic/basic-category/basic-category.component' +import { StockakingJobComponent } from './pages/fixed-asset/stocktaking/stockaking-job/stockaking-job.component' +import { StockakingPlanComponent } from './pages/fixed-asset/stocktaking/stockaking-plan/stockaking-plan.component' export const routes: Routes = [ { @@ -87,7 +98,7 @@ export const routes: Routes = [ }, { path: 'user', - component: SystemComponent, + component: SystemUserComponent, canActivate: [permissionGuard], data: { permission: 'user', @@ -230,10 +241,78 @@ export const routes: Routes = [ }, ], }, + { + path: 'basic', + title: '基础数据', + children: [ + { + path: '', + pathMatch: 'full', + redirectTo: 'goods-stock', + }, + { + path: 'goods-stock', + component: BasicGoodsStockComponent, + title: '物品档案', + }, + { + path: 'category', + component: BasicCategoryComponent, + title: '物品分类', + }, + { + path: 'save-position', + component: SavePositionComponent, + title: '存放位置', + }, + { + path: 'maintainer', + component: BasicMaintainerComponent, + title: '维保商', + }, + { + path: 'manufacturer', + component: BasicManufacturerComponent, + title: '生产商', + }, + { + path: 'supplier', + component: BasicSupplierComponent, + title: '供应商', + }, + { + path: 'warehouse', + component: BasicWarehouseComponent, + title: '存放仓库', + }, + ], + }, + { + path: 'stocktaking', + title: '盘点管理', + children: [ + { + path: '', + pathMatch: 'full', + redirectTo: 'job', + }, + { + path: 'job', + component: StockakingJobComponent, + title: '盘点任务', + }, + { + path: 'plan', + component: StockakingPlanComponent, + title: '盘点计划', + }, + ], + }, ], }, ], }, + { path: 'not-found', component: NotfoundComponent, diff --git a/web-admin-app/src/app/components/component-basic-category-tree/component-basic-category-tree.component.html b/web-admin-app/src/app/components/component-basic-category-tree/component-basic-category-tree.component.html new file mode 100644 index 0000000..b5dddd9 --- /dev/null +++ b/web-admin-app/src/app/components/component-basic-category-tree/component-basic-category-tree.component.html @@ -0,0 +1,64 @@ +
+
+
+ + + + + + +
+ @if (createable) { + + } +
+
+ + +
+
+ @switch (origin.organizationType) { + @case ('0') { + + } + @case ('1') { + + } + @case ('2') { + + } + } + {{ node.title }} +
+ + +
    +
  • 添加同级分类
  • +
  • 添加下级分类
  • +
  • +
  • 删除
  • +
+
+
+
+
+
+
diff --git a/web-admin-app/src/app/components/component-basic-category-tree/component-basic-category-tree.component.less b/web-admin-app/src/app/components/component-basic-category-tree/component-basic-category-tree.component.less new file mode 100644 index 0000000..fcd4a28 --- /dev/null +++ b/web-admin-app/src/app/components/component-basic-category-tree/component-basic-category-tree.component.less @@ -0,0 +1,7 @@ +.tree { + ::ng-deep { + .ant-tree-switcher { + align-self: center; + } + } +} \ No newline at end of file diff --git a/web-admin-app/src/app/components/component-basic-category-tree/component-basic-category-tree.component.ts b/web-admin-app/src/app/components/component-basic-category-tree/component-basic-category-tree.component.ts new file mode 100644 index 0000000..7d233b9 --- /dev/null +++ b/web-admin-app/src/app/components/component-basic-category-tree/component-basic-category-tree.component.ts @@ -0,0 +1,153 @@ +import { Component, EventEmitter, Input, OnInit, Output, TemplateRef } from '@angular/core' +import { FormBuilder, FormGroup } from '@angular/forms' +import { ApiService } from 'app/services' +import { SharedModule } from 'app/shared/shared.module' +import { FormValidators } from 'app/utils' +import { NzSafeAny } from 'ng-zorro-antd/core/types' +import { NzDrawerRef, NzDrawerService } from 'ng-zorro-antd/drawer' +import { NzMessageService } from 'ng-zorro-antd/message' +import { NzModalService } from 'ng-zorro-antd/modal' +import { NzFormatEmitEvent, NzTreeNodeOptions } from 'ng-zorro-antd/tree' + +interface CateGoryInterface { + categoryId: number + categoryName: string + createTime: string + depth: string + lowerLimit: number | null + parentId: number + safetyLimit: number | null + upperLimit: number | null +} +function buildTree(organizations: CateGoryInterface[]): NzTreeNodeOptions[] { + const map: { [parentId: number]: NzTreeNodeOptions[] } = {} + + organizations.forEach((org) => { + if (!map[org.parentId]) { + map[org.parentId] = [] + } + const treeNode: NzTreeNodeOptions = { + ...org, + title: org.categoryName, + key: org.categoryId.toString(), + } + map[org.parentId].push(treeNode) + }) + + const build = (parentId: number): NzTreeNodeOptions[] => { + if (!map[parentId]) { + return [] + } + return map[parentId].map((node) => { + const children = build(parseInt(node.key)) + return { + ...node, + isLeaf: children.length === 0, + children, + } + }) + } + + return build(0) +} + +@Component({ + selector: 'app-component-basic-category-tree', + standalone: true, + imports: [SharedModule], + templateUrl: './component-basic-category-tree.component.html', + styleUrl: './component-basic-category-tree.component.less', +}) +export class ComponentBasicCategoryTreeComponent { + constructor( + private api: ApiService, + private drawer: NzDrawerService, + private fb: FormBuilder, + private msg: NzMessageService, + private modal: NzModalService, + ) {} + + @Input() createable = true + + @Output() onSelectedChange = new EventEmitter() + + drawerRef?: NzDrawerRef + + searchValue = '' + + parentId?: number + + nodes: NzSafeAny[] = [] + + expandedKeys: string[] = [] + + selectedKeys: string[] = [] + + initTree() { + this.api.getBasicCategoryTree().subscribe((res) => { + this.nodes = buildTree(res.body) + this.expandedKeys = [...this.expandedKeys] + console.log('this.selectedKeys', this.selectedKeys) + if (this.selectedKeys.length === 0) { + this.selectedKeys = [this.nodes[0].key] + } else { + this.selectedKeys = [...this.selectedKeys] + } + + const node = res.body.find((node: NzSafeAny) => String(node.categoryId) === this.selectedKeys[0]) + this.onSelectedChange.emit(node) + }) + } + + ngOnInit(): void { + this.initTree() + } + + nzEvent(event: NzFormatEmitEvent): void { + if (event.eventName === 'click') { + const { node } = event + this.selectedKeys = event.keys ?? [] + this.onSelectedChange.emit(node?.origin) + } + } + + onExpandChange(e: NzFormatEmitEvent) { + this.expandedKeys = e.keys ?? [] + } + + onSelectedKeysChange(e: string[]) { + console.log('e', e) + } + + onCreate(parentId: number) { + this.api + .addBasicCategoryTree({ + depth: '', + lowerLimit: 0, + safetyLimit: 0, + upperLimit: 0, + parentId, + categoryName: '新分类', + }) + .subscribe((res) => { + this.initTree() + this.msg.success(res.desc) + }) + } + + onDelete(id: number) { + this.modal.confirm({ + nzTitle: '警告', + nzContent: '是否要删除该分类?', + nzOnOk: () => { + this.api.deleteBasicCategory([id]).subscribe((res) => { + if (this.selectedKeys.includes(String(id))) { + this.selectedKeys = [] + } + this.msg.success(res.desc) + this.initTree() + }) + }, + }) + } +} diff --git a/web-admin-app/src/app/components/component-org-tree/component-org-tree.component.html b/web-admin-app/src/app/components/component-org-tree/component-org-tree.component.html new file mode 100644 index 0000000..8a82e75 --- /dev/null +++ b/web-admin-app/src/app/components/component-org-tree/component-org-tree.component.html @@ -0,0 +1,113 @@ +
+
+
+ + + + + + +
+ @if (createable) { + + +
    +
  • 添加组织
  • +
  • 添加岗位
  • +
+
+ } +
+
+ + +
+
+ @switch (origin.organizationType) { + @case ('0') { + + } + @case ('1') { + + } + @case ('2') { + + } + } + {{ node.title }} +
+ @if (createable) { + + +
    +
  • 添加组织
  • +
  • 添加岗位
  • +
  • + 编辑 +
  • +
  • +
  • 删除
  • +
+
+ } +
+
+
+
+ + +
+ + 名称 + + + + + @if (isOrg) { + + 类型 + + + + + + + + } + + 状态 + + + + +
+
+ + + + + + + + + + + +
diff --git a/web-admin-app/src/app/components/component-org-tree/component-org-tree.component.less b/web-admin-app/src/app/components/component-org-tree/component-org-tree.component.less new file mode 100644 index 0000000..fcd4a28 --- /dev/null +++ b/web-admin-app/src/app/components/component-org-tree/component-org-tree.component.less @@ -0,0 +1,7 @@ +.tree { + ::ng-deep { + .ant-tree-switcher { + align-self: center; + } + } +} \ No newline at end of file diff --git a/web-admin-app/src/app/components/component-org-tree/component-org-tree.component.ts b/web-admin-app/src/app/components/component-org-tree/component-org-tree.component.ts new file mode 100644 index 0000000..fce2f29 --- /dev/null +++ b/web-admin-app/src/app/components/component-org-tree/component-org-tree.component.ts @@ -0,0 +1,186 @@ +import { Component, EventEmitter, Input, OnInit, Output, TemplateRef } from '@angular/core' +import { FormBuilder, FormGroup } from '@angular/forms' +import { ApiService } from 'app/services' +import { SharedModule } from 'app/shared/shared.module' +import { FormValidators } from 'app/utils' +import { NzSafeAny } from 'ng-zorro-antd/core/types' +import { NzDrawerRef, NzDrawerService } from 'ng-zorro-antd/drawer' +import { NzMessageService } from 'ng-zorro-antd/message' +import { NzModalService } from 'ng-zorro-antd/modal' +import { NzFormatEmitEvent, NzTreeNodeOptions } from 'ng-zorro-antd/tree' + +interface Organization { + depth: string + orderNum: number + organizationId: number + organizationName: string + organizationType: string + parentId: number + status: string +} +function buildTree(organizations: Organization[]): NzTreeNodeOptions[] { + const map: { [parentId: number]: NzTreeNodeOptions[] } = {} + + organizations.forEach((org) => { + if (!map[org.parentId]) { + map[org.parentId] = [] + } + const treeNode: NzTreeNodeOptions = { + ...org, + title: org.organizationName, + key: org.organizationId.toString(), + } + map[org.parentId].push(treeNode) + }) + + const build = (parentId: number): NzTreeNodeOptions[] => { + if (!map[parentId]) { + return [] + } + return map[parentId].map((node) => { + const children = build(parseInt(node.key)) + return { + ...node, + isLeaf: children.length === 0, + children, + } + }) + } + + return build(0) +} + +@Component({ + selector: 'app-component-org-tree', + standalone: true, + imports: [SharedModule], + templateUrl: './component-org-tree.component.html', + styleUrl: './component-org-tree.component.less', +}) +export class ComponentOrgTreeComponent implements OnInit { + constructor( + private api: ApiService, + private drawer: NzDrawerService, + private fb: FormBuilder, + private msg: NzMessageService, + private modal: NzModalService, + ) {} + + @Input() createable = true + + @Output() onOrgSelectedChange = new EventEmitter() + + drawerRef?: NzDrawerRef + + isOrg = false + + searchValue = '' + + parentId?: number + + nodes: NzSafeAny[] = [] + + expandedKeys: string[] = [] + + form!: FormGroup + + initForm() { + this.form = this.fb.group({ + organizationId: this.fb.control(null, []), + organizationName: this.fb.control('', [FormValidators.required('请输入组织名称')]), + organizationType: this.fb.control('1', []), + status: this.fb.control(true, []), + }) + } + + initTree() { + this.api.getOrgTree().subscribe((res) => { + this.nodes = buildTree(res.body) + this.expandedKeys = [...this.expandedKeys] + }) + } + + ngOnInit(): void { + this.initTree() + this.initForm() + } + + nzEvent(event: NzFormatEmitEvent): void { + if (event.eventName === 'click') { + const { node } = event + this.onOrgSelectedChange.emit(event.keys?.length === 0 ? null : node?.origin) + } + } + + onExpandChange(e: NzFormatEmitEvent) { + this.expandedKeys = e.keys ?? [] + } + + onSelectedKeysChange(e: string[]) { + console.log('e', e) + } + + onCreate( + isOrg: boolean, + nzContent: TemplateRef, + nzFooter: TemplateRef, + origin?: NzSafeAny, + edit?: boolean, + ) { + this.isOrg = isOrg + + this.form.patchValue({ + organizationType: isOrg ? '1' : '2', + }) + if (edit) { + this.isOrg = origin.organizationType !== '2' + this.form.patchValue(origin) + } else { + this.parentId = origin?.organizationId + } + + this.drawerRef = this.drawer.create({ + nzTitle: '组织管理', + nzContent, + nzWidth: 600, + nzFooter, + }) + } + + onDelete(id: number) { + this.modal.confirm({ + nzTitle: '警告', + nzContent: '是否要删除该组织?', + nzOnOk: () => { + this.api.deleteOrg(id).subscribe((res) => { + this.msg.success(res.desc) + this.initTree() + }) + }, + }) + } + + onConfirm() { + if (FormValidators.validateFormGroup(this.form)) { + const { value } = this.form + this.api + .saveOrg({ + ...value, + status: value.status ? 0 : 1, + parentId: this.parentId, + }) + .subscribe((res) => { + this.initTree() + this.msg.success(res.desc) + this.onCancel() + }) + } + } + + onCancel() { + this.drawerRef?.close() + this.form.reset() + this.isOrg = false + this.parentId = void 0 + } +} diff --git a/web-admin-app/src/app/components/index.ts b/web-admin-app/src/app/components/index.ts index 0d1d6d2..1d2e804 100644 --- a/web-admin-app/src/app/components/index.ts +++ b/web-admin-app/src/app/components/index.ts @@ -1,5 +1,3 @@ -// export * from "./form-error-tips/form-error-tips.component"; -// export * from "./server-paginated-table"; - -export * from './header/header.component' -export * from './layout/layout.component' +export * from './component-org-tree/component-org-tree.component' +export * from './component-basic-category-tree/component-basic-category-tree.component' +export * from './select-user-by-org/select-user-by-org.component' diff --git a/web-admin-app/src/app/components/layout/layout.component.less b/web-admin-app/src/app/components/layout/layout.component.less deleted file mode 100644 index b087501..0000000 --- a/web-admin-app/src/app/components/layout/layout.component.less +++ /dev/null @@ -1,15 +0,0 @@ -:host { - display: block; - height: 100%; -} - -.app-width { - ::ng-deep { - router-outlet+* { - display: block; - width: 100%; - height: 100%; - // overflow: hidden; - } - } -} \ No newline at end of file diff --git a/web-admin-app/src/app/components/layout/layout.component.ts b/web-admin-app/src/app/components/layout/layout.component.ts deleted file mode 100644 index fcfb2e3..0000000 --- a/web-admin-app/src/app/components/layout/layout.component.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Component } from '@angular/core'; -import { HeaderComponent } from "../header/header.component"; -import { SharedModule } from "../../shared/shared.module"; - -@Component({ - standalone: true, - selector: 'app-layout', - templateUrl: './layout.component.html', - styleUrls: ['./layout.component.less'], - imports: [SharedModule, HeaderComponent] -}) -export class LayoutComponent { - -} diff --git a/web-admin-app/src/app/components/select-user-by-org/select-user-by-org.component.html b/web-admin-app/src/app/components/select-user-by-org/select-user-by-org.component.html new file mode 100644 index 0000000..b215a75 --- /dev/null +++ b/web-admin-app/src/app/components/select-user-by-org/select-user-by-org.component.html @@ -0,0 +1,74 @@ +
+ @if (selectedKeys.size > 0) { + + } @else { +
+ + + {{ placeholder }} + +
+ } +
+ + + @for (uid of selectedKeys; track $index) { + + {{ allGetedDataMap.get(uid).userName }} + + } + + + +
+ +
+ +
+ +
+
+ +
+
+
+ + 全选 + +
+
+
    + @for (item of currentUsers; track $index) { +
  • + {{ item.userName }} + +
  • + } +
+
+
+
+
+
+
diff --git a/web-admin-app/src/app/components/select-user-by-org/select-user-by-org.component.less b/web-admin-app/src/app/components/select-user-by-org/select-user-by-org.component.less new file mode 100644 index 0000000..0ad5565 --- /dev/null +++ b/web-admin-app/src/app/components/select-user-by-org/select-user-by-org.component.less @@ -0,0 +1,21 @@ +.trigger { + border: 1px dashed #e0e0e0; +} + +.user-select { + .org { + border-right: 1px solid #e0e0e0; + } + + .user-list { + .hd { + border-bottom: 1px solid #e0e0e0; + } + + .item { + &:hover { + background-color: #f0f1f4; + } + } + } +} \ No newline at end of file diff --git a/web-admin-app/src/app/components/select-user-by-org/select-user-by-org.component.ts b/web-admin-app/src/app/components/select-user-by-org/select-user-by-org.component.ts new file mode 100644 index 0000000..12e1680 --- /dev/null +++ b/web-admin-app/src/app/components/select-user-by-org/select-user-by-org.component.ts @@ -0,0 +1,128 @@ +import { CommonModule } from '@angular/common' +import { Component, Input, OnInit, TemplateRef, forwardRef } from '@angular/core' +import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms' +import { NzCardModule } from 'ng-zorro-antd/card' +import { NzSafeAny } from 'ng-zorro-antd/core/types' +import { NzIconModule } from 'ng-zorro-antd/icon' +import { NzModalModule, NzModalService } from 'ng-zorro-antd/modal' +import { NzTreeModule } from 'ng-zorro-antd/tree' +import { ComponentOrgTreeComponent } from '../component-org-tree/component-org-tree.component' +import { NzButtonModule } from 'ng-zorro-antd/button' +import { NzCheckboxModule } from 'ng-zorro-antd/checkbox' +import { ApiService } from 'app/services' +import { NzMessageModule, NzMessageService } from 'ng-zorro-antd/message' +import { MaxPageSize } from 'app/app.config' +import { NzTagModule } from 'ng-zorro-antd/tag' + +@Component({ + selector: 'app-select-user-by-org', + standalone: true, + imports: [ + CommonModule, + ComponentOrgTreeComponent, + NzButtonModule, + NzCheckboxModule, + NzTreeModule, + NzModalModule, + NzIconModule, + NzCardModule, + NzMessageModule, + NzTagModule, + ], + templateUrl: './select-user-by-org.component.html', + styleUrl: './select-user-by-org.component.less', + providers: [ + { + provide: NG_VALUE_ACCESSOR, + multi: true, + useExisting: forwardRef(() => SelectUserByOrgComponent), + }, + ], +}) +export class SelectUserByOrgComponent implements ControlValueAccessor, OnInit { + constructor( + private modal: NzModalService, + private api: ApiService, + private msg: NzMessageService, + ) {} + + @Input() placeholder: string = '请选择' + + @Input() modalTitle: string = '选择' + + allGetedDataMap = new Map() + + currentUsers: NzSafeAny[] = [] + + selectedKeys = new Set() + + indeterminate = false + + allChecked = false + + ngOnInit(): void {} + + onTriggerClick(nzContent: TemplateRef) { + this.modal.create({ + nzTitle: this.modalTitle, + nzContent, + nzWidth: '660px', + }) + } + + onOrgSelectedChange(v: NzSafeAny) { + this.api + .getUserPage({ pageSize: MaxPageSize, pageNum: 1, organizationId: v.organizationId }) + .subscribe((res) => { + if (Array.isArray(res.body?.rows) && res.body.rows.length > 0) { + res.body.rows.forEach((element: NzSafeAny) => { + this.currentUsers = res.body.rows + this.allGetedDataMap.set(element.userId, element) + }) + } + }) + } + + onUserCheckedChange(e: boolean, v: number) { + if (e) { + this.selectedKeys.add(v) + } else { + this.selectedKeys.delete(v) + } + this.statusChange() + } + + statusChange() { + this.allChecked = this.selectedKeys.size === this.currentUsers.length + this.indeterminate = this.selectedKeys.size > 0 && this.selectedKeys.size < this.currentUsers.length + } + + onAllCheckedChange(e: boolean) { + if (e) { + this.currentUsers.forEach((element) => { + this.selectedKeys.add(element.userId) + }) + } else { + this.selectedKeys.clear() + } + this.statusChange() + } + + onTouched = () => {} + + onChange(v: string[]) { + console.log('v', v) + } + + writeValue(v: any): void {} + + registerOnChange(fn: any): void { + this.onChange = fn + } + + registerOnTouched(fn: any): void { + this.onTouched = fn + } + + setDisabledState?(isDisabled: boolean): void {} +} diff --git a/web-admin-app/src/app/guards/auth.guard.ts b/web-admin-app/src/app/guards/auth.guard.ts index 1ee38bb..11ea492 100644 --- a/web-admin-app/src/app/guards/auth.guard.ts +++ b/web-admin-app/src/app/guards/auth.guard.ts @@ -4,17 +4,16 @@ import { ApiService, LocalHttpInterceptorService } from 'app/services' import { map } from 'rxjs' export const authGuard: CanActivateFn = (route, state) => { - const local = inject(LocalHttpInterceptorService) - const accessData = local.getAccess() - let token = accessData?.access_token - if (token) { - return true - } - const router = inject(Router) - return router.createUrlTree(['/login']) - // const api = inject(ApiService) - // if (!localStorage.getItem('sc')) { - // return router.createUrlTree(['/login']) + // const local = inject(LocalHttpInterceptorService) + // const accessData = local.getAccess() + // let token = accessData?.access_token + // if (token) { + // return true // } - // return api.getAuthInfo(true).pipe(map((r) => !!r)) + const router = inject(Router) + const api = inject(ApiService) + if (!api.authInfo) { + return router.createUrlTree(['/login']) + } + return true } diff --git a/web-admin-app/src/app/pages/component-org-tree/component-org-tree.component.html b/web-admin-app/src/app/pages/component-org-tree/component-org-tree.component.html deleted file mode 100644 index addfd12..0000000 --- a/web-admin-app/src/app/pages/component-org-tree/component-org-tree.component.html +++ /dev/null @@ -1,23 +0,0 @@ -
-
- - - - - - -
- @if (createable) { - - } -
-
- -
diff --git a/web-admin-app/src/app/pages/component-org-tree/component-org-tree.component.ts b/web-admin-app/src/app/pages/component-org-tree/component-org-tree.component.ts deleted file mode 100644 index 343171d..0000000 --- a/web-admin-app/src/app/pages/component-org-tree/component-org-tree.component.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { Component, Input } from '@angular/core' -import { SharedModule } from 'app/shared/shared.module' -import { NzFormatEmitEvent } from 'ng-zorro-antd/tree' - -@Component({ - selector: 'app-component-org-tree', - standalone: true, - imports: [SharedModule], - templateUrl: './component-org-tree.component.html', - styleUrl: './component-org-tree.component.less', -}) -export class ComponentOrgTreeComponent { - constructor() {} - - @Input() createable = true - - searchValue = '' - - nodes = [ - { - title: '科技部', - key: '0-0', - children: [ - { - title: '岗位1', - key: '0-0-0', - }, - { - title: '岗位12', - key: '0-0-1', - children: [ - { title: '0-0-1-0', key: '0-0-1-0', isLeaf: true }, - { title: '0-0-1-1', key: '0-0-1-1', isLeaf: true }, - { title: '0-0-1-2', key: '0-0-1-2', isLeaf: true }, - ], - }, - { - title: '岗位14', - key: '0-0-2', - isLeaf: true, - }, - ], - }, - { - title: '综合办', - key: '0-1', - }, - { - title: '办公室', - key: '0-2', - isLeaf: true, - }, - ] - - nzEvent(event: NzFormatEmitEvent): void { - console.log(event) - } -} diff --git a/web-admin-app/src/app/pages/dashboard/dashboard.component.ts b/web-admin-app/src/app/pages/dashboard/dashboard.component.ts index 519f25d..71628b3 100644 --- a/web-admin-app/src/app/pages/dashboard/dashboard.component.ts +++ b/web-admin-app/src/app/pages/dashboard/dashboard.component.ts @@ -3,7 +3,6 @@ import { init, EChartsType } from 'echarts' import { SharedModule } from '../../shared/shared.module' import { ApiService } from 'app/services' import { ConsoleClientTopDTO, ConsoleCountDTO, ConsoleExpireDTO } from 'app/services/api.dto' -import { AppPageComponent } from 'app/components/app-page/app-page.component' const antvColor = [ '#5B8FF9', @@ -20,7 +19,7 @@ const antvColor = [ @Component({ standalone: true, - imports: [SharedModule, AppPageComponent], + imports: [SharedModule], selector: 'app-dashboard', templateUrl: './dashboard.component.html', styleUrls: ['./dashboard.component.less'], diff --git a/web-admin-app/src/app/pages/fixed-asset/basic/basic-category/basic-category.component.html b/web-admin-app/src/app/pages/fixed-asset/basic/basic-category/basic-category.component.html new file mode 100644 index 0000000..0ea4079 --- /dev/null +++ b/web-admin-app/src/app/pages/fixed-asset/basic/basic-category/basic-category.component.html @@ -0,0 +1,63 @@ + +
+ + + +
+ +
+ + 名称 + + + + + + 安全库存 + + + + + + 安全库存上限 + + + + + + 安全库存下限 + + + + + + + + + + + +
+
+
+
+
+ + + + diff --git a/web-admin-app/src/app/components/form-error-tips/form-error-tips.component.less b/web-admin-app/src/app/pages/fixed-asset/basic/basic-category/basic-category.component.less similarity index 100% rename from web-admin-app/src/app/components/form-error-tips/form-error-tips.component.less rename to web-admin-app/src/app/pages/fixed-asset/basic/basic-category/basic-category.component.less diff --git a/web-admin-app/src/app/pages/fixed-asset/basic/basic-category/basic-category.component.ts b/web-admin-app/src/app/pages/fixed-asset/basic/basic-category/basic-category.component.ts new file mode 100644 index 0000000..66ad4ba --- /dev/null +++ b/web-admin-app/src/app/pages/fixed-asset/basic/basic-category/basic-category.component.ts @@ -0,0 +1,82 @@ +import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core' +import { SharedModule } from 'app/shared/shared.module' + +import { ApiService } from 'app/services' +import { FormBuilder, FormGroup } from '@angular/forms' +import { AnyObject, TableOption } from 'app/shared/components/server-paginated-table' +import { NzSafeAny } from 'ng-zorro-antd/core/types' +import { NzModalService } from 'ng-zorro-antd/modal' +import { NzMessageService } from 'ng-zorro-antd/message' +import { NzDrawerRef, NzDrawerService } from 'ng-zorro-antd/drawer' +import { lastValueFrom } from 'rxjs' +import { FormValidators } from 'app/utils' +import { ComponentBasicCategoryTreeComponent } from 'app/components' + +@Component({ + selector: 'app-basic-category', + standalone: true, + imports: [SharedModule, ComponentBasicCategoryTreeComponent], + templateUrl: './basic-category.component.html', + styleUrl: './basic-category.component.less', +}) +export class BasicCategoryComponent { + constructor( + private modal: NzModalService, + private msg: NzMessageService, + private drawer: NzDrawerService, + private api: ApiService, + private fb: FormBuilder, + ) {} + + @ViewChild('treeEl') treeEl!: ComponentBasicCategoryTreeComponent + + queryForm!: FormGroup + + createForm!: FormGroup + + drawerRef?: NzDrawerRef + + @ViewChild('drawerFooterTpl') drawerFooterTpl!: TemplateRef + + @ViewChild('formContentTpl') formContentTpl!: TemplateRef + + initCreateForm() { + this.createForm = this.fb.group({ + categoryId: [], + categoryName: ['', [FormValidators.required('请输入')]], + safetyLimit: [0, []], + lowerLimit: [0, []], + upperLimit: [0, []], + }) + } + initQueryForm() { + this.queryForm = this.fb.group({ + name: [''], + }) + } + + ngOnInit(): void { + this.initQueryForm() + this.initCreateForm() + } + + onSelectedChange(v: NzSafeAny) { + this.createForm.patchValue(v) + } + + onConfirm() { + if (FormValidators.validateFormGroup(this.createForm)) { + const { value } = this.createForm + + this.api + .updateBasicCategoryTree({ + ...value, + }) + .subscribe((res) => { + this.msg.success(res.desc) + console.log('this.treeEl', this.treeEl) + this.treeEl.initTree() + }) + } + } +} diff --git a/web-admin-app/src/app/pages/fixed-asset/basic/basic-goods-stock/basic-goods-stock.component.html b/web-admin-app/src/app/pages/fixed-asset/basic/basic-goods-stock/basic-goods-stock.component.html new file mode 100644 index 0000000..20897df --- /dev/null +++ b/web-admin-app/src/app/pages/fixed-asset/basic/basic-goods-stock/basic-goods-stock.component.html @@ -0,0 +1 @@ +

basic-goods-stock works!

diff --git a/web-admin-app/src/app/components/range-picker/range-picker.component.less b/web-admin-app/src/app/pages/fixed-asset/basic/basic-goods-stock/basic-goods-stock.component.less similarity index 100% rename from web-admin-app/src/app/components/range-picker/range-picker.component.less rename to web-admin-app/src/app/pages/fixed-asset/basic/basic-goods-stock/basic-goods-stock.component.less diff --git a/web-admin-app/src/app/pages/fixed-asset/basic/basic-goods-stock/basic-goods-stock.component.ts b/web-admin-app/src/app/pages/fixed-asset/basic/basic-goods-stock/basic-goods-stock.component.ts new file mode 100644 index 0000000..ee2fb77 --- /dev/null +++ b/web-admin-app/src/app/pages/fixed-asset/basic/basic-goods-stock/basic-goods-stock.component.ts @@ -0,0 +1,12 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-basic-goods-stock', + standalone: true, + imports: [], + templateUrl: './basic-goods-stock.component.html', + styleUrl: './basic-goods-stock.component.less' +}) +export class BasicGoodsStockComponent { + +} diff --git a/web-admin-app/src/app/pages/fixed-asset/basic/basic-maintainer/basic-maintainer.component.html b/web-admin-app/src/app/pages/fixed-asset/basic/basic-maintainer/basic-maintainer.component.html new file mode 100644 index 0000000..07a59f6 --- /dev/null +++ b/web-admin-app/src/app/pages/fixed-asset/basic/basic-maintainer/basic-maintainer.component.html @@ -0,0 +1,108 @@ + + + + + + +
+ + + @switch (key) { + @case ('status') { + + } + + @default { + {{ data }} + } + } + + + + + + + + + + + + + + +
+
+ + + + + + + + + +
+ + 名称 + + + + + + 编码 + + + + + + 统一社会信用代码 + + + + + + 商务联系人 + + + + + + 商务联系方式 + + + + + + 售后联系人 + + + + + + 售后联系方式 + + + + + + + 地址 + + + + + + 备注 + + + + +
+
+ + + + diff --git a/web-admin-app/src/app/components/user-form/user-form.component.less b/web-admin-app/src/app/pages/fixed-asset/basic/basic-maintainer/basic-maintainer.component.less similarity index 100% rename from web-admin-app/src/app/components/user-form/user-form.component.less rename to web-admin-app/src/app/pages/fixed-asset/basic/basic-maintainer/basic-maintainer.component.less diff --git a/web-admin-app/src/app/pages/fixed-asset/basic/basic-maintainer/basic-maintainer.component.ts b/web-admin-app/src/app/pages/fixed-asset/basic/basic-maintainer/basic-maintainer.component.ts new file mode 100644 index 0000000..0afa0fe --- /dev/null +++ b/web-admin-app/src/app/pages/fixed-asset/basic/basic-maintainer/basic-maintainer.component.ts @@ -0,0 +1,136 @@ +import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core' +import { SharedModule } from 'app/shared/shared.module' +import { ApiService } from 'app/services' +import { FormBuilder, FormGroup } from '@angular/forms' +import { AnyObject, TableOption } from 'app/shared/components/server-paginated-table' +import { NzSafeAny } from 'ng-zorro-antd/core/types' +import { NzModalService } from 'ng-zorro-antd/modal' +import { NzMessageService } from 'ng-zorro-antd/message' +import { NzDrawerRef, NzDrawerService } from 'ng-zorro-antd/drawer' +import { lastValueFrom } from 'rxjs' +import { FormValidators } from 'app/utils' + +@Component({ + selector: 'app-basic-maintainer', + standalone: true, + imports: [SharedModule], + templateUrl: './basic-maintainer.component.html', + styleUrl: './basic-maintainer.component.less', +}) +export class BasicMaintainerComponent { + constructor( + private modal: NzModalService, + private msg: NzMessageService, + private drawer: NzDrawerService, + private api: ApiService, + private fb: FormBuilder, + ) {} + + table = new TableOption(this.fetchData.bind(this)) + + queryForm!: FormGroup + + createForm!: FormGroup + + drawerRef?: NzDrawerRef + + @ViewChild('drawerFooterTpl') drawerFooterTpl!: TemplateRef + + @ViewChild('formContentTpl') formContentTpl!: TemplateRef + + initCreateForm() { + this.createForm = this.fb.group({ + maintenanceVendorId: [], + name: ['', [FormValidators.required('请输入')]], + code: ['', []], + uscc: ['', []], + notes: ['', []], + businessContactor: ['', []], + businessContact: ['', []], + afterSalesContactor: ['', []], + afterSalesContact: ['', []], + address: ['', []], + }) + } + initQueryForm() { + this.queryForm = this.fb.group({ + name: [''], + uscc: [''], + code: [''], + }) + } + + ngOnInit(): void { + this.table + + .setColumn([ + { key: 'name', title: '名称' }, + { key: 'code', title: '编码' }, + { key: 'uscc', title: '统一社会信用代码' }, + { key: 'businessContactor', title: '商务联系人' }, + { key: 'businessContact', title: '商务联系方式' }, + { key: 'afterSalesContactor', title: '售后联系人' }, + { key: 'afterSalesContact', title: '售后联系方式' }, + { key: 'address', title: '地址' }, + { key: 'notes', title: '备注' }, + ]) + .setRowOperate([ + { title: '编辑', onClick: this.onCreate.bind(this) }, + { title: '删除', onClick: this.deleteItem.bind(this) }, + ]) + this.initQueryForm() + this.initCreateForm() + } + + fetchData(p: {}, q: AnyObject) { + return this.api.getBasicMaintenanceVendorPage({ ...p, ...q }) + } + + onCreate(data?: NzSafeAny) { + if (data) { + this.createForm.patchValue(data) + } + this.drawerRef = this.drawer.create({ + nzTitle: data ? '编辑维保商' : '新增维保商', + nzContent: this.formContentTpl, + nzFooter: this.drawerFooterTpl, + nzWidth: 600, + nzOnCancel: this.onCancel.bind(this), + }) + } + + onConfirm() { + if (FormValidators.validateFormGroup(this.createForm)) { + const { value } = this.createForm + + this.api + .saveBasicMaintenanceVendor({ + ...value, + + // maintenanceVendorId: value.maintenanceVendorId ?? 0, + }) + .subscribe((res) => { + this.msg.success(res.desc) + this.onCancel() + this.table.ref.reload() + }) + } + } + + async onCancel() { + this.drawerRef?.close() + this.createForm.reset({}) + } + + deleteItem(item: NzSafeAny) { + this.modal.confirm({ + nzTitle: '警告', + nzContent: '是否要删除该维保商?', + nzOnOk: async () => { + const res = await lastValueFrom(this.api.deleteBasicMaintenanceVendor([item.maintenanceVendorId])) + this.msg.success(res.desc) + this.table.ref.reload() + }, + }) + } +} diff --git a/web-admin-app/src/app/pages/fixed-asset/basic/basic-manufacturer/basic-manufacturer.component.html b/web-admin-app/src/app/pages/fixed-asset/basic/basic-manufacturer/basic-manufacturer.component.html new file mode 100644 index 0000000..3d993e6 --- /dev/null +++ b/web-admin-app/src/app/pages/fixed-asset/basic/basic-manufacturer/basic-manufacturer.component.html @@ -0,0 +1,75 @@ + + + + + + +
+ + + @switch (key) { + @case ('status') { + + } + + @default { + {{ data }} + } + } + + + + + + + + + + + +
+
+ + + + + + + + + +
+ + 名称 + + + + + + 编码 + + + + + + + 地址 + + + + + + 备注 + + + + +
+
+ + + + diff --git a/web-admin-app/src/app/pages/component-org-tree/component-org-tree.component.less b/web-admin-app/src/app/pages/fixed-asset/basic/basic-manufacturer/basic-manufacturer.component.less similarity index 100% rename from web-admin-app/src/app/pages/component-org-tree/component-org-tree.component.less rename to web-admin-app/src/app/pages/fixed-asset/basic/basic-manufacturer/basic-manufacturer.component.less diff --git a/web-admin-app/src/app/pages/fixed-asset/basic/basic-manufacturer/basic-manufacturer.component.ts b/web-admin-app/src/app/pages/fixed-asset/basic/basic-manufacturer/basic-manufacturer.component.ts new file mode 100644 index 0000000..f915dff --- /dev/null +++ b/web-admin-app/src/app/pages/fixed-asset/basic/basic-manufacturer/basic-manufacturer.component.ts @@ -0,0 +1,130 @@ +import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core' +import { SharedModule } from 'app/shared/shared.module' + +import { ApiService } from 'app/services' +import { FormBuilder, FormGroup } from '@angular/forms' +import { AnyObject, TableOption } from 'app/shared/components/server-paginated-table' +import { NzSafeAny } from 'ng-zorro-antd/core/types' +import { NzModalService } from 'ng-zorro-antd/modal' +import { NzMessageService } from 'ng-zorro-antd/message' +import { NzDrawerRef, NzDrawerService } from 'ng-zorro-antd/drawer' +import { lastValueFrom } from 'rxjs' +import { FormValidators } from 'app/utils' + +@Component({ + selector: 'app-basic-manufacturer', + standalone: true, + imports: [SharedModule], + templateUrl: './basic-manufacturer.component.html', + styleUrl: './basic-manufacturer.component.less', +}) +export class BasicManufacturerComponent { + constructor( + private modal: NzModalService, + private msg: NzMessageService, + private drawer: NzDrawerService, + private api: ApiService, + private fb: FormBuilder, + ) {} + + table = new TableOption(this.fetchData.bind(this)) + + queryForm!: FormGroup + + createForm!: FormGroup + + drawerRef?: NzDrawerRef + + @ViewChild('drawerFooterTpl') drawerFooterTpl!: TemplateRef + + @ViewChild('formContentTpl') formContentTpl!: TemplateRef + + initCreateForm() { + this.createForm = this.fb.group({ + manufacturersVendorId: [], + name: ['', [FormValidators.required('请输入')]], + code: ['', []], + notes: ['', []], + address: ['', []], + }) + } + initQueryForm() { + this.queryForm = this.fb.group({ + name: [''], + + code: [''], + }) + } + + ngOnInit(): void { + this.table + + .setColumn([ + { key: 'manufacturersVendorId', title: '主键', visible: false }, + { key: 'name', title: '名称' }, + { key: 'code', title: '编码' }, + + { key: 'address', title: '地址' }, + { key: 'notes', title: '备注' }, + { key: 'createTime', title: '创建时间' }, + ]) + .setRowOperate([ + { title: '编辑', onClick: this.onCreate.bind(this) }, + { title: '删除', onClick: this.deleteItem.bind(this) }, + ]) + this.initQueryForm() + this.initCreateForm() + } + + fetchData(p: {}, q: AnyObject) { + return this.api.getBasicManufacturersVendorPage({ ...p, ...q }) + } + + onCreate(data?: NzSafeAny) { + if (data) { + this.createForm.patchValue(data) + } + this.drawerRef = this.drawer.create({ + nzTitle: data ? '编辑生产商' : '新增生产商', + nzContent: this.formContentTpl, + nzFooter: this.drawerFooterTpl, + nzWidth: 600, + nzOnCancel: this.onCancel.bind(this), + }) + } + + onConfirm() { + if (FormValidators.validateFormGroup(this.createForm)) { + const { value } = this.createForm + + this.api + .saveBasicManufacturersVendor({ + ...value, + + // manufacturersVendorId: value.manufacturersVendorId ?? 0, + }) + .subscribe((res) => { + this.msg.success(res.desc) + this.onCancel() + this.table.ref.reload() + }) + } + } + + async onCancel() { + this.drawerRef?.close() + this.createForm.reset({}) + } + + deleteItem(item: NzSafeAny) { + this.modal.confirm({ + nzTitle: '警告', + nzContent: '是否要删除该生产商?', + nzOnOk: async () => { + const res = await lastValueFrom(this.api.deleteBasicManufacturersVendor([item.manufacturersVendorId])) + this.msg.success(res.desc) + this.table.ref.reload() + }, + }) + } +} diff --git a/web-admin-app/src/app/pages/fixed-asset/basic/basic-supplier/basic-supplier.component.html b/web-admin-app/src/app/pages/fixed-asset/basic/basic-supplier/basic-supplier.component.html new file mode 100644 index 0000000..07a59f6 --- /dev/null +++ b/web-admin-app/src/app/pages/fixed-asset/basic/basic-supplier/basic-supplier.component.html @@ -0,0 +1,108 @@ + + + + + + +
+ + + @switch (key) { + @case ('status') { + + } + + @default { + {{ data }} + } + } + + + + + + + + + + + + + + +
+
+ + + + + + + + + +
+ + 名称 + + + + + + 编码 + + + + + + 统一社会信用代码 + + + + + + 商务联系人 + + + + + + 商务联系方式 + + + + + + 售后联系人 + + + + + + 售后联系方式 + + + + + + + 地址 + + + + + + 备注 + + + + +
+
+ + + + diff --git a/web-admin-app/src/app/pages/system/system.component.less b/web-admin-app/src/app/pages/fixed-asset/basic/basic-supplier/basic-supplier.component.less similarity index 100% rename from web-admin-app/src/app/pages/system/system.component.less rename to web-admin-app/src/app/pages/fixed-asset/basic/basic-supplier/basic-supplier.component.less diff --git a/web-admin-app/src/app/pages/fixed-asset/basic/basic-supplier/basic-supplier.component.ts b/web-admin-app/src/app/pages/fixed-asset/basic/basic-supplier/basic-supplier.component.ts new file mode 100644 index 0000000..c4fa1af --- /dev/null +++ b/web-admin-app/src/app/pages/fixed-asset/basic/basic-supplier/basic-supplier.component.ts @@ -0,0 +1,135 @@ +import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core' +import { SharedModule } from 'app/shared/shared.module' + +import { ApiService } from 'app/services' +import { FormBuilder, FormGroup } from '@angular/forms' +import { AnyObject, TableOption } from 'app/shared/components/server-paginated-table' +import { NzSafeAny } from 'ng-zorro-antd/core/types' +import { NzModalService } from 'ng-zorro-antd/modal' +import { NzMessageService } from 'ng-zorro-antd/message' +import { NzDrawerRef, NzDrawerService } from 'ng-zorro-antd/drawer' +import { lastValueFrom } from 'rxjs' +import { FormValidators } from 'app/utils' + +@Component({ + selector: 'app-basic-supplier', + standalone: true, + imports: [SharedModule], + templateUrl: './basic-supplier.component.html', + styleUrl: './basic-supplier.component.less', +}) +export class BasicSupplierComponent { + constructor( + private modal: NzModalService, + private msg: NzMessageService, + private drawer: NzDrawerService, + private api: ApiService, + private fb: FormBuilder, + ) {} + + table = new TableOption(this.fetchData.bind(this)) + + queryForm!: FormGroup + + createForm!: FormGroup + + drawerRef?: NzDrawerRef + + @ViewChild('drawerFooterTpl') drawerFooterTpl!: TemplateRef + + @ViewChild('formContentTpl') formContentTpl!: TemplateRef + + initCreateForm() { + this.createForm = this.fb.group({ + supplierVendorId: [], + name: ['', [FormValidators.required('请输入')]], + code: ['', []], + uscc: ['', []], + notes: ['', []], + businessContactor: ['', []], + businessContact: ['', []], + afterSalesContactor: ['', []], + afterSalesContact: ['', []], + address: ['', []], + }) + } + initQueryForm() { + this.queryForm = this.fb.group({ + name: [''], + uscc: [''], + code: [''], + }) + } + + ngOnInit(): void { + this.table + + .setColumn([ + { key: 'name', title: '名称' }, + { key: 'code', title: '编码' }, + { key: 'uscc', title: '统一社会信用代码' }, + { key: 'businessContactor', title: '商务联系人' }, + { key: 'businessContact', title: '商务联系方式' }, + { key: 'afterSalesContactor', title: '售后联系人' }, + { key: 'afterSalesContact', title: '售后联系方式' }, + { key: 'address', title: '地址' }, + { key: 'notes', title: '备注' }, + ]) + .setRowOperate([ + { title: '编辑', onClick: this.onCreate.bind(this) }, + { title: '删除', onClick: this.deleteItem.bind(this) }, + ]) + this.initQueryForm() + this.initCreateForm() + } + + fetchData(p: {}, q: AnyObject) { + return this.api.getBasicSupplierVendorPage({ ...p, ...q }) + } + + onCreate(data?: NzSafeAny) { + if (data) { + this.createForm.patchValue(data) + } + this.drawerRef = this.drawer.create({ + nzTitle: data ? '编辑供应商' : '新增供应商', + nzContent: this.formContentTpl, + nzFooter: this.drawerFooterTpl, + nzWidth: 600, + nzOnCancel: this.onCancel.bind(this), + }) + } + + onConfirm() { + if (FormValidators.validateFormGroup(this.createForm)) { + const { value } = this.createForm + + this.api + .saveBasicSupplierVendor({ + ...value, + }) + .subscribe((res) => { + this.msg.success(res.desc) + this.onCancel() + this.table.ref.reload() + }) + } + } + + async onCancel() { + this.drawerRef?.close() + this.createForm.reset({}) + } + + deleteItem(item: NzSafeAny) { + this.modal.confirm({ + nzTitle: '警告', + nzContent: '是否要删除该供应商?', + nzOnOk: async () => { + const res = await lastValueFrom(this.api.deleteBasicSupplierVendor([item.supplierVendorId])) + this.msg.success(res.desc) + this.table.ref.reload() + }, + }) + } +} diff --git a/web-admin-app/src/app/pages/fixed-asset/basic/basic-warehouse/basic-warehouse.component.html b/web-admin-app/src/app/pages/fixed-asset/basic/basic-warehouse/basic-warehouse.component.html new file mode 100644 index 0000000..fa34e2d --- /dev/null +++ b/web-admin-app/src/app/pages/fixed-asset/basic/basic-warehouse/basic-warehouse.component.html @@ -0,0 +1,77 @@ + + + + + + +
+
+ + + @switch (key) { + @case ('status') { + + } + + @default { + {{ data }} + } + } + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + +
+ + 名称 + + + + + + 状态 + + + + + + + +
+
+ + + + diff --git a/web-admin-app/src/app/pages/fixed-asset/basic/basic-warehouse/basic-warehouse.component.less b/web-admin-app/src/app/pages/fixed-asset/basic/basic-warehouse/basic-warehouse.component.less new file mode 100644 index 0000000..e69de29 diff --git a/web-admin-app/src/app/pages/fixed-asset/basic/basic-warehouse/basic-warehouse.component.ts b/web-admin-app/src/app/pages/fixed-asset/basic/basic-warehouse/basic-warehouse.component.ts new file mode 100644 index 0000000..b546817 --- /dev/null +++ b/web-admin-app/src/app/pages/fixed-asset/basic/basic-warehouse/basic-warehouse.component.ts @@ -0,0 +1,125 @@ +import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core' +import { SharedModule } from 'app/shared/shared.module' + +import { ApiService } from 'app/services' +import { FormBuilder, FormGroup } from '@angular/forms' +import { AnyObject, TableOption } from 'app/shared/components/server-paginated-table' +import { NzSafeAny } from 'ng-zorro-antd/core/types' +import { NzModalService } from 'ng-zorro-antd/modal' +import { NzMessageService } from 'ng-zorro-antd/message' +import { NzDrawerRef, NzDrawerService } from 'ng-zorro-antd/drawer' +import { lastValueFrom } from 'rxjs' +import { FormValidators } from 'app/utils' + +@Component({ + selector: 'app-basic-warehouse', + standalone: true, + imports: [SharedModule], + templateUrl: './basic-warehouse.component.html', + styleUrl: './basic-warehouse.component.less', +}) +export class BasicWarehouseComponent { + constructor( + private modal: NzModalService, + private msg: NzMessageService, + private drawer: NzDrawerService, + private api: ApiService, + private fb: FormBuilder, + ) {} + + table = new TableOption(this.fetchData.bind(this)) + + queryForm!: FormGroup + + createForm!: FormGroup + + drawerRef?: NzDrawerRef + + @ViewChild('drawerFooterTpl') drawerFooterTpl!: TemplateRef + + @ViewChild('formContentTpl') formContentTpl!: TemplateRef + + initCreateForm() { + this.createForm = this.fb.group({ + warehouseId: [], + name: ['', [FormValidators.required('请输入')]], + status: [0, [FormValidators.required('请选择')]], + notes: ['', []], + }) + } + initQueryForm() { + this.queryForm = this.fb.group({ + name: [''], + status: [], + }) + } + + ngOnInit(): void { + this.table + + .setColumn([ + { key: 'warehouseId', title: '主键', visible: false }, + { key: 'name', title: '名称' }, + { key: 'status', title: '状态' }, + { key: 'createTime', title: '创建时间' }, + ]) + .setRowOperate([ + { title: '编辑', onClick: this.onCreate.bind(this) }, + { title: '删除', onClick: this.deleteItem.bind(this) }, + ]) + this.initQueryForm() + this.initCreateForm() + } + + fetchData(p: {}, q: AnyObject) { + return this.api.getBasicWarehousePage({ ...p, ...q }) + } + + onCreate(data?: NzSafeAny) { + if (data) { + this.createForm.patchValue(data) + } + this.drawerRef = this.drawer.create({ + nzTitle: data ? '编辑存放仓库' : '新增存放仓库', + nzContent: this.formContentTpl, + nzFooter: this.drawerFooterTpl, + nzWidth: 600, + nzOnCancel: this.onCancel.bind(this), + }) + } + + onConfirm() { + if (FormValidators.validateFormGroup(this.createForm)) { + const { value } = this.createForm + + this.api + .saveBasicWarehouse({ + ...value, + + // warehouseId: value.warehouseId ?? 0, + }) + .subscribe((res) => { + this.msg.success(res.desc) + this.onCancel() + this.table.ref.reload() + }) + } + } + + async onCancel() { + this.drawerRef?.close() + this.createForm.reset({ status: 0 }) + } + + deleteItem(item: NzSafeAny) { + this.modal.confirm({ + nzTitle: '警告', + nzContent: '是否要删除该存放仓库?', + nzOnOk: async () => { + const res = await lastValueFrom(this.api.deleteBasicWarehouse([item.warehouseId])) + this.msg.success(res.desc) + this.table.ref.reload() + }, + }) + } +} diff --git a/web-admin-app/src/app/pages/fixed-asset/basic/save-position/save-position.component.html b/web-admin-app/src/app/pages/fixed-asset/basic/save-position/save-position.component.html new file mode 100644 index 0000000..c5facf6 --- /dev/null +++ b/web-admin-app/src/app/pages/fixed-asset/basic/save-position/save-position.component.html @@ -0,0 +1,55 @@ + + + + + + +
+
+ + + @switch (key) { + @case ('status') { + + } + + @default { + {{ data }} + } + } + + + + + + + + +
+
+
+ + + + + + + + + +
+ + 名称 + + + + +
+
+ + + + diff --git a/web-admin-app/src/app/pages/fixed-asset/basic/save-position/save-position.component.less b/web-admin-app/src/app/pages/fixed-asset/basic/save-position/save-position.component.less new file mode 100644 index 0000000..e69de29 diff --git a/web-admin-app/src/app/pages/fixed-asset/basic/save-position/save-position.component.ts b/web-admin-app/src/app/pages/fixed-asset/basic/save-position/save-position.component.ts new file mode 100644 index 0000000..154521f --- /dev/null +++ b/web-admin-app/src/app/pages/fixed-asset/basic/save-position/save-position.component.ts @@ -0,0 +1,122 @@ +import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core' +import { SharedModule } from 'app/shared/shared.module' +import { ComponentOrgTreeComponent } from 'app/components/component-org-tree/component-org-tree.component' + +import { format } from 'date-fns' +import { ApiService } from 'app/services' +import { FormBuilder, FormGroup } from '@angular/forms' +import { AnyObject, TableOption } from 'app/shared/components/server-paginated-table' +import { NzSafeAny } from 'ng-zorro-antd/core/types' +import { NzModalService } from 'ng-zorro-antd/modal' +import { NzMessageService } from 'ng-zorro-antd/message' +import { NzDrawerRef, NzDrawerService } from 'ng-zorro-antd/drawer' +import { lastValueFrom } from 'rxjs' +import { FormValidators } from 'app/utils' + +@Component({ + selector: 'app-save-position', + standalone: true, + imports: [SharedModule, ComponentOrgTreeComponent], + templateUrl: './save-position.component.html', + styleUrl: './save-position.component.less', +}) +export class SavePositionComponent implements OnInit { + constructor( + private modal: NzModalService, + private msg: NzMessageService, + private drawer: NzDrawerService, + private api: ApiService, + private fb: FormBuilder, + ) {} + + table = new TableOption(this.fetchData.bind(this)) + + queryForm!: FormGroup + + createForm!: FormGroup + + drawerRef?: NzDrawerRef + + @ViewChild('drawerFooterTpl') drawerFooterTpl!: TemplateRef + + @ViewChild('formContentTpl') formContentTpl!: TemplateRef + + initCreateForm() { + this.createForm = this.fb.group({ + positionId: [], + name: ['', FormValidators.required('请输入')], + }) + } + initQueryForm() { + this.queryForm = this.fb.group({ + name: [''], + }) + } + + ngOnInit(): void { + this.table + + .setColumn([ + { key: 'positionId', title: '编号', width: '100px' }, + { key: 'name', title: '名称' }, + ]) + .setRowOperate([ + { title: '编辑', onClick: this.onCreate.bind(this) }, + { title: '删除', onClick: this.deleteItem.bind(this) }, + ]) + this.initQueryForm() + this.initCreateForm() + } + + fetchData(p: {}, q: AnyObject) { + return this.api.getBasicPositionPage({ ...p, ...q }) + } + + onCreate(data?: NzSafeAny) { + if (data) { + this.createForm.patchValue(data) + } + this.drawerRef = this.drawer.create({ + nzTitle: data ? '编辑存放位置' : '新增存放位置', + nzContent: this.formContentTpl, + nzFooter: this.drawerFooterTpl, + nzWidth: 600, + nzOnCancel: this.onCancel.bind(this), + }) + } + + onConfirm() { + if (FormValidators.validateFormGroup(this.createForm)) { + const { value } = this.createForm + + this.api + .saveBasicPosition({ + ...value, + parentId: 0, + positionId: value.positionId ?? 0, + }) + .subscribe((res) => { + this.msg.success(res.desc) + this.onCancel() + this.table.ref.reload() + }) + } + } + + async onCancel() { + this.drawerRef?.close() + this.createForm.reset({}) + } + + deleteItem(item: NzSafeAny) { + this.modal.confirm({ + nzTitle: '警告', + nzContent: '是否要删除该存放位置?', + nzOnOk: async () => { + const res = await lastValueFrom(this.api.deleteBasicPosition([item.positionId])) + this.msg.success(res.desc) + this.table.ref.reload() + }, + }) + } +} diff --git a/web-admin-app/src/app/pages/fixed-asset/fixed-asset.component.html b/web-admin-app/src/app/pages/fixed-asset/fixed-asset.component.html index a082672..b37b3a0 100644 --- a/web-admin-app/src/app/pages/fixed-asset/fixed-asset.component.html +++ b/web-admin-app/src/app/pages/fixed-asset/fixed-asset.component.html @@ -1,4 +1,6 @@ -
+ - +
+ +
diff --git a/web-admin-app/src/app/pages/fixed-asset/fixed-asset.component.less b/web-admin-app/src/app/pages/fixed-asset/fixed-asset.component.less index 0bf4d7d..9d03848 100644 --- a/web-admin-app/src/app/pages/fixed-asset/fixed-asset.component.less +++ b/web-admin-app/src/app/pages/fixed-asset/fixed-asset.component.less @@ -1,4 +1,6 @@ -:host { - display: flex !important; - width: 100%; -} \ No newline at end of file +// :host { +// display: flex !important; +// width: auto; +// overflow: hidden; + +// } \ No newline at end of file diff --git a/web-admin-app/src/app/pages/fixed-asset/ledger/fixed-asset-belong/fixed-asset-belong.component.ts b/web-admin-app/src/app/pages/fixed-asset/ledger/fixed-asset-belong/fixed-asset-belong.component.ts index 1831785..13e06f3 100644 --- a/web-admin-app/src/app/pages/fixed-asset/ledger/fixed-asset-belong/fixed-asset-belong.component.ts +++ b/web-admin-app/src/app/pages/fixed-asset/ledger/fixed-asset-belong/fixed-asset-belong.component.ts @@ -1,7 +1,7 @@ import { Component } from '@angular/core' import { FormControl, FormGroup } from '@angular/forms' -import { AnyObject, TableOption } from 'app/components/server-paginated-table' -import { ComponentOrgTreeComponent } from 'app/pages/component-org-tree/component-org-tree.component' +import { AnyObject, TableOption } from 'app/shared/components/server-paginated-table' +import { ComponentOrgTreeComponent } from 'app/components/component-org-tree/component-org-tree.component' import { ApiService } from 'app/services' import { SharedModule } from 'app/shared/shared.module' import { format } from 'date-fns' diff --git a/web-admin-app/src/app/pages/fixed-asset/ledger/fixed-asset-category/fixed-asset-category.component.ts b/web-admin-app/src/app/pages/fixed-asset/ledger/fixed-asset-category/fixed-asset-category.component.ts index d1177e8..3d5ebbe 100644 --- a/web-admin-app/src/app/pages/fixed-asset/ledger/fixed-asset-category/fixed-asset-category.component.ts +++ b/web-admin-app/src/app/pages/fixed-asset/ledger/fixed-asset-category/fixed-asset-category.component.ts @@ -1,6 +1,6 @@ import { Component } from '@angular/core' import { FormControl, FormGroup } from '@angular/forms' -import { AnyObject, TableOption } from 'app/components/server-paginated-table' +import { AnyObject, TableOption } from 'app/shared/components/server-paginated-table' import { ApiService } from 'app/services' import { SharedModule } from 'app/shared/shared.module' import { format } from 'date-fns' diff --git a/web-admin-app/src/app/pages/fixed-asset/ledger/fixed-asset-employee/fixed-asset-employee.component.ts b/web-admin-app/src/app/pages/fixed-asset/ledger/fixed-asset-employee/fixed-asset-employee.component.ts index 585af41..da794c7 100644 --- a/web-admin-app/src/app/pages/fixed-asset/ledger/fixed-asset-employee/fixed-asset-employee.component.ts +++ b/web-admin-app/src/app/pages/fixed-asset/ledger/fixed-asset-employee/fixed-asset-employee.component.ts @@ -1,6 +1,6 @@ import { Component } from '@angular/core' import { FormControl, FormGroup } from '@angular/forms' -import { AnyObject, TableOption } from 'app/components/server-paginated-table' +import { AnyObject, TableOption } from 'app/shared/components/server-paginated-table' import { ApiService } from 'app/services' import { SharedModule } from 'app/shared/shared.module' import { format } from 'date-fns' diff --git a/web-admin-app/src/app/pages/fixed-asset/ledger/fixed-asset-ledger/fixed-asset-ledger.component.ts b/web-admin-app/src/app/pages/fixed-asset/ledger/fixed-asset-ledger/fixed-asset-ledger.component.ts index 74d3c42..5348189 100644 --- a/web-admin-app/src/app/pages/fixed-asset/ledger/fixed-asset-ledger/fixed-asset-ledger.component.ts +++ b/web-admin-app/src/app/pages/fixed-asset/ledger/fixed-asset-ledger/fixed-asset-ledger.component.ts @@ -1,6 +1,6 @@ import { Component, OnInit } from '@angular/core' import { ActivatedRoute, NavigationEnd, Router } from '@angular/router' -import { AppPageComponent } from 'app/components/app-page/app-page.component' + import { SharedModule } from 'app/shared/shared.module' import { Subscription, filter } from 'rxjs' @@ -38,7 +38,7 @@ const tabs = [ @Component({ selector: 'app-fixed-asset-ledger', standalone: true, - imports: [SharedModule, AppPageComponent], + imports: [SharedModule], templateUrl: './fixed-asset-ledger.component.html', styleUrl: './fixed-asset-ledger.component.less', }) diff --git a/web-admin-app/src/app/pages/fixed-asset/ledger/fixed-asset-myown/fixed-asset-myown.component.ts b/web-admin-app/src/app/pages/fixed-asset/ledger/fixed-asset-myown/fixed-asset-myown.component.ts index f78c8ad..69d2a0e 100644 --- a/web-admin-app/src/app/pages/fixed-asset/ledger/fixed-asset-myown/fixed-asset-myown.component.ts +++ b/web-admin-app/src/app/pages/fixed-asset/ledger/fixed-asset-myown/fixed-asset-myown.component.ts @@ -1,6 +1,6 @@ import { Component } from '@angular/core' import { FormControl, FormGroup } from '@angular/forms' -import { AnyObject, TableOption } from 'app/components/server-paginated-table' +import { AnyObject, TableOption } from 'app/shared/components/server-paginated-table' import { ApiService } from 'app/services' import { SharedModule } from 'app/shared/shared.module' import { format } from 'date-fns' diff --git a/web-admin-app/src/app/pages/fixed-asset/ledger/fixed-asset-org/fixed-asset-org.component.ts b/web-admin-app/src/app/pages/fixed-asset/ledger/fixed-asset-org/fixed-asset-org.component.ts index c313b7e..939825d 100644 --- a/web-admin-app/src/app/pages/fixed-asset/ledger/fixed-asset-org/fixed-asset-org.component.ts +++ b/web-admin-app/src/app/pages/fixed-asset/ledger/fixed-asset-org/fixed-asset-org.component.ts @@ -1,6 +1,6 @@ import { Component } from '@angular/core' import { FormControl, FormGroup } from '@angular/forms' -import { AnyObject, TableOption } from 'app/components/server-paginated-table' +import { AnyObject, TableOption } from 'app/shared/components/server-paginated-table' import { ApiService } from 'app/services' import { SharedModule } from 'app/shared/shared.module' import { format } from 'date-fns' diff --git a/web-admin-app/src/app/pages/fixed-asset/ledger/fixed-asset-position/fixed-asset-position.component.ts b/web-admin-app/src/app/pages/fixed-asset/ledger/fixed-asset-position/fixed-asset-position.component.ts index d26ca9f..5cef505 100644 --- a/web-admin-app/src/app/pages/fixed-asset/ledger/fixed-asset-position/fixed-asset-position.component.ts +++ b/web-admin-app/src/app/pages/fixed-asset/ledger/fixed-asset-position/fixed-asset-position.component.ts @@ -1,6 +1,6 @@ import { Component } from '@angular/core' import { FormControl, FormGroup } from '@angular/forms' -import { AnyObject, TableOption } from 'app/components/server-paginated-table' +import { AnyObject, TableOption } from 'app/shared/components/server-paginated-table' import { ApiService } from 'app/services' import { SharedModule } from 'app/shared/shared.module' import { format } from 'date-fns' diff --git a/web-admin-app/src/app/pages/fixed-asset/ledger/fixed-asset-search/fixed-asset-search.component.ts b/web-admin-app/src/app/pages/fixed-asset/ledger/fixed-asset-search/fixed-asset-search.component.ts index 3f802e0..a843f10 100644 --- a/web-admin-app/src/app/pages/fixed-asset/ledger/fixed-asset-search/fixed-asset-search.component.ts +++ b/web-admin-app/src/app/pages/fixed-asset/ledger/fixed-asset-search/fixed-asset-search.component.ts @@ -1,6 +1,6 @@ import { Component } from '@angular/core' import { FormControl, FormGroup } from '@angular/forms' -import { AnyObject, TableOption } from 'app/components/server-paginated-table' +import { AnyObject, TableOption } from 'app/shared/components/server-paginated-table' import { ApiService } from 'app/services' import { SharedModule } from 'app/shared/shared.module' import { format } from 'date-fns' diff --git a/web-admin-app/src/app/pages/fixed-asset/manage/fixed-asset-manage-allot/fixed-asset-manage-allot.component.ts b/web-admin-app/src/app/pages/fixed-asset/manage/fixed-asset-manage-allot/fixed-asset-manage-allot.component.ts index a03d665..c056b51 100644 --- a/web-admin-app/src/app/pages/fixed-asset/manage/fixed-asset-manage-allot/fixed-asset-manage-allot.component.ts +++ b/web-admin-app/src/app/pages/fixed-asset/manage/fixed-asset-manage-allot/fixed-asset-manage-allot.component.ts @@ -1,7 +1,7 @@ import { Component } from '@angular/core' import { FormControl, FormGroup } from '@angular/forms' -import { AppPageComponent } from 'app/components/app-page/app-page.component' -import { AnyObject, TableOption } from 'app/components/server-paginated-table' + +import { AnyObject, TableOption } from 'app/shared/components/server-paginated-table' import { ApiService } from 'app/services' import { SharedModule } from 'app/shared/shared.module' import { format } from 'date-fns' @@ -10,7 +10,7 @@ import { of } from 'rxjs' @Component({ selector: 'app-fixed-asset-manage-allot', standalone: true, - imports: [SharedModule, AppPageComponent], + imports: [SharedModule], templateUrl: './fixed-asset-manage-allot.component.html', styleUrl: './fixed-asset-manage-allot.component.less', }) diff --git a/web-admin-app/src/app/pages/fixed-asset/manage/fixed-asset-manage-borrow/fixed-asset-manage-borrow.component.ts b/web-admin-app/src/app/pages/fixed-asset/manage/fixed-asset-manage-borrow/fixed-asset-manage-borrow.component.ts index 1bbdc27..f8188e7 100644 --- a/web-admin-app/src/app/pages/fixed-asset/manage/fixed-asset-manage-borrow/fixed-asset-manage-borrow.component.ts +++ b/web-admin-app/src/app/pages/fixed-asset/manage/fixed-asset-manage-borrow/fixed-asset-manage-borrow.component.ts @@ -1,7 +1,7 @@ import { Component } from '@angular/core' import { FormControl, FormGroup } from '@angular/forms' -import { AppPageComponent } from 'app/components/app-page/app-page.component' -import { AnyObject, TableOption } from 'app/components/server-paginated-table' + +import { AnyObject, TableOption } from 'app/shared/components/server-paginated-table' import { ApiService } from 'app/services' import { SharedModule } from 'app/shared/shared.module' import { format } from 'date-fns' @@ -9,7 +9,7 @@ import { of } from 'rxjs' @Component({ selector: 'app-fixed-asset-manage-borrow', standalone: true, - imports: [SharedModule, AppPageComponent], + imports: [SharedModule], templateUrl: './fixed-asset-manage-borrow.component.html', styleUrl: './fixed-asset-manage-borrow.component.less', }) diff --git a/web-admin-app/src/app/pages/fixed-asset/manage/fixed-asset-manage-distribution/fixed-asset-manage-distribution.component.ts b/web-admin-app/src/app/pages/fixed-asset/manage/fixed-asset-manage-distribution/fixed-asset-manage-distribution.component.ts index 6b7ec49..42969bd 100644 --- a/web-admin-app/src/app/pages/fixed-asset/manage/fixed-asset-manage-distribution/fixed-asset-manage-distribution.component.ts +++ b/web-admin-app/src/app/pages/fixed-asset/manage/fixed-asset-manage-distribution/fixed-asset-manage-distribution.component.ts @@ -1,7 +1,7 @@ import { Component } from '@angular/core' import { FormControl, FormGroup } from '@angular/forms' -import { AppPageComponent } from 'app/components/app-page/app-page.component' -import { AnyObject, TableOption } from 'app/components/server-paginated-table' + +import { AnyObject, TableOption } from 'app/shared/components/server-paginated-table' import { ApiService } from 'app/services' import { SharedModule } from 'app/shared/shared.module' import { format } from 'date-fns' @@ -10,7 +10,7 @@ import { of } from 'rxjs' @Component({ selector: 'app-fixed-asset-manage-distribution', standalone: true, - imports: [SharedModule, AppPageComponent], + imports: [SharedModule], templateUrl: './fixed-asset-manage-distribution.component.html', styleUrl: './fixed-asset-manage-distribution.component.less', }) diff --git a/web-admin-app/src/app/pages/fixed-asset/manage/fixed-asset-manage-entry/fixed-asset-manage-entry.component.ts b/web-admin-app/src/app/pages/fixed-asset/manage/fixed-asset-manage-entry/fixed-asset-manage-entry.component.ts index 00e8b53..26900f9 100644 --- a/web-admin-app/src/app/pages/fixed-asset/manage/fixed-asset-manage-entry/fixed-asset-manage-entry.component.ts +++ b/web-admin-app/src/app/pages/fixed-asset/manage/fixed-asset-manage-entry/fixed-asset-manage-entry.component.ts @@ -1,7 +1,7 @@ import { Component } from '@angular/core' import { FormControl, FormGroup } from '@angular/forms' -import { AppPageComponent } from 'app/components/app-page/app-page.component' -import { AnyObject, TableOption } from 'app/components/server-paginated-table' + +import { AnyObject, TableOption } from 'app/shared/components/server-paginated-table' import { ApiService } from 'app/services' import { SharedModule } from 'app/shared/shared.module' import { format } from 'date-fns' @@ -10,7 +10,7 @@ import { of } from 'rxjs' @Component({ selector: 'app-fixed-asset-manage-entry', standalone: true, - imports: [SharedModule, AppPageComponent], + imports: [SharedModule], templateUrl: './fixed-asset-manage-entry.component.html', styleUrl: './fixed-asset-manage-entry.component.less', }) diff --git a/web-admin-app/src/app/pages/fixed-asset/manage/fixed-asset-manage-return/fixed-asset-manage-return.component.ts b/web-admin-app/src/app/pages/fixed-asset/manage/fixed-asset-manage-return/fixed-asset-manage-return.component.ts index 2755cb8..65fe9ec 100644 --- a/web-admin-app/src/app/pages/fixed-asset/manage/fixed-asset-manage-return/fixed-asset-manage-return.component.ts +++ b/web-admin-app/src/app/pages/fixed-asset/manage/fixed-asset-manage-return/fixed-asset-manage-return.component.ts @@ -1,7 +1,7 @@ import { Component } from '@angular/core' import { FormControl, FormGroup } from '@angular/forms' -import { AppPageComponent } from 'app/components/app-page/app-page.component' -import { AnyObject, TableOption } from 'app/components/server-paginated-table' + +import { AnyObject, TableOption } from 'app/shared/components/server-paginated-table' import { ApiService } from 'app/services' import { SharedModule } from 'app/shared/shared.module' import { format } from 'date-fns' @@ -10,7 +10,7 @@ import { of } from 'rxjs' @Component({ selector: 'app-fixed-asset-manage-return', standalone: true, - imports: [SharedModule, AppPageComponent], + imports: [SharedModule], templateUrl: './fixed-asset-manage-return.component.html', styleUrl: './fixed-asset-manage-return.component.less', }) diff --git a/web-admin-app/src/app/pages/fixed-asset/manage/fixed-asset-manage-revert/fixed-asset-manage-revert.component.ts b/web-admin-app/src/app/pages/fixed-asset/manage/fixed-asset-manage-revert/fixed-asset-manage-revert.component.ts index 2fc5e15..ec4c127 100644 --- a/web-admin-app/src/app/pages/fixed-asset/manage/fixed-asset-manage-revert/fixed-asset-manage-revert.component.ts +++ b/web-admin-app/src/app/pages/fixed-asset/manage/fixed-asset-manage-revert/fixed-asset-manage-revert.component.ts @@ -1,8 +1,8 @@ import { Component } from '@angular/core' import { FormControl, FormGroup } from '@angular/forms' -import { AppPageComponent } from 'app/components/app-page/app-page.component' -import { AnyObject, TableOption } from 'app/components/server-paginated-table' + import { ApiService } from 'app/services' +import { AnyObject, TableOption } from 'app/shared/components/server-paginated-table' import { SharedModule } from 'app/shared/shared.module' import { format } from 'date-fns' import { of } from 'rxjs' @@ -10,7 +10,7 @@ import { of } from 'rxjs' @Component({ selector: 'app-fixed-asset-manage-revert', standalone: true, - imports: [SharedModule, AppPageComponent], + imports: [SharedModule], templateUrl: './fixed-asset-manage-revert.component.html', styleUrl: './fixed-asset-manage-revert.component.less', }) diff --git a/web-admin-app/src/app/pages/fixed-asset/manage/fixed-asset-manage-scrap/fixed-asset-manage-scrap.component.ts b/web-admin-app/src/app/pages/fixed-asset/manage/fixed-asset-manage-scrap/fixed-asset-manage-scrap.component.ts index 33add4b..2733c91 100644 --- a/web-admin-app/src/app/pages/fixed-asset/manage/fixed-asset-manage-scrap/fixed-asset-manage-scrap.component.ts +++ b/web-admin-app/src/app/pages/fixed-asset/manage/fixed-asset-manage-scrap/fixed-asset-manage-scrap.component.ts @@ -1,7 +1,7 @@ import { Component } from '@angular/core' import { FormControl, FormGroup } from '@angular/forms' -import { AppPageComponent } from 'app/components/app-page/app-page.component' -import { AnyObject, TableOption } from 'app/components/server-paginated-table' + +import { AnyObject, TableOption } from 'app/shared/components/server-paginated-table' import { ApiService } from 'app/services' import { SharedModule } from 'app/shared/shared.module' import { format } from 'date-fns' @@ -10,7 +10,7 @@ import { of } from 'rxjs' @Component({ selector: 'app-fixed-asset-manage-scrap', standalone: true, - imports: [SharedModule, AppPageComponent], + imports: [SharedModule], templateUrl: './fixed-asset-manage-scrap.component.html', styleUrl: './fixed-asset-manage-scrap.component.less', }) diff --git a/web-admin-app/src/app/pages/fixed-asset/manage/fixed-asset-manage-transfer/fixed-asset-manage-transfer.component.ts b/web-admin-app/src/app/pages/fixed-asset/manage/fixed-asset-manage-transfer/fixed-asset-manage-transfer.component.ts index 2bc5d0d..cd7c6d2 100644 --- a/web-admin-app/src/app/pages/fixed-asset/manage/fixed-asset-manage-transfer/fixed-asset-manage-transfer.component.ts +++ b/web-admin-app/src/app/pages/fixed-asset/manage/fixed-asset-manage-transfer/fixed-asset-manage-transfer.component.ts @@ -1,7 +1,7 @@ import { Component } from '@angular/core' import { FormControl, FormGroup } from '@angular/forms' -import { AppPageComponent } from 'app/components/app-page/app-page.component' -import { AnyObject, TableOption } from 'app/components/server-paginated-table' + +import { AnyObject, TableOption } from 'app/shared/components/server-paginated-table' import { ApiService } from 'app/services' import { SharedModule } from 'app/shared/shared.module' import { format } from 'date-fns' @@ -10,7 +10,7 @@ import { of } from 'rxjs' @Component({ selector: 'app-fixed-asset-manage-transfer', standalone: true, - imports: [SharedModule, AppPageComponent], + imports: [SharedModule], templateUrl: './fixed-asset-manage-transfer.component.html', styleUrl: './fixed-asset-manage-transfer.component.less', }) diff --git a/web-admin-app/src/app/pages/fixed-asset/manage/fixed-asset-manage/fixed-asset-manage.component.ts b/web-admin-app/src/app/pages/fixed-asset/manage/fixed-asset-manage/fixed-asset-manage.component.ts index 385408e..8ae9f18 100644 --- a/web-admin-app/src/app/pages/fixed-asset/manage/fixed-asset-manage/fixed-asset-manage.component.ts +++ b/web-admin-app/src/app/pages/fixed-asset/manage/fixed-asset-manage/fixed-asset-manage.component.ts @@ -1,7 +1,7 @@ import { Component } from '@angular/core' import { FormControl, FormGroup } from '@angular/forms' -import { AppPageComponent } from 'app/components/app-page/app-page.component' -import { AnyObject, TableOption } from 'app/components/server-paginated-table' + +import { AnyObject, TableOption } from 'app/shared/components/server-paginated-table' import { ApiService } from 'app/services' import { SharedModule } from 'app/shared/shared.module' import { format } from 'date-fns' @@ -10,7 +10,7 @@ import { of } from 'rxjs' @Component({ selector: 'app-fixed-asset-manage', standalone: true, - imports: [SharedModule, AppPageComponent], + imports: [SharedModule], templateUrl: './fixed-asset-manage.component.html', styleUrl: './fixed-asset-manage.component.less', }) diff --git a/web-admin-app/src/app/pages/fixed-asset/stocktaking/stockaking-job/stockaking-job.component.html b/web-admin-app/src/app/pages/fixed-asset/stocktaking/stockaking-job/stockaking-job.component.html new file mode 100644 index 0000000..8c07129 --- /dev/null +++ b/web-admin-app/src/app/pages/fixed-asset/stocktaking/stockaking-job/stockaking-job.component.html @@ -0,0 +1,179 @@ + +
+ + + @switch (key) { + @case ('fullStocktaking') { + @switch (data) { + @case (0) { + + } + @case (1) { + + } + @default { + - + } + } + } + @case ('status') { + @switch (data) { + @case (0) { + + } + @case (1) { + + } + @case (2) { + + } + @case (3) { + + } + @default { + - + } + } + } + + @default { + {{ data }} + } + } + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + +
+ + 名称 + + + + + + 全员盘点 + + + + + + + + + 负责人 + + + + + + 盘点人 + + + + + 备注 + + + + + +

盘点范围

+ + 购置开始日期 + + + + + + 购置结束日期 + + + + + + 资产分类 + + + + + + 资产状态 + + + + + + 位置 + + + + + + 仓库 + + + + + + 所属公司 + + + + + + 使用公司/部门 + + + + + + 保管人 + + + + +
+
+ + + + diff --git a/web-admin-app/src/app/pages/fixed-asset/stocktaking/stockaking-job/stockaking-job.component.less b/web-admin-app/src/app/pages/fixed-asset/stocktaking/stockaking-job/stockaking-job.component.less new file mode 100644 index 0000000..e69de29 diff --git a/web-admin-app/src/app/pages/fixed-asset/stocktaking/stockaking-job/stockaking-job.component.ts b/web-admin-app/src/app/pages/fixed-asset/stocktaking/stockaking-job/stockaking-job.component.ts new file mode 100644 index 0000000..df8e92d --- /dev/null +++ b/web-admin-app/src/app/pages/fixed-asset/stocktaking/stockaking-job/stockaking-job.component.ts @@ -0,0 +1,162 @@ +import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core' +import { SharedModule } from 'app/shared/shared.module' +import { ApiService } from 'app/services' +import { FormBuilder, FormGroup } from '@angular/forms' +import { AnyObject, TableOption } from 'app/shared/components/server-paginated-table' +import { NzSafeAny } from 'ng-zorro-antd/core/types' +import { NzModalService } from 'ng-zorro-antd/modal' +import { NzMessageService } from 'ng-zorro-antd/message' +import { NzDrawerRef, NzDrawerService } from 'ng-zorro-antd/drawer' +import { lastValueFrom } from 'rxjs' +import { FormValidators } from 'app/utils' +import { SelectUserByOrgComponent } from 'app/components' + +@Component({ + selector: 'app-stockaking-job', + standalone: true, + imports: [SharedModule, SelectUserByOrgComponent], + templateUrl: './stockaking-job.component.html', + styleUrl: './stockaking-job.component.less', +}) +export class StockakingJobComponent { + constructor( + private modal: NzModalService, + private msg: NzMessageService, + private drawer: NzDrawerService, + private api: ApiService, + private fb: FormBuilder, + ) {} + + table = new TableOption(this.fetchData.bind(this)) + + queryForm!: FormGroup + + createForm!: FormGroup + + drawerRef?: NzDrawerRef + + @ViewChild('drawerFooterTpl') drawerFooterTpl!: TemplateRef + + @ViewChild('formContentTpl') formContentTpl!: TemplateRef + + initCreateForm() { + this.createForm = this.fb.group({ + stocktakingJobId: [], + name: ['', [FormValidators.required('请输入')]], + notes: ['', []], + fullStocktaking: [1, []], + stocktakingStartDate: [null, []], + stocktakingEndDate: [null, []], + }) + } + initQueryForm() { + this.queryForm = this.fb.group({ + name: [''], + uscc: [''], + code: [''], + }) + } + + ngOnInit(): void { + this.table + .setConfig({ + selectable: true, + rowKey: 'stocktakingJobId', + }) + .setColumn([ + { key: 'name', title: '名称' }, + { key: 'fullStocktaking', title: '全员盘点' }, + { key: 'status', title: '盘点状态' }, + { key: 'head', title: '负责人' }, + { key: 'stocktakingUserId', title: '盘点人' }, + { key: 'stocktakingStartDate', title: '购置开始日期', width: '180px' }, + { key: 'stocktakingEndDate', title: '购置结束日期', width: '180px' }, + { key: 'createTime', title: '创建时间', width: '180px' }, + { key: 'createUser', title: '创建人' }, + { key: 'notes', title: '备注' }, + ]) + .setRowOperate([ + { title: '编辑', onClick: this.onCreate.bind(this) }, + { title: '编辑', onClick: this.onCreate.bind(this) }, + { title: '删除', onClick: this.deleteItem.bind(this) }, + ]) + this.initQueryForm() + this.initCreateForm() + } + + fetchData(p: {}, q: AnyObject) { + return this.api.getStocktakingJobPage({ ...p, ...q }) + } + + onCreate(data?: NzSafeAny) { + if (data) { + this.createForm.patchValue(data) + } + this.drawerRef = this.drawer.create({ + nzTitle: data ? '编辑盘点任务' : '新增盘点任务', + nzContent: this.formContentTpl, + nzFooter: this.drawerFooterTpl, + nzWidth: 600, + nzOnCancel: this.onCancel.bind(this), + }) + } + + onConfirm() { + if (FormValidators.validateFormGroup(this.createForm)) { + const { value } = this.createForm + + this.api + .saveStocktakingJob({ + ...value, + + // stocktakingJobId: value.stocktakingJobId ?? 0, + }) + .subscribe((res) => { + this.msg.success(res.desc) + this.onCancel() + this.table.ref.reload() + }) + } + } + + async onCancel() { + this.drawerRef?.close() + this.createForm.reset({}) + } + + deleteItem(item: NzSafeAny) { + this.modal.confirm({ + nzTitle: '警告', + nzContent: '是否要删除该盘点任务?', + nzOnOk: async () => { + const res = await lastValueFrom(this.api.deleteStocktakingJob([item.stocktakingJobId])) + this.msg.success(res.desc) + this.table.ref.reload() + }, + }) + } + onBegin() { + const ids = Array.from(this.table.ref.selected).map((i) => Number(i)) + this.modal.confirm({ + nzTitle: '警告', + nzContent: '是否要开始该盘点任务?', + nzOnOk: async () => { + const res = await lastValueFrom(this.api.beginStocktakingJob(ids)) + this.msg.success(res.desc) + this.table.ref.reload() + }, + }) + } + onStop() { + const ids = Array.from(this.table.ref.selected).map((i) => Number(i)) + this.modal.confirm({ + nzTitle: '警告', + nzContent: '是否要结束该盘点任务?', + nzOnOk: async () => { + const res = await lastValueFrom(this.api.stopStocktakingJob(ids)) + this.msg.success(res.desc) + this.table.ref.reload() + }, + }) + } +} diff --git a/web-admin-app/src/app/pages/fixed-asset/stocktaking/stockaking-plan/stockaking-plan.component.html b/web-admin-app/src/app/pages/fixed-asset/stocktaking/stockaking-plan/stockaking-plan.component.html new file mode 100644 index 0000000..31ce39d --- /dev/null +++ b/web-admin-app/src/app/pages/fixed-asset/stocktaking/stockaking-plan/stockaking-plan.component.html @@ -0,0 +1 @@ +

stockaking-plan works!

diff --git a/web-admin-app/src/app/pages/fixed-asset/stocktaking/stockaking-plan/stockaking-plan.component.less b/web-admin-app/src/app/pages/fixed-asset/stocktaking/stockaking-plan/stockaking-plan.component.less new file mode 100644 index 0000000..e69de29 diff --git a/web-admin-app/src/app/pages/fixed-asset/stocktaking/stockaking-plan/stockaking-plan.component.ts b/web-admin-app/src/app/pages/fixed-asset/stocktaking/stockaking-plan/stockaking-plan.component.ts new file mode 100644 index 0000000..2a32057 --- /dev/null +++ b/web-admin-app/src/app/pages/fixed-asset/stocktaking/stockaking-plan/stockaking-plan.component.ts @@ -0,0 +1,21 @@ +import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core' +import { SharedModule } from 'app/shared/shared.module' +import { ApiService } from 'app/services' +import { FormBuilder, FormGroup } from '@angular/forms' +import { AnyObject, TableOption } from 'app/shared/components/server-paginated-table' +import { NzSafeAny } from 'ng-zorro-antd/core/types' +import { NzModalService } from 'ng-zorro-antd/modal' +import { NzMessageService } from 'ng-zorro-antd/message' +import { NzDrawerRef, NzDrawerService } from 'ng-zorro-antd/drawer' +import { lastValueFrom } from 'rxjs' +import { FormValidators } from 'app/utils' +import { SelectUserByOrgComponent } from 'app/components' + +@Component({ + selector: 'app-stockaking-plan', + standalone: true, + imports: [], + templateUrl: './stockaking-plan.component.html', + styleUrl: './stockaking-plan.component.less', +}) +export class StockakingPlanComponent {} diff --git a/web-admin-app/src/app/pages/login/login.component.less b/web-admin-app/src/app/pages/login/login.component.less index 454d57d..d306dd6 100644 --- a/web-admin-app/src/app/pages/login/login.component.less +++ b/web-admin-app/src/app/pages/login/login.component.less @@ -4,8 +4,11 @@ .bg { background-image: url(/assets/images/login-bg.jpg); background-repeat: no-repeat; - background-size: cover; - filter: blur(1px); + background-position: bottom; + display: flex; + align-items: flex-end; + justify-content: center; + background-color: #3d62f1; } diff --git a/web-admin-app/src/app/pages/login/login.component.ts b/web-admin-app/src/app/pages/login/login.component.ts index d3d5f3d..d5f4f41 100644 --- a/web-admin-app/src/app/pages/login/login.component.ts +++ b/web-admin-app/src/app/pages/login/login.component.ts @@ -18,7 +18,6 @@ export class LoginComponent { constructor( private api: ApiService, private msg: NzMessageService, - private local: LocalHttpInterceptorService, private router: Router, ) {} @@ -39,13 +38,9 @@ export class LoginComponent { this.loading = false }), ) - .subscribe((res) => { + .subscribe(() => { this.msg.success('登录成功') - this.local.setAccess({ - access_token: res.body.authorization, - ...res.body, - }) - localStorage.setItem('add', res.data) + this.router.navigate(['/']) }) } diff --git a/web-admin-app/src/app/pages/org-setting/org-setting.component.html b/web-admin-app/src/app/pages/org-setting/org-setting.component.html index b394883..9436ede 100644 --- a/web-admin-app/src/app/pages/org-setting/org-setting.component.html +++ b/web-admin-app/src/app/pages/org-setting/org-setting.component.html @@ -1,40 +1,84 @@ - +
- +
- + + + @switch (key) { + @case ('avatar') { + @if (data) { + + } @else { + + } + } + @case ('status') { + + } + @case ('sex') { + + @switch (data) { + @case ('0') { + 男 + } + @case ('1') { + 女 + } + @default { + 未知 + } + } + + } + @default { + {{ data }} + } + } + - - + + - + - + - + - - - + + @@ -43,17 +87,103 @@ nzBorderless class="!w-auto" [nzDropdownMatchSelectWidth]="false" + formControlName="sex" + nzAllowClear > - - + + + - -
+ + + + + + + + + +
+ + 姓名 + + + + + + 账号名 + + + + + + 联系电话 + + + + + + 邮箱 + + + + + + + 密码 + + + + + + + 确认密码 + + + + + + 状态 + + + + + + + + + 头像 + + +
+ +
+ +
+
+ + 性别 + + + + + + + + +
+
+ + + + diff --git a/web-admin-app/src/app/pages/org-setting/org-setting.component.ts b/web-admin-app/src/app/pages/org-setting/org-setting.component.ts index c988e75..5fbbd66 100644 --- a/web-admin-app/src/app/pages/org-setting/org-setting.component.ts +++ b/web-admin-app/src/app/pages/org-setting/org-setting.component.ts @@ -1,92 +1,182 @@ -import { Component, OnInit } from '@angular/core' -import { AppPageComponent } from 'app/components/app-page/app-page.component' +import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core' import { SharedModule } from 'app/shared/shared.module' -import { ComponentOrgTreeComponent } from '../component-org-tree/component-org-tree.component' -import { AnyObject, TableOption } from 'app/components/server-paginated-table' +import { ComponentOrgTreeComponent } from 'app/components/component-org-tree/component-org-tree.component' + import { format } from 'date-fns' import { ApiService } from 'app/services' -import { of } from 'rxjs' +import { FormBuilder, FormGroup } from '@angular/forms' +import { AnyObject, TableOption } from 'app/shared/components/server-paginated-table' +import { NzSafeAny } from 'ng-zorro-antd/core/types' +import { NzModalService } from 'ng-zorro-antd/modal' +import { NzMessageService } from 'ng-zorro-antd/message' +import { NzDrawerRef, NzDrawerService } from 'ng-zorro-antd/drawer' +import { lastValueFrom } from 'rxjs' +import { FormValidators } from 'app/utils' @Component({ selector: 'app-org-setting', standalone: true, - imports: [SharedModule, AppPageComponent, ComponentOrgTreeComponent], + imports: [SharedModule, ComponentOrgTreeComponent], templateUrl: './org-setting.component.html', styleUrl: './org-setting.component.less', }) export class OrgSettingComponent implements OnInit { - constructor(private api: ApiService) {} + constructor( + private modal: NzModalService, + private msg: NzMessageService, + private drawer: NzDrawerService, + private api: ApiService, + private fb: FormBuilder, + ) {} table = new TableOption(this.fetchData.bind(this)) + queryForm!: FormGroup + + createForm!: FormGroup + + drawerRef?: NzDrawerRef + + organization: null | NzSafeAny = null + + iconPreview = '' + + uploadLoading = false + + @ViewChild('drawerFooterTpl') drawerFooterTpl!: TemplateRef + + @ViewChild('formContentTpl') formContentTpl!: TemplateRef + + initCreateForm() { + this.createForm = this.fb.group({ + userId: [], + userName: ['', FormValidators.required('请输入')], + loginName: ['', FormValidators.required('请输入')], + phone: [ + '', + [FormValidators.required('请输入'), FormValidators.pattern(/^1[3-9]\d{9}$/, '请输入正确的手机号')], + ], + password: [], + repassword: [], + email: [], + status: ['0'], + sex: ['0'], + avatar: [], + roleId: [], + }) + } + initQueryForm() { + this.queryForm = this.fb.group({ + userName: [''], + loginName: [''], + phone: [''], + email: [''], + status: [''], + sex: [''], + }) + } + ngOnInit(): void { this.table - .setConfig({ - selectable: true, - }) + .setColumn([ - { key: '公司ID', title: '公司ID', visible: true }, - { key: '工号', title: '工号' }, - { key: '姓名', title: '姓名' }, - { key: '性别', title: '性别' }, - { key: '手机号', title: '手机号' }, - { key: '部门', title: '部门' }, - { key: '主岗', title: '主岗' }, - { key: 'ID', title: 'ID', visible: false }, - { key: '人员ID', title: '人员ID', visible: false }, - { key: '状态', title: '状态', visible: false }, - { key: '修改人ID', title: '修改人ID', visible: false }, - { key: '类型', title: '类型', visible: false }, - { key: '直属领导', title: '直属领导', visible: false }, - { key: 'extInfo', title: 'extInfo', visible: false }, - { key: '身份证', title: '身份证', visible: false }, - { key: '兼岗', title: '兼岗', visible: false }, - { key: '签约方', title: '签约方', visible: false }, - { key: '成本中心', title: '成本中心', visible: false }, - { key: '客户信息', title: '客户信息', visible: false }, - - { key: 'createTime', title: '创建时间' }, + { key: 'avatar', title: '头像', width: '100px' }, + { key: 'userName', title: '姓名' }, + { key: 'loginName', title: '账号名' }, + { key: 'phone', title: '联系电话' }, + { key: 'email', title: '邮箱' }, + { key: 'status', title: '状态' }, + { key: 'sex', title: '性别' }, ]) - .setRowOperate([{ title: '查看', premissions: [] }, { title: '编辑' }, { title: '删除' }]) + .setRowOperate([ + { title: '编辑', onClick: this.onCreate.bind(this) }, + { title: '删除', onClick: this.deleteItem.bind(this) }, + ]) + this.initQueryForm() + this.initCreateForm() } fetchData(p: {}, q: AnyObject) { - if (Array.isArray(q['createTime'])) { - const createTimeStart = q['createTime']?.[0] - const createTimeEnd = q['createTime']?.[1] + return this.api.getUserPage({ ...p, ...q, organizationId: this.organization?.organizationId }) + } - q['createTimeStart'] = createTimeStart ? format(new Date(createTimeStart), 'yyyy-MM-dd HH:mm:ss') : '' - q['createTimeEnd'] = createTimeEnd ? format(new Date(createTimeEnd), 'yyyy-MM-dd HH:mm:ss') : '' + onOrgSelectedChange(org: NzSafeAny) { + console.log('org', org) + this.organization = org + this.table.ref.search() + } + + onCreate(data?: NzSafeAny) { + if (data) { + this.createForm.patchValue(data) + } + this.drawerRef = this.drawer.create({ + nzTitle: data ? '编辑员工' : '新增员工', + nzContent: this.formContentTpl, + nzFooter: this.drawerFooterTpl, + nzWidth: 600, + nzOnCancel: this.onCancel.bind(this), + }) + } + + onConfirm() { + if (FormValidators.validateFormGroup(this.createForm)) { + const { value } = this.createForm + if (value.password && value.repassword !== value.password) { + this.msg.error('两次密码输入不一致') + return + } + this.api + .saveUser({ + ...value, + organizationId: this.organization?.organizationId, + }) + .subscribe((res) => { + this.msg.success(res.desc) + this.onCancel() + this.table.ref.reload() + }) } - return of({ - data: { - total: 5, - records: [ - { - id: 1, - name: '沙滩', - price: 590, - type: 0, - lifespan: 6, - number: 20, - max: 20, - status: 1, - createTime: '2024-05-01', - }, - - { - id: 2, - name: '清凉一夏~沙滩排球', - price: 100000, - type: 1, - lifespan: 12, - max: 20, - status: 1, - createTime: '2024-05-01', - }, - ], + } + + async onCancel() { + this.drawerRef?.close() + this.createForm.reset({ + sex: '0', + status: '0', + }) + } + + deleteItem(item: NzSafeAny) { + this.modal.confirm({ + nzTitle: '警告', + nzContent: '是否要删除该员工?', + nzOnOk: async () => { + const res = await lastValueFrom(this.api.deleteUser([item.userId])) + this.msg.success(res.desc) + this.table.ref.reload() }, }) - return this.api.getEntityPage(p, q) + } + + onFileChange(e: Event) { + const target = e.target as HTMLInputElement + const file = target.files![0] + target.value = '' + if (file.size / 1024 / 1024 >= 2) { + this.msg.error('图片大小不能超过2M') + return + } + const fileReader = new FileReader() + fileReader.onload = () => { + const base64 = fileReader.result as string + this.iconPreview = base64 + } + fileReader.readAsDataURL(file) + const formdata = new FormData() + formdata.append('file', file) + this.api.upload(formdata).subscribe((res) => { + this.createForm.get('avatar')?.setValue(res.body.fileName) + }) } } diff --git a/web-admin-app/src/app/pages/profile-account/profile-account.component.ts b/web-admin-app/src/app/pages/profile-account/profile-account.component.ts index 599bf3b..ae2fa92 100644 --- a/web-admin-app/src/app/pages/profile-account/profile-account.component.ts +++ b/web-admin-app/src/app/pages/profile-account/profile-account.component.ts @@ -20,27 +20,27 @@ export class ProfileAccountComponent { ) {} formGroup = new FormGroup({ - id: new FormControl(this.api.authInfo.id), - username: new FormControl({ value: this.api.authInfo.username, disabled: true }, [ - FormValidators.required('请输入用户名'), - ]), - password: new FormControl('', [FormValidators.required('请输入密码')]), - confirmPassword: new FormControl('', [FormValidators.required('请再次输入密码')]), + // id: new FormControl(this.api.authInfo.id), + // username: new FormControl({ value: this.api.authInfo.username, disabled: true }, [ + // FormValidators.required('请输入用户名'), + // ]), + // password: new FormControl('', [FormValidators.required('请输入密码')]), + // confirmPassword: new FormControl('', [FormValidators.required('请再次输入密码')]), }) onSubmit() { if (FormValidators.validateFormGroup(this.formGroup)) { - if (this.formGroup.value.confirmPassword !== this.formGroup.value.password) { - this.msg.error('两次输入密码不一致') - return - } - const v = this.formGroup.getRawValue() - this.api.changePassword(v).subscribe(() => { - this.msg.success('修改成功,请重新登录').onClose.subscribe(() => { - this.local.removeAccess() - window.location.href = '/login' - }) - }) + // if (this.formGroup.value.confirmPassword !== this.formGroup.value.password) { + // this.msg.error('两次输入密码不一致') + // return + // } + // const v = this.formGroup.getRawValue() + // this.api.changePassword(v).subscribe(() => { + // this.msg.success('修改成功,请重新登录').onClose.subscribe(() => { + // this.local.removeAccess() + // window.location.href = '/login' + // }) + // }) } } } diff --git a/web-admin-app/src/app/pages/profile-basic/profile-basic.component.ts b/web-admin-app/src/app/pages/profile-basic/profile-basic.component.ts index 216fd1a..8332377 100644 --- a/web-admin-app/src/app/pages/profile-basic/profile-basic.component.ts +++ b/web-admin-app/src/app/pages/profile-basic/profile-basic.component.ts @@ -1,7 +1,6 @@ import { Component, OnDestroy, OnInit } from '@angular/core' import { SharedModule } from '../../shared/shared.module' import { ApiService } from 'app/services' -import { UserFormComponent } from 'app/components/user-form/user-form.component' import { FormBuilder, FormControl, FormGroup } from '@angular/forms' import { FormValidators } from 'app/utils' import { NzMessageService } from 'ng-zorro-antd/message' @@ -9,7 +8,7 @@ import { Subscription } from 'rxjs' @Component({ standalone: true, - imports: [SharedModule, UserFormComponent], + imports: [SharedModule], selector: 'app-profile-basic', templateUrl: './profile-basic.component.html', styleUrls: ['./profile-basic.component.less'], @@ -24,10 +23,10 @@ export class ProfileBasicComponent implements OnInit, OnDestroy { formGroup!: FormGroup ngOnInit(): void { - this.formGroup = this.fb.group({ - name: new FormControl(this.api.authInfo.name, [FormValidators.required('请输入姓名')]), - remark: new FormControl(this.api.authInfo.remark), - }) + // this.formGroup = this.fb.group({ + // name: new FormControl(this.api.authInfo.name, [FormValidators.required('请输入姓名')]), + // remark: new FormControl(this.api.authInfo.remark), + // }) } ngOnDestroy(): void {} @@ -45,7 +44,7 @@ export class ProfileBasicComponent implements OnInit, OnDestroy { if (vals) { this.api.saveUser({ ...this.api.authInfo, ...vals }).subscribe(() => { this.msg.success('保存成功') - this.api.getAuthInfo(true).subscribe(() => {}) + // this.api.getAuthInfo(true).subscribe(() => {}) }) } } diff --git a/web-admin-app/src/app/pages/profile/profile.component.html b/web-admin-app/src/app/pages/profile/profile.component.html index 67fc742..14d4ca4 100644 --- a/web-admin-app/src/app/pages/profile/profile.component.html +++ b/web-admin-app/src/app/pages/profile/profile.component.html @@ -2,18 +2,10 @@ - {{ api.authInfo.username }} + {{ api.authInfo?.loginName }} - {{ api.authInfo.name }} - - - - @if (api.authInfo.enable) { - - } @else { - - } + {{ api.authInfo?.userName }} diff --git a/web-admin-app/src/app/pages/profile/profile.component.ts b/web-admin-app/src/app/pages/profile/profile.component.ts index cd46449..5a8c0c6 100644 --- a/web-admin-app/src/app/pages/profile/profile.component.ts +++ b/web-admin-app/src/app/pages/profile/profile.component.ts @@ -14,9 +14,7 @@ import { Subscription } from 'rxjs' export class ProfileComponent implements OnInit, OnDestroy { constructor(public api: ApiService) {} - ngOnInit(): void { - this.api.getUserInfo(this.api.authInfo.id).subscribe((res) => {}) - } + ngOnInit(): void {} ngOnDestroy(): void {} } diff --git a/web-admin-app/src/app/pages/system/system.component.html b/web-admin-app/src/app/pages/system/index/system.component.html similarity index 56% rename from web-admin-app/src/app/pages/system/system.component.html rename to web-admin-app/src/app/pages/system/index/system.component.html index 67e7bd4..7634b59 100644 --- a/web-admin-app/src/app/pages/system/system.component.html +++ b/web-admin-app/src/app/pages/system/index/system.component.html @@ -1 +1,2 @@ +
ad
diff --git a/web-admin-app/src/app/pages/system/index/system.component.less b/web-admin-app/src/app/pages/system/index/system.component.less new file mode 100644 index 0000000..e69de29 diff --git a/web-admin-app/src/app/pages/system/system.component.ts b/web-admin-app/src/app/pages/system/index/system.component.ts similarity index 100% rename from web-admin-app/src/app/pages/system/system.component.ts rename to web-admin-app/src/app/pages/system/index/system.component.ts diff --git a/web-admin-app/src/app/pages/system/system-user/system-user.component.html b/web-admin-app/src/app/pages/system/system-user/system-user.component.html new file mode 100644 index 0000000..0434380 --- /dev/null +++ b/web-admin-app/src/app/pages/system/system-user/system-user.component.html @@ -0,0 +1 @@ +

system-user works!

diff --git a/web-admin-app/src/app/pages/system/system-user/system-user.component.less b/web-admin-app/src/app/pages/system/system-user/system-user.component.less new file mode 100644 index 0000000..e69de29 diff --git a/web-admin-app/src/app/pages/system/system-user/system-user.component.ts b/web-admin-app/src/app/pages/system/system-user/system-user.component.ts new file mode 100644 index 0000000..3588e8f --- /dev/null +++ b/web-admin-app/src/app/pages/system/system-user/system-user.component.ts @@ -0,0 +1,11 @@ +import { Component } from '@angular/core' +import { SharedModule } from 'app/shared/shared.module' + +@Component({ + selector: 'app-system-user', + standalone: true, + imports: [SharedModule], + templateUrl: './system-user.component.html', + styleUrl: './system-user.component.less', +}) +export class SystemUserComponent {} diff --git a/web-admin-app/src/app/services/api.dto.ts b/web-admin-app/src/app/services/api.dto.ts index 6339870..5615f20 100644 --- a/web-admin-app/src/app/services/api.dto.ts +++ b/web-admin-app/src/app/services/api.dto.ts @@ -1,15 +1,9 @@ export type AuthDTO = { - createTime: string - enable: boolean - groupId: string - id: string - name: string - remark: string - roleId: string - roleName: string - updateTime: string - username: string - authorities: AuthorityDTO[] + authorization: string + loginName: string + permissions: string[] + roles: string[] + userName: string } export type AuthorityDTO = { authority: string } diff --git a/web-admin-app/src/app/services/api.service.ts b/web-admin-app/src/app/services/api.service.ts index 928d504..dee21c5 100644 --- a/web-admin-app/src/app/services/api.service.ts +++ b/web-admin-app/src/app/services/api.service.ts @@ -6,7 +6,6 @@ import { NzTreeNodeOptions } from 'ng-zorro-antd/tree' import { BehaviorSubject, map, of, tap } from 'rxjs' import { AuthDTO, - AuthorityDTO, AuthorizeItemDTO, ConsoleClientTopDTO, ConsoleCountDTO, @@ -20,6 +19,7 @@ import { UserDTO, } from './api.dto' import { PermissionService } from 'app/shared/permission/permission.service' +import { NzSafeAny } from 'ng-zorro-antd/core/types' export interface UserGroupTreeItem { name: string @@ -37,224 +37,178 @@ export class ApiService { private permission: PermissionService, ) {} - authInfo: AuthDTO = { - createTime: '', - enable: false, - groupId: '', - id: '', - name: '', - remark: '', - roleId: '', - roleName: '', - updateTime: '', - username: '', - authorities: [], - } + AUTH_KEY_NAME = 'auth' - getAuthInfo(force?: boolean) { - if (this.authInfo && !force) { - return of(this.authInfo) - } - localStorage.setItem('da', 'af') - return of(this.authInfo) - // return this.http.get>('/api/auth/info').pipe( - // map((res) => res.data), - // tap((res) => { - // this.authInfo = res - // this.permission.loadPermission(res.authorities.map((f) => f.authority)) - // }), - // ) + get authInfo(): AuthDTO | null { + let authInfo: AuthDTO | null = null + try { + const strData = localStorage.getItem(this.AUTH_KEY_NAME) + if (strData) { + authInfo = JSON.parse(strData) + this.permission.loadPermission(authInfo?.permissions ?? []) + } + } catch (error) {} + return authInfo } - login(data: {}) { - return this.http.post('/api/oauth/login', data) + removeAuthData() { + localStorage.removeItem(this.AUTH_KEY_NAME) } - private _parseUserGroupTree(group: UserGroupTreeItem[]): NzTreeNodeOptions[] { - if (group?.length === 0) { - return [] - } - return group.map((i) => { - return { - ...i, - key: i.id, - title: i.name, - children: this._parseUserGroupTree(i.children ?? []), - isLeaf: i.children?.length === 0 || !i.children, - } - }) + upload(data: FormData) { + return this.http.post('/api/common/upload', data) } - changeUserPassword(id: string, password: string) { - return this.http.put('/api/user/reset/password', { - id, - password, - }) + login(data: {}) { + return this.http.post('/api/oauth/login', data).pipe( + tap((res) => { + localStorage.setItem(this.AUTH_KEY_NAME, JSON.stringify(res.body)) + }), + ) } - getDashboardCounter() { - return this.http.get>(`/api/console/count`) + logout() { + return this.http.post('/api/oauth/logout', null) } - getDashboardExpire() { - return this.http.get>(`/api/console/expire`) + getOrgTree() { + return this.http.post('/api/umsOrganization/tree', null) } - getDashboardClientTop() { - return this.http.get>(`/api/console/client/top`) + saveOrg(data: NzSafeAny) { + if (Utils.isEmpty(data.organizationId)) { + return this.http.post('/api/umsOrganization/add', data) + } + return this.http.post('/api/umsOrganization/update', data) } - getUserInfo(id: string) { - return this.http.get>(`/api/user/${id}`).pipe() + deleteOrg(id: number) { + return this.http.post('/api/umsOrganization/delete', [id]) } - changePassword(data: {}) { - return this.http.put('/api/user/password', data) + getUserPage(data: {}) { + return this.http.post('/api/umsUser/list', data) } - getUserPage(p: {}, q: {}) { - const params = Utils.objectToURLSearchParams({ ...p, ...q }) - return this.http.get(`/api/user/pages?${params}`) + deleteUser(ids: number[]) { + return this.http.post(`/api/umsUser/delete`, ids) } - saveUser(user: any) { - if (user.id) { - return this.http.put('/api/user', user) - } else { - return this.http.post('/api/user', user) + saveUser(data: NzSafeAny) { + if (Utils.isEmpty(data.userId)) { + return this.http.post('/api/umsUser/add', data) } + return this.http.post('/api/umsUser/update', data) } - deleteUser(id: string) { - return this.http.delete(`/api/user/${id}`) - } - - getUserGroupTree() { - return this.http.get>('/api/user/group/tree').pipe( - map((res) => { - return this._parseUserGroupTree(res.data) - }), - ) + getBasicPositionPage(data: {}) { + return this.http.post('/api/eamBasicPosition/list', data) } - - saveUserGroup(group: Partial) { - if (group.id) { - return this.http.put('/api/user/group', group) - } else { - return this.http.post('/api/user/group', group) + saveBasicPosition(data: NzSafeAny) { + if (Utils.isEmpty(data.positionId)) { + return this.http.post('/api/eamBasicPosition/add', data) } + return this.http.post('/api/eamBasicPosition/update', data) } - - updateUserStatus(id: string) { - return this.http.put(`/api/user/enable/${id}`, null) + deleteBasicPosition(ids: number[]) { + return this.http.post(`/api/eamBasicPosition/delete`, ids) } - deleteUserGroup(id: string) { - return this.http.delete(`/api/user/group/${id}`) + getBasicMaintenanceVendorPage(data: {}) { + return this.http.post('/api/eamBasicMaintenanceVendor/list', data) } - - getAllRole() { - return this.http.get>(`/api/sysRole/list`) + saveBasicMaintenanceVendor(data: NzSafeAny) { + if (Utils.isEmpty(data.maintenanceVendorId)) { + return this.http.post('/api/eamBasicMaintenanceVendor/add', data) + } + return this.http.post('/api/eamBasicMaintenanceVendor/update', data) } - - getRolePage(p: {}, q: {}) { - const params = Utils.objectToURLSearchParams({ ...p, ...q }) - return this.http.get(`/api/sysRole/pages?${params}`) + deleteBasicMaintenanceVendor(ids: number[]) { + return this.http.post(`/api/eamBasicMaintenanceVendor/delete`, ids) } - getAllPermission() { - return this.http.get>('/api/authority/tree') + getBasicManufacturersVendorPage(data: {}) { + return this.http.post('/api/eamBasicManufacturersVendor/list', data) } - - getRoleById(id: string) { - return this.http.get>(`/api/sysRole/${id}`) + saveBasicManufacturersVendor(data: NzSafeAny) { + if (Utils.isEmpty(data.manufacturersVendorId)) { + return this.http.post('/api/eamBasicManufacturersVendor/add', data) + } + return this.http.post('/api/eamBasicManufacturersVendor/update', data) } - - deleteRole(id: string) { - return this.http.delete(`/api/sysRole/${id}`) + deleteBasicManufacturersVendor(ids: number[]) { + return this.http.post(`/api/eamBasicManufacturersVendor/delete`, ids) } - saveRole(role: NullableProps) { - if (role.id) { - return this.http.put('/api/sysRole', role) - } else { - return this.http.post('/api/sysRole', role) + getBasicSupplierVendorPage(data: {}) { + return this.http.post('/api/eamBasicSupplierVendor/list', data) + } + saveBasicSupplierVendor(data: NzSafeAny) { + if (Utils.isEmpty(data.supplierVendorId)) { + return this.http.post('/api/eamBasicSupplierVendor/add', data) } + return this.http.post('/api/eamBasicSupplierVendor/update', data) } - - authorize(v: {}) { - return this.http.post('/api/client/license', v) + deleteBasicSupplierVendor(ids: number[]) { + return this.http.post(`/api/eamBasicSupplierVendor/delete`, ids) } - getSysLog(p: {}, q: {}) { - const params = Utils.objectToURLSearchParams({ ...p, ...q }) - return this.http.get(`/api/sysLog/pages?${params}`) + getBasicWarehousePage(data: {}) { + return this.http.post('/api/eamBasicWarehouse/list', data) } - - getEntityPage(p: {}, q: {}) { - const params = Utils.objectToURLSearchParams({ ...p, ...q }) - return this.http.get(`/api/client/pages?${params}`) + saveBasicWarehouse(data: NzSafeAny) { + if (Utils.isEmpty(data.warehouseId)) { + return this.http.post('/api/eamBasicWarehouse/add', data) + } + return this.http.post('/api/eamBasicWarehouse/update', data) } - - getEntityAuthorizeList(clientId: string) { - return this.http.get>(`/api/licenseLog/${clientId}/list`) + deleteBasicWarehouse(ids: number[]) { + return this.http.post(`/api/eamBasicWarehouse/delete`, ids) } - getEntityDetail(id: string) { - return this.http.get>(`/api/client/${id}`) + getBasicCategoryTree() { + return this.http.post('/api/eamBasicCategory/tree', null) } - - saveEntity(entity: Partial>) { - if (entity.id) { - return this.http.put('/api/client', entity) - } else { - return this.http.post('/api/client', entity) - } + addBasicCategoryTree(data: {}) { + return this.http.post('/api/eamBasicCategory/add', data) } - - deleteEntity(id: string) { - return this.http.delete(`/api/client/${id}`) + updateBasicCategoryTree(data: {}) { + return this.http.post('/api/eamBasicCategory/update', data) } - - getProductPage(p: {}, q: {}) { - const params = Utils.objectToURLSearchParams({ ...p, ...q }) - return this.http.get(`/api/product/pages?${params}`) + deleteBasicCategory(ids: number[]) { + return this.http.post('/api/eamBasicCategory/delete', ids) } - getAllProduct() { - return this.http.get>(`/api/product/list`) + getStocktakingJobPage(data: {}) { + return this.http.post('/api/eamStocktakingJob/list', data) } - - saveProduct(entity: Partial>) { - if (entity.id) { - return this.http.put('/api/product', entity) - } else { - return this.http.post('/api/product', entity) + saveStocktakingJob(data: NzSafeAny) { + if (Utils.isEmpty(data.stocktakingJobId)) { + return this.http.post('/api/eamStocktakingJob/add', data) } + return this.http.post('/api/eamStocktakingJob/update', data) } - - deleteProduct(id: string) { - return this.http.delete(`/api/product/${id}`) + deleteStocktakingJob(ids: number[]) { + return this.http.post(`/api/eamStocktakingJob/delete`, ids) } - getProductVersionPage(p: {}, q: {}) { - const params = Utils.objectToURLSearchParams({ ...p, ...q }) - return this.http.get(`/api/product/pages?${params}`) + beginStocktakingJob(ids: number[]) { + return this.http.post(`/api/eamStocktakingJob/start`, ids) } - - saveVersion(entity: Partial>) { - if (entity.id) { - return this.http.put('/api/product', entity) - } else { - return this.http.post('/api/product', entity) - } + stopStocktakingJob(ids: number[]) { + return this.http.post(`/api/eamStocktakingJob/complete`, ids) } - deleteVersion(id: string, pid: string) { - return this.http.delete(`/api/product/${id}`) - } + /** + * + * + * ------------------------------- + * + * + */ - getProductDetail(pid: string) { - return this.http.get(`/api/product/${pid}`) + getEntityPage(p: {}, q: {}) { + const params = Utils.objectToURLSearchParams({ ...p, ...q }) + return this.http.get(`/api/client/pages?${params}`) } } diff --git a/web-admin-app/src/app/services/local-http-interceptor.service.ts b/web-admin-app/src/app/services/local-http-interceptor.service.ts index 2a3fc76..9441b00 100644 --- a/web-admin-app/src/app/services/local-http-interceptor.service.ts +++ b/web-admin-app/src/app/services/local-http-interceptor.service.ts @@ -11,6 +11,7 @@ import { Observable, throwError } from 'rxjs' import { catchError, filter, tap } from 'rxjs/operators' import { ActivatedRoute, NavigationEnd, Router } from '@angular/router' import { NzMessageService } from 'ng-zorro-antd/message' +import { ApiService } from './api.service' function uintToString(uintArray: Uint8Array) { const encodedString = String.fromCharCode.apply(null, uintArray as any) @@ -59,30 +60,11 @@ export function getErrorMessage(err: HttpErrorResponse & Record, de export class LocalHttpInterceptorService implements HttpInterceptor { constructor( private msg: NzMessageService, + private api: ApiService, private router: Router, private route: ActivatedRoute, ) {} - tokenName = 'AUTH_TOKEN' - - getAccess() { - try { - let persistData = localStorage.getItem(this.tokenName) - if (persistData) { - return JSON.parse(persistData) - } - } catch (error) {} - return {} - } - - setAccess(accessData: { access_token: string } & Record) { - localStorage.setItem(this.tokenName, JSON.stringify(accessData)) - } - - removeAccess() { - localStorage.removeItem(this.tokenName) - } - intercept(req: HttpRequest, next: HttpHandler): Observable> { let url = req.url let baseHref = '' @@ -92,21 +74,18 @@ export class LocalHttpInterceptorService implements HttpInterceptor { if (baseHref.endsWith('/')) { baseHref = baseHref.slice(0, baseHref.length - 1) } - if (['/api/auth/info'].includes(req.url)) { - baseHref = '/authserver' - } + url = baseHref + req.url } - const accessData = this.getAccess() - let token = accessData?.access_token - let refreshToken = accessData?.refresh_token + const accessData = this.api.authInfo + let token = accessData?.authorization if (this.shouldRemoveAuthorizationToken(req.url)) { token = '' } - const Authorization: Record = token ? { Authorization: `Bearer ${token}` } : {} + const Authorization: Record = token ? { Authorization: token } : {} const newRequest = req.clone({ ...req, @@ -122,14 +101,6 @@ export class LocalHttpInterceptorService implements HttpInterceptor { return next.handle(authReq).pipe( tap((res) => { if (res instanceof HttpResponse) { - const access_token = res.headers.get('Rep-Access-Token') - const refresh_token = res.headers.get('Rep-Refresh-Token') - if (access_token) { - this.setAccess({ - access_token, - refresh_token, - }) - } if (res.body?.success === false && res.body.desc) { throw new HttpErrorResponse({ error: res.body }) } @@ -149,7 +120,7 @@ export class LocalHttpInterceptorService implements HttpInterceptor { switch (res.status) { case 401: if (window.location.pathname !== '/login') { - this.removeAccess() + this.api.removeAuthData() this.msg.error('登录已失效') setTimeout(() => { window.location.href = '/login' @@ -176,23 +147,6 @@ export class LocalHttpInterceptorService implements HttpInterceptor { } private shouldRemoveAuthorizationToken(url: string) { - if (url.includes('/api/auth/info')) { - return false - } - - if (url.includes('/api/login')) { - return true - } - if (url.includes('/api/auth/')) { - return true - } - if (url.includes('/api/reset/')) { - return true - } - if (url.includes('/api/refresh_token')) { - return true - } - return false } } diff --git a/web-admin-app/src/app/components/app-page/app-page.component.html b/web-admin-app/src/app/shared/components/app-page/app-page.component.html similarity index 100% rename from web-admin-app/src/app/components/app-page/app-page.component.html rename to web-admin-app/src/app/shared/components/app-page/app-page.component.html diff --git a/web-admin-app/src/app/components/app-page/app-page.component.less b/web-admin-app/src/app/shared/components/app-page/app-page.component.less similarity index 100% rename from web-admin-app/src/app/components/app-page/app-page.component.less rename to web-admin-app/src/app/shared/components/app-page/app-page.component.less diff --git a/web-admin-app/src/app/components/app-page/app-page.component.ts b/web-admin-app/src/app/shared/components/app-page/app-page.component.ts similarity index 97% rename from web-admin-app/src/app/components/app-page/app-page.component.ts rename to web-admin-app/src/app/shared/components/app-page/app-page.component.ts index cfb0f41..73ea490 100644 --- a/web-admin-app/src/app/components/app-page/app-page.component.ts +++ b/web-admin-app/src/app/shared/components/app-page/app-page.component.ts @@ -6,8 +6,6 @@ import { Subscription, filter } from 'rxjs' @Component({ selector: 'app-page', - standalone: true, - imports: [SharedModule], templateUrl: './app-page.component.html', styleUrl: './app-page.component.less', }) diff --git a/web-admin-app/src/app/components/form-error-tips/form-error-tips.component.html b/web-admin-app/src/app/shared/components/form-error-tips/form-error-tips.component.html similarity index 100% rename from web-admin-app/src/app/components/form-error-tips/form-error-tips.component.html rename to web-admin-app/src/app/shared/components/form-error-tips/form-error-tips.component.html diff --git a/web-admin-app/src/app/shared/components/form-error-tips/form-error-tips.component.less b/web-admin-app/src/app/shared/components/form-error-tips/form-error-tips.component.less new file mode 100644 index 0000000..e69de29 diff --git a/web-admin-app/src/app/components/form-error-tips/form-error-tips.component.ts b/web-admin-app/src/app/shared/components/form-error-tips/form-error-tips.component.ts similarity index 100% rename from web-admin-app/src/app/components/form-error-tips/form-error-tips.component.ts rename to web-admin-app/src/app/shared/components/form-error-tips/form-error-tips.component.ts diff --git a/web-admin-app/src/app/components/header/header.component.html b/web-admin-app/src/app/shared/components/header/header.component.html similarity index 98% rename from web-admin-app/src/app/components/header/header.component.html rename to web-admin-app/src/app/shared/components/header/header.component.html index 16a4e17..0195dff 100644 --- a/web-admin-app/src/app/components/header/header.component.html +++ b/web-admin-app/src/app/shared/components/header/header.component.html @@ -66,7 +66,7 @@ - {{ api.authInfo.name || 'admin' }} + {{ api.authInfo?.userName ?? '-' }} diff --git a/web-admin-app/src/app/components/header/header.component.less b/web-admin-app/src/app/shared/components/header/header.component.less similarity index 100% rename from web-admin-app/src/app/components/header/header.component.less rename to web-admin-app/src/app/shared/components/header/header.component.less diff --git a/web-admin-app/src/app/components/header/header.component.ts b/web-admin-app/src/app/shared/components/header/header.component.ts similarity index 82% rename from web-admin-app/src/app/components/header/header.component.ts rename to web-admin-app/src/app/shared/components/header/header.component.ts index f49e969..00d9161 100644 --- a/web-admin-app/src/app/components/header/header.component.ts +++ b/web-admin-app/src/app/shared/components/header/header.component.ts @@ -1,5 +1,5 @@ +import { lastValueFrom } from 'rxjs' import { Component, OnInit, inject } from '@angular/core' -import { SharedModule } from '../../shared/shared.module' import { ApiService, LocalHttpInterceptorService } from 'app/services' import { Router } from '@angular/router' import { NzMessageService } from 'ng-zorro-antd/message' @@ -7,15 +7,12 @@ import { NzModalService } from 'ng-zorro-antd/modal' import { PermissionService } from 'app/shared/permission/permission.service' @Component({ - standalone: true, selector: 'app-header', templateUrl: './header.component.html', styleUrls: ['./header.component.less'], - imports: [SharedModule], }) export class HeaderComponent implements OnInit { constructor( - private local: LocalHttpInterceptorService, private router: Router, private msg: NzMessageService, private modal: NzModalService, @@ -30,9 +27,10 @@ export class HeaderComponent implements OnInit { this.modal.confirm({ nzTitle: '退出登录', nzContent: '确认要退出当前账户吗?', - nzOnOk: () => { + nzOnOk: async () => { + await lastValueFrom(this.api.logout()) this.permission.reset() - this.local.removeAccess() + this.api.removeAuthData() this.router.navigate(['/login']) this.msg.success('退出成功') }, diff --git a/web-admin-app/src/app/shared/components/index.ts b/web-admin-app/src/app/shared/components/index.ts new file mode 100644 index 0000000..5abf137 --- /dev/null +++ b/web-admin-app/src/app/shared/components/index.ts @@ -0,0 +1,6 @@ +// export * from "./form-error-tips/form-error-tips.component"; +// export * from "./server-paginated-table"; + +export * from './header/header.component' +export * from './layout/layout.component' +export * from './user-form/user-form.component' diff --git a/web-admin-app/src/app/components/layout/layout.component.html b/web-admin-app/src/app/shared/components/layout/layout.component.html similarity index 100% rename from web-admin-app/src/app/components/layout/layout.component.html rename to web-admin-app/src/app/shared/components/layout/layout.component.html diff --git a/web-admin-app/src/app/shared/components/layout/layout.component.less b/web-admin-app/src/app/shared/components/layout/layout.component.less new file mode 100644 index 0000000..ba84b94 --- /dev/null +++ b/web-admin-app/src/app/shared/components/layout/layout.component.less @@ -0,0 +1,15 @@ +:host { + display: block; + height: 100%; +} + +// .app-width { +// ::ng-deep { +// router-outlet+* { +// display: block; +// width: 100%; +// height: 100%; +// overflow: hidden; +// } +// } +// } \ No newline at end of file diff --git a/web-admin-app/src/app/shared/components/layout/layout.component.ts b/web-admin-app/src/app/shared/components/layout/layout.component.ts new file mode 100644 index 0000000..54d675a --- /dev/null +++ b/web-admin-app/src/app/shared/components/layout/layout.component.ts @@ -0,0 +1,8 @@ +import { Component } from '@angular/core' + +@Component({ + selector: 'app-layout', + templateUrl: './layout.component.html', + styleUrls: ['./layout.component.less'], +}) +export class LayoutComponent {} diff --git a/web-admin-app/src/app/components/range-picker/range-picker.component.html b/web-admin-app/src/app/shared/components/range-picker/range-picker.component.html similarity index 100% rename from web-admin-app/src/app/components/range-picker/range-picker.component.html rename to web-admin-app/src/app/shared/components/range-picker/range-picker.component.html diff --git a/web-admin-app/src/app/shared/components/range-picker/range-picker.component.less b/web-admin-app/src/app/shared/components/range-picker/range-picker.component.less new file mode 100644 index 0000000..e69de29 diff --git a/web-admin-app/src/app/components/range-picker/range-picker.component.ts b/web-admin-app/src/app/shared/components/range-picker/range-picker.component.ts similarity index 100% rename from web-admin-app/src/app/components/range-picker/range-picker.component.ts rename to web-admin-app/src/app/shared/components/range-picker/range-picker.component.ts diff --git a/web-admin-app/src/app/components/server-paginated-table/date-query/date-query.component.html b/web-admin-app/src/app/shared/components/server-paginated-table/date-query/date-query.component.html similarity index 100% rename from web-admin-app/src/app/components/server-paginated-table/date-query/date-query.component.html rename to web-admin-app/src/app/shared/components/server-paginated-table/date-query/date-query.component.html diff --git a/web-admin-app/src/app/components/server-paginated-table/date-query/date-query.component.less b/web-admin-app/src/app/shared/components/server-paginated-table/date-query/date-query.component.less similarity index 100% rename from web-admin-app/src/app/components/server-paginated-table/date-query/date-query.component.less rename to web-admin-app/src/app/shared/components/server-paginated-table/date-query/date-query.component.less diff --git a/web-admin-app/src/app/components/server-paginated-table/date-query/date-query.component.ts b/web-admin-app/src/app/shared/components/server-paginated-table/date-query/date-query.component.ts similarity index 100% rename from web-admin-app/src/app/components/server-paginated-table/date-query/date-query.component.ts rename to web-admin-app/src/app/shared/components/server-paginated-table/date-query/date-query.component.ts diff --git a/web-admin-app/src/app/components/server-paginated-table/index.ts b/web-admin-app/src/app/shared/components/server-paginated-table/index.ts similarity index 100% rename from web-admin-app/src/app/components/server-paginated-table/index.ts rename to web-admin-app/src/app/shared/components/server-paginated-table/index.ts diff --git a/web-admin-app/src/app/components/server-paginated-table/query-item/query-item.component.html b/web-admin-app/src/app/shared/components/server-paginated-table/query-item/query-item.component.html similarity index 100% rename from web-admin-app/src/app/components/server-paginated-table/query-item/query-item.component.html rename to web-admin-app/src/app/shared/components/server-paginated-table/query-item/query-item.component.html diff --git a/web-admin-app/src/app/components/server-paginated-table/query-item/query-item.component.less b/web-admin-app/src/app/shared/components/server-paginated-table/query-item/query-item.component.less similarity index 53% rename from web-admin-app/src/app/components/server-paginated-table/query-item/query-item.component.less rename to web-admin-app/src/app/shared/components/server-paginated-table/query-item/query-item.component.less index 0abe4ca..1241bfe 100644 --- a/web-admin-app/src/app/components/server-paginated-table/query-item/query-item.component.less +++ b/web-admin-app/src/app/shared/components/server-paginated-table/query-item/query-item.component.less @@ -1,7 +1,8 @@ .query-control { ::ng-deep { input { - width: 100px; + min-width: 100px; + width: 100%; } } } \ No newline at end of file diff --git a/web-admin-app/src/app/components/server-paginated-table/query-item/query-item.component.ts b/web-admin-app/src/app/shared/components/server-paginated-table/query-item/query-item.component.ts similarity index 100% rename from web-admin-app/src/app/components/server-paginated-table/query-item/query-item.component.ts rename to web-admin-app/src/app/shared/components/server-paginated-table/query-item/query-item.component.ts diff --git a/web-admin-app/src/app/components/server-paginated-table/server-paginated-table.component.html b/web-admin-app/src/app/shared/components/server-paginated-table/server-paginated-table.component.html similarity index 86% rename from web-admin-app/src/app/components/server-paginated-table/server-paginated-table.component.html rename to web-admin-app/src/app/shared/components/server-paginated-table/server-paginated-table.component.html index cc81e0d..4191ba8 100644 --- a/web-admin-app/src/app/components/server-paginated-table/server-paginated-table.component.html +++ b/web-admin-app/src/app/shared/components/server-paginated-table/server-paginated-table.component.html @@ -44,10 +44,17 @@ + @if (tableAction) { +
+ +
+ } + {{ th.title }} + {{ th.title }} } } @if (options.operate.length > 0) { - 操作 + 操作 + } + @if (options.columns.length > 3) { + +
+ +
+ } - -
- -
- @@ -131,7 +140,7 @@ } @if (options.operate.length > 0) { - + @@ -154,7 +163,9 @@ } - + @if (options.columns.length > 3) { + + } } diff --git a/web-admin-app/src/app/components/server-paginated-table/server-paginated-table.component.less b/web-admin-app/src/app/shared/components/server-paginated-table/server-paginated-table.component.less similarity index 100% rename from web-admin-app/src/app/components/server-paginated-table/server-paginated-table.component.less rename to web-admin-app/src/app/shared/components/server-paginated-table/server-paginated-table.component.less diff --git a/web-admin-app/src/app/components/server-paginated-table/server-paginated-table.component.ts b/web-admin-app/src/app/shared/components/server-paginated-table/server-paginated-table.component.ts similarity index 98% rename from web-admin-app/src/app/components/server-paginated-table/server-paginated-table.component.ts rename to web-admin-app/src/app/shared/components/server-paginated-table/server-paginated-table.component.ts index c750db5..d634843 100644 --- a/web-admin-app/src/app/components/server-paginated-table/server-paginated-table.component.ts +++ b/web-admin-app/src/app/shared/components/server-paginated-table/server-paginated-table.component.ts @@ -178,6 +178,10 @@ export class ServerPaginatedTableComponent implements OnInit, OnChanges { * 不使用表格模式,自定义渲染 */ @Input() renderItem?: TemplateRef<{}> + /** + * 不使用表格模式,自定义渲染 + */ + @Input() tableAction?: TemplateRef<{}> @ContentChild(TableFormDirective, { static: true, read: TemplateRef }) formContentChild!: TemplateRef diff --git a/web-admin-app/src/app/components/server-paginated-table/server-paginated-table.module.ts b/web-admin-app/src/app/shared/components/server-paginated-table/server-paginated-table.module.ts similarity index 100% rename from web-admin-app/src/app/components/server-paginated-table/server-paginated-table.module.ts rename to web-admin-app/src/app/shared/components/server-paginated-table/server-paginated-table.module.ts diff --git a/web-admin-app/src/app/components/server-paginated-table/server-paginated-table.service.ts b/web-admin-app/src/app/shared/components/server-paginated-table/server-paginated-table.service.ts similarity index 100% rename from web-admin-app/src/app/components/server-paginated-table/server-paginated-table.service.ts rename to web-admin-app/src/app/shared/components/server-paginated-table/server-paginated-table.service.ts diff --git a/web-admin-app/src/app/components/server-paginated-table/table-action.directive.ts b/web-admin-app/src/app/shared/components/server-paginated-table/table-action.directive.ts similarity index 100% rename from web-admin-app/src/app/components/server-paginated-table/table-action.directive.ts rename to web-admin-app/src/app/shared/components/server-paginated-table/table-action.directive.ts diff --git a/web-admin-app/src/app/components/server-paginated-table/table-form.directive.ts b/web-admin-app/src/app/shared/components/server-paginated-table/table-form.directive.ts similarity index 100% rename from web-admin-app/src/app/components/server-paginated-table/table-form.directive.ts rename to web-admin-app/src/app/shared/components/server-paginated-table/table-form.directive.ts diff --git a/web-admin-app/src/app/components/user-form/user-form.component.html b/web-admin-app/src/app/shared/components/user-form/user-form.component.html similarity index 100% rename from web-admin-app/src/app/components/user-form/user-form.component.html rename to web-admin-app/src/app/shared/components/user-form/user-form.component.html diff --git a/web-admin-app/src/app/shared/components/user-form/user-form.component.less b/web-admin-app/src/app/shared/components/user-form/user-form.component.less new file mode 100644 index 0000000..e69de29 diff --git a/web-admin-app/src/app/components/user-form/user-form.component.ts b/web-admin-app/src/app/shared/components/user-form/user-form.component.ts similarity index 96% rename from web-admin-app/src/app/components/user-form/user-form.component.ts rename to web-admin-app/src/app/shared/components/user-form/user-form.component.ts index 7935c73..6edefec 100644 --- a/web-admin-app/src/app/components/user-form/user-form.component.ts +++ b/web-admin-app/src/app/shared/components/user-form/user-form.component.ts @@ -7,8 +7,7 @@ import { NZ_MODAL_DATA } from 'ng-zorro-antd/modal' @Component({ selector: 'app-user-form', - standalone: true, - imports: [SharedModule], + templateUrl: './user-form.component.html', styleUrl: './user-form.component.less', }) diff --git a/web-admin-app/src/app/shared/shared.module.ts b/web-admin-app/src/app/shared/shared.module.ts index 42a5596..42a97ba 100644 --- a/web-admin-app/src/app/shared/shared.module.ts +++ b/web-admin-app/src/app/shared/shared.module.ts @@ -3,15 +3,27 @@ import { CommonModule } from '@angular/common' import { RouterOutlet, RouterModule } from '@angular/router' import { EditorModule } from '@tinymce/tinymce-angular' import { ngZorroModules } from './ng-zorro' -import { ServerPaginatedTableModule } from '../components/server-paginated-table' -import { FormErrorTipsComponent } from '../components/form-error-tips/form-error-tips.component' +import { ServerPaginatedTableModule } from './components/server-paginated-table' +import { FormErrorTipsComponent } from './components/form-error-tips/form-error-tips.component' import { FormsModule, ReactiveFormsModule } from '@angular/forms' import { PermissionModule } from './permission/permission.module' -import { RangePickerComponent } from './../components/range-picker/range-picker.component' +import { RangePickerComponent } from './components/range-picker/range-picker.component' +import { AppPageComponent } from './components/app-page/app-page.component' +import { LayoutComponent, HeaderComponent, UserFormComponent } from './components' @NgModule({ - declarations: [], - imports: [RouterOutlet, FormErrorTipsComponent, PermissionModule, RangePickerComponent], + declarations: [AppPageComponent, LayoutComponent, HeaderComponent, UserFormComponent], + imports: [ + CommonModule, + FormsModule, + ReactiveFormsModule, + RouterOutlet, + RouterModule, + FormErrorTipsComponent, + PermissionModule, + RangePickerComponent, + ...ngZorroModules, + ], exports: [ CommonModule, RouterOutlet, @@ -23,6 +35,10 @@ import { RangePickerComponent } from './../components/range-picker/range-picker. PermissionModule, RangePickerComponent, EditorModule, + AppPageComponent, + UserFormComponent, + LayoutComponent, + HeaderComponent, ...ngZorroModules, ], }) diff --git a/web-admin-app/src/app/types/http.ts b/web-admin-app/src/app/types/http.ts index 5eaad5f..ca613d8 100644 --- a/web-admin-app/src/app/types/http.ts +++ b/web-admin-app/src/app/types/http.ts @@ -1,6 +1,6 @@ export type JwResponse = { - data: T + // data: T body: T - msg: string + desc: string code: number } diff --git a/web-admin-app/src/assets/images/jiluo_logo.png b/web-admin-app/src/assets/images/jiluo_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..b635ac2bb7fcc4d909f491bdcdee9cd2750531ea GIT binary patch literal 29332 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

NgY^rrrHl z&l5dg+y1;Fy0%6h=g+YVxAFHckKz2S5!*UC5=&AlYl@evz)dm> zd<3}u+)>HxdibWC-D@1w&L?puwLzWi9-`!{l+W9Y?>4V$V>y2Q(q?R<%F&T@gSZUP zrrSFn+@xKG&YzHrdgsE?nUp78JwGI_=V=CoS!iQO2vSwQ>Tb?gVpK1pIC6Oa@9jT` zbJy-*oJzG8ztlutZ5Bk-)V}7Yp;T=mNf}VFv5pmj*-elG1@G@&ZT%LC_!@E@Na$JzcI3ff~O zma)zLwN11DCh)kXtmXq+Bnd5GY6_LkrMakS&I|I`u(%Vyeq{@`t!S|+Sdy_-swUd} zNaIp$NUwO~zc_0?ch3gRgL*EaRMXlUTEYL&`9b{oWF?|!VJdLGm> zNbu5-P_6r{SvTW;6^AYi;r*{q;QXC28i~Y$ClI?G5v2mS?`q9-h8S9t=2P=YM(f1L zJ+ylj^rn1lT$nbMWB0mFbf(C=)+Mni7E+p&!4A3g7#7EJPlv-Fp5{S43rSK77L%-} z4_+9+yPqG%=^MkC@MWCEiCOBYfo2stawFWF2^WG%R1c)45Is}tN=Mp5ysVzW6n?*N z8(vu3iv^ho5*EH%Yo?@%m$=c~H+n8jGx!>085Pe0u0Kj$IkFj+Ma6 zP*u=mBp8N-R5n=D3j;40-OS`5szpPET31nV7zf-XQYnLs+Z{B_xI|%4rO6WMjtmV?IV~FqC z@K(asam2esu#Vxc&4bkV@7nc`jpjjJN2<0f%aki=*(HN6|r4nL6fYzvwEsH$- zr?)pzhwegei{7WA#19RkvA8uWYHbo}`>t!oIV*&8whf)lNajaB(%k=%M(goO)wLFB zym);O10zM`eI`*vO?9>BLJ&bSweF)4rQ##BU_6YRJa*HtJTGqBy0xV|w8VVd((f0q z?ZlQfJ?Lt2z?H;xI~XW@6%F0juVOOo@8(Y^cMQ2)zQwq@9j)Y(H)C4eV3-uxX z)H8J+)H6sjZzNm9-Qg@MTGlK^U79*7%`gMDwQg_L1_HU(h>lhAwyoQ5 zU)zD5t2(ftHEP30Z531*t5S`KXbn;_rA6R2-+sC@59(P+tFeye3MdBJEsH=l!|QvX zn#7gN_NpaYR(M5kD}Md@ZtPjN(3o zZftxKB@N?LCk&IQtaClDy<gi#g*>ikyR%z)Ktqb)8!UYZB>3=%H1 z$)~Mjt;V{Fk4oTM3qw_%8U(X?6q_pztH@1Epd}Hdl+I(zl1}{b^=)`@T_+Y>J9I!E zinhY58#5}c**WRn2I%`}UQ*9f9SPKJnIw%g%0e^7WFoqjXFYSKWb;YO4o4`dwFvwl z-hK%?R`sASRi(No53$$-GMEuIcQgWy*wKtxJ#(`>NQN#X_;ZQRP7PhFBLrrxG$wMrvMdbO7 z0ot`_yV}D!*Mjc&a^U`HXX`wuXOI$PaYq81RxPl77bPjxUTn3x{Scg*??*s7piVn` zKI5LoT?lU4O~7?wN8wS8s0L-*TPDStVB@lG{OZk@uzkZ~YvphqDg>{*ljHY-ssrsb z&Agr`NAsYbK{CHOqZMplxd6+0sfJX`R6_*V>7)uJaShpaB-@UdC+t>7=r^SOO5C`f^nL_kDJtED6dIkx82}xmz=f*b$Bg_>+9Ph z(#WGNlEa$bG=BB!cI;TYz$VEiBV`(cG(-9N{kWZRrE)S)bJ9GhXQ7I)k$M-kYLjnAbpH0?PQ}r&*8Xf+$RiHcxXA1!@f;@SlgX+3(ZjCD;#ZT z}MS|Qp6OB<4AG6}R~QdrU3g`MkGVEwXIbb3^2VwCRGpCb{f zEd28;^qq#Mb|aWc)Aph`&^ZfQQ$g)~{gKf;sAnTLJxV9j2eo2IB5Q=6q;rmX_Xyp< z;5bIda~K}WBAYEBneuGQ=A06bLKFx!A zHWGkmqwu~|0BtOhC&0^Uuhz91IjDV5 literal 0 HcmV?d00001 diff --git a/web-admin-app/src/assets/images/login-bg.jpg b/web-admin-app/src/assets/images/login-bg.jpg index 848d29ea0e3327f6756f855945f7bd4ed9cde87b..c7a618ab9cfaae73ae8144c11ff2661d2be53cb9 100644 GIT binary patch literal 237434 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