Browse Source

基础数据 & 人事管理

main
kkerwin 2 years ago
parent
commit
0f26e35f2c
  1. 34
      web-admin-app/README.md
  2. 2
      web-admin-app/proxy/devserver.js
  3. 20
      web-admin-app/src/app/app.config.ts
  4. 85
      web-admin-app/src/app/app.routes.ts
  5. 64
      web-admin-app/src/app/components/component-basic-category-tree/component-basic-category-tree.component.html
  6. 7
      web-admin-app/src/app/components/component-basic-category-tree/component-basic-category-tree.component.less
  7. 153
      web-admin-app/src/app/components/component-basic-category-tree/component-basic-category-tree.component.ts
  8. 113
      web-admin-app/src/app/components/component-org-tree/component-org-tree.component.html
  9. 7
      web-admin-app/src/app/components/component-org-tree/component-org-tree.component.less
  10. 186
      web-admin-app/src/app/components/component-org-tree/component-org-tree.component.ts
  11. 8
      web-admin-app/src/app/components/index.ts
  12. 15
      web-admin-app/src/app/components/layout/layout.component.less
  13. 14
      web-admin-app/src/app/components/layout/layout.component.ts
  14. 74
      web-admin-app/src/app/components/select-user-by-org/select-user-by-org.component.html
  15. 21
      web-admin-app/src/app/components/select-user-by-org/select-user-by-org.component.less
  16. 128
      web-admin-app/src/app/components/select-user-by-org/select-user-by-org.component.ts
  17. 21
      web-admin-app/src/app/guards/auth.guard.ts
  18. 23
      web-admin-app/src/app/pages/component-org-tree/component-org-tree.component.html
  19. 58
      web-admin-app/src/app/pages/component-org-tree/component-org-tree.component.ts
  20. 3
      web-admin-app/src/app/pages/dashboard/dashboard.component.ts
  21. 63
      web-admin-app/src/app/pages/fixed-asset/basic/basic-category/basic-category.component.html
  22. 0
      web-admin-app/src/app/pages/fixed-asset/basic/basic-category/basic-category.component.less
  23. 82
      web-admin-app/src/app/pages/fixed-asset/basic/basic-category/basic-category.component.ts
  24. 1
      web-admin-app/src/app/pages/fixed-asset/basic/basic-goods-stock/basic-goods-stock.component.html
  25. 0
      web-admin-app/src/app/pages/fixed-asset/basic/basic-goods-stock/basic-goods-stock.component.less
  26. 12
      web-admin-app/src/app/pages/fixed-asset/basic/basic-goods-stock/basic-goods-stock.component.ts
  27. 108
      web-admin-app/src/app/pages/fixed-asset/basic/basic-maintainer/basic-maintainer.component.html
  28. 0
      web-admin-app/src/app/pages/fixed-asset/basic/basic-maintainer/basic-maintainer.component.less
  29. 136
      web-admin-app/src/app/pages/fixed-asset/basic/basic-maintainer/basic-maintainer.component.ts
  30. 75
      web-admin-app/src/app/pages/fixed-asset/basic/basic-manufacturer/basic-manufacturer.component.html
  31. 0
      web-admin-app/src/app/pages/fixed-asset/basic/basic-manufacturer/basic-manufacturer.component.less
  32. 130
      web-admin-app/src/app/pages/fixed-asset/basic/basic-manufacturer/basic-manufacturer.component.ts
  33. 108
      web-admin-app/src/app/pages/fixed-asset/basic/basic-supplier/basic-supplier.component.html
  34. 0
      web-admin-app/src/app/pages/fixed-asset/basic/basic-supplier/basic-supplier.component.less
  35. 135
      web-admin-app/src/app/pages/fixed-asset/basic/basic-supplier/basic-supplier.component.ts
  36. 77
      web-admin-app/src/app/pages/fixed-asset/basic/basic-warehouse/basic-warehouse.component.html
  37. 0
      web-admin-app/src/app/pages/fixed-asset/basic/basic-warehouse/basic-warehouse.component.less
  38. 125
      web-admin-app/src/app/pages/fixed-asset/basic/basic-warehouse/basic-warehouse.component.ts
  39. 55
      web-admin-app/src/app/pages/fixed-asset/basic/save-position/save-position.component.html
  40. 0
      web-admin-app/src/app/pages/fixed-asset/basic/save-position/save-position.component.less
  41. 122
      web-admin-app/src/app/pages/fixed-asset/basic/save-position/save-position.component.ts
  42. 48
      web-admin-app/src/app/pages/fixed-asset/fixed-asset.component.html
  43. 10
      web-admin-app/src/app/pages/fixed-asset/fixed-asset.component.less
  44. 4
      web-admin-app/src/app/pages/fixed-asset/ledger/fixed-asset-belong/fixed-asset-belong.component.ts
  45. 2
      web-admin-app/src/app/pages/fixed-asset/ledger/fixed-asset-category/fixed-asset-category.component.ts
  46. 2
      web-admin-app/src/app/pages/fixed-asset/ledger/fixed-asset-employee/fixed-asset-employee.component.ts
  47. 4
      web-admin-app/src/app/pages/fixed-asset/ledger/fixed-asset-ledger/fixed-asset-ledger.component.ts
  48. 2
      web-admin-app/src/app/pages/fixed-asset/ledger/fixed-asset-myown/fixed-asset-myown.component.ts
  49. 2
      web-admin-app/src/app/pages/fixed-asset/ledger/fixed-asset-org/fixed-asset-org.component.ts
  50. 2
      web-admin-app/src/app/pages/fixed-asset/ledger/fixed-asset-position/fixed-asset-position.component.ts
  51. 2
      web-admin-app/src/app/pages/fixed-asset/ledger/fixed-asset-search/fixed-asset-search.component.ts
  52. 6
      web-admin-app/src/app/pages/fixed-asset/manage/fixed-asset-manage-allot/fixed-asset-manage-allot.component.ts
  53. 6
      web-admin-app/src/app/pages/fixed-asset/manage/fixed-asset-manage-borrow/fixed-asset-manage-borrow.component.ts
  54. 6
      web-admin-app/src/app/pages/fixed-asset/manage/fixed-asset-manage-distribution/fixed-asset-manage-distribution.component.ts
  55. 6
      web-admin-app/src/app/pages/fixed-asset/manage/fixed-asset-manage-entry/fixed-asset-manage-entry.component.ts
  56. 6
      web-admin-app/src/app/pages/fixed-asset/manage/fixed-asset-manage-return/fixed-asset-manage-return.component.ts
  57. 6
      web-admin-app/src/app/pages/fixed-asset/manage/fixed-asset-manage-revert/fixed-asset-manage-revert.component.ts
  58. 6
      web-admin-app/src/app/pages/fixed-asset/manage/fixed-asset-manage-scrap/fixed-asset-manage-scrap.component.ts
  59. 6
      web-admin-app/src/app/pages/fixed-asset/manage/fixed-asset-manage-transfer/fixed-asset-manage-transfer.component.ts
  60. 6
      web-admin-app/src/app/pages/fixed-asset/manage/fixed-asset-manage/fixed-asset-manage.component.ts
  61. 179
      web-admin-app/src/app/pages/fixed-asset/stocktaking/stockaking-job/stockaking-job.component.html
  62. 0
      web-admin-app/src/app/pages/fixed-asset/stocktaking/stockaking-job/stockaking-job.component.less
  63. 162
      web-admin-app/src/app/pages/fixed-asset/stocktaking/stockaking-job/stockaking-job.component.ts
  64. 1
      web-admin-app/src/app/pages/fixed-asset/stocktaking/stockaking-plan/stockaking-plan.component.html
  65. 0
      web-admin-app/src/app/pages/fixed-asset/stocktaking/stockaking-plan/stockaking-plan.component.less
  66. 21
      web-admin-app/src/app/pages/fixed-asset/stocktaking/stockaking-plan/stockaking-plan.component.ts
  67. 7
      web-admin-app/src/app/pages/login/login.component.less
  68. 9
      web-admin-app/src/app/pages/login/login.component.ts
  69. 164
      web-admin-app/src/app/pages/org-setting/org-setting.component.html
  70. 218
      web-admin-app/src/app/pages/org-setting/org-setting.component.ts
  71. 34
      web-admin-app/src/app/pages/profile-account/profile-account.component.ts
  72. 13
      web-admin-app/src/app/pages/profile-basic/profile-basic.component.ts
  73. 12
      web-admin-app/src/app/pages/profile/profile.component.html
  74. 4
      web-admin-app/src/app/pages/profile/profile.component.ts
  75. 1
      web-admin-app/src/app/pages/system/index/system.component.html
  76. 0
      web-admin-app/src/app/pages/system/index/system.component.less
  77. 0
      web-admin-app/src/app/pages/system/index/system.component.ts
  78. 1
      web-admin-app/src/app/pages/system/system-user/system-user.component.html
  79. 0
      web-admin-app/src/app/pages/system/system-user/system-user.component.less
  80. 11
      web-admin-app/src/app/pages/system/system-user/system-user.component.ts
  81. 16
      web-admin-app/src/app/services/api.dto.ts
  82. 272
      web-admin-app/src/app/services/api.service.ts
  83. 60
      web-admin-app/src/app/services/local-http-interceptor.service.ts
  84. 0
      web-admin-app/src/app/shared/components/app-page/app-page.component.html
  85. 0
      web-admin-app/src/app/shared/components/app-page/app-page.component.less
  86. 2
      web-admin-app/src/app/shared/components/app-page/app-page.component.ts
  87. 0
      web-admin-app/src/app/shared/components/form-error-tips/form-error-tips.component.html
  88. 0
      web-admin-app/src/app/shared/components/form-error-tips/form-error-tips.component.less
  89. 0
      web-admin-app/src/app/shared/components/form-error-tips/form-error-tips.component.ts
  90. 2
      web-admin-app/src/app/shared/components/header/header.component.html
  91. 0
      web-admin-app/src/app/shared/components/header/header.component.less
  92. 10
      web-admin-app/src/app/shared/components/header/header.component.ts
  93. 6
      web-admin-app/src/app/shared/components/index.ts
  94. 0
      web-admin-app/src/app/shared/components/layout/layout.component.html
  95. 15
      web-admin-app/src/app/shared/components/layout/layout.component.less
  96. 8
      web-admin-app/src/app/shared/components/layout/layout.component.ts
  97. 0
      web-admin-app/src/app/shared/components/range-picker/range-picker.component.html
  98. 0
      web-admin-app/src/app/shared/components/range-picker/range-picker.component.less
  99. 0
      web-admin-app/src/app/shared/components/range-picker/range-picker.component.ts
  100. 0
      web-admin-app/src/app/shared/components/server-paginated-table/date-query/date-query.component.html

34
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.

2
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 = {}

20
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,
}
},
})

85
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,

64
web-admin-app/src/app/components/component-basic-category-tree/component-basic-category-tree.component.html

@ -0,0 +1,64 @@
<div class="w-60 overflow-auto">
<div class="flex items-center">
<div class="flex-1 pr-2">
<nz-input-group [nzSuffix]="suffixIcon">
<input type="text" nz-input placeholder="请输入关键字" [(ngModel)]="searchValue" />
</nz-input-group>
<ng-template #suffixIcon>
<span nz-icon nzType="search"></span>
</ng-template>
</div>
@if (createable) {
<button nz-button nzType="primary" (click)="onCreate(0)">添加</button>
}
</div>
<div class="py-4">
<nz-tree
class="tree"
nzBlockNode
[nzData]="nodes"
[nzExpandedKeys]="expandedKeys"
[(nzSelectedKeys)]="selectedKeys"
[nzSearchValue]="searchValue"
(nzClick)="nzEvent($event)"
(nzExpandChange)="onExpandChange($event)"
[nzTreeTemplate]="nzTreeTemplate"
>
<ng-template #nzTreeTemplate let-node let-origin="origin">
<div class="custom-node flex items-center overflow-hidden">
<div class="flex-1">
@switch (origin.organizationType) {
@case ('0') {
<span nz-icon nzType="bank" nzTheme="outline"></span>
}
@case ('1') {
<span nz-icon nzType="cluster" nzTheme="outline"></span>
}
@case ('2') {
<span nz-icon nzType="team" nzTheme="outline"></span>
}
}
<span class="ml-2 overflow-hidden text-ellipsis">{{ node.title }}</span>
</div>
<button
nz-button
nz-dropdown
[nzDropdownMenu]="menu"
nzType="text"
onclick="event.stopPropagation()"
>
<span nz-icon nzType="more"></span>
</button>
<nz-dropdown-menu #menu="nzDropdownMenu">
<ul nz-menu>
<li nz-menu-item (click)="onCreate(origin.parentId)">添加同级分类</li>
<li nz-menu-item (click)="onCreate(origin.categoryId)">添加下级分类</li>
<li nz-menu-divider></li>
<li nz-menu-item (click)="onDelete(origin.categoryId)">删除</li>
</ul>
</nz-dropdown-menu>
</div>
</ng-template>
</nz-tree>
</div>
</div>

7
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;
}
}
}

153
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<NzSafeAny>()
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()
})
},
})
}
}

113
web-admin-app/src/app/components/component-org-tree/component-org-tree.component.html

@ -0,0 +1,113 @@
<div class="overflow-auto">
<div class="flex items-center">
<div class="flex-1">
<nz-input-group [nzSuffix]="suffixIcon">
<input type="text" nz-input placeholder="请输入关键字" [(ngModel)]="searchValue" />
</nz-input-group>
<ng-template #suffixIcon>
<span nz-icon nzType="search"></span>
</ng-template>
</div>
@if (createable) {
<button nz-button class="pl-2" nzType="primary" nz-dropdown [nzDropdownMenu]="createMenu">添加</button>
<nz-dropdown-menu #createMenu="nzDropdownMenu">
<ul nz-menu>
<li nz-menu-item (click)="onCreate(true, orgFormTpl, confirmTpl)">添加组织</li>
<li nz-menu-item (click)="onCreate(false, orgFormTpl, confirmTpl)">添加岗位</li>
</ul>
</nz-dropdown-menu>
}
</div>
<div class="py-4">
<nz-tree
class="tree"
nzBlockNode
[nzData]="nodes"
[nzExpandedKeys]="expandedKeys"
[nzSearchValue]="searchValue"
(nzClick)="nzEvent($event)"
(nzExpandChange)="onExpandChange($event)"
[nzTreeTemplate]="nzTreeTemplate"
>
<ng-template #nzTreeTemplate let-node let-origin="origin">
<div class="custom-node flex items-center overflow-hidden">
<div class="flex-1">
@switch (origin.organizationType) {
@case ('0') {
<span nz-icon nzType="bank" nzTheme="outline"></span>
}
@case ('1') {
<span nz-icon nzType="cluster" nzTheme="outline"></span>
}
@case ('2') {
<span nz-icon nzType="team" nzTheme="outline"></span>
}
}
<span class="ml-2 overflow-hidden text-ellipsis">{{ node.title }}</span>
</div>
@if (createable) {
<button
nz-button
nz-dropdown
[nzDropdownMenu]="menu"
nzType="text"
onclick="event.stopPropagation()"
>
<span nz-icon nzType="more"></span>
</button>
<nz-dropdown-menu #menu="nzDropdownMenu">
<ul nz-menu>
<li nz-menu-item (click)="onCreate(true, orgFormTpl, confirmTpl, origin)">添加组织</li>
<li nz-menu-item (click)="onCreate(false, orgFormTpl, confirmTpl, origin)">添加岗位</li>
<li nz-menu-item (click)="onCreate(false, orgFormTpl, confirmTpl, origin, true)">
编辑
</li>
<li nz-menu-divider></li>
<li nz-menu-item (click)="onDelete(origin.organizationId)">删除</li>
</ul>
</nz-dropdown-menu>
}
</div>
</ng-template>
</nz-tree>
</div>
<ng-template #orgFormTpl>
<form nz-form nzLayout="vertical" [formGroup]="form">
<nz-form-item>
<nz-form-label> 名称 </nz-form-label>
<nz-form-control [nzErrorTip]="errorTpl">
<input type="text" nz-input formControlName="organizationName" placeholder="请输入名称" />
</nz-form-control>
</nz-form-item>
@if (isOrg) {
<nz-form-item>
<nz-form-label> 类型 </nz-form-label>
<nz-form-control [nzErrorTip]="errorTpl">
<nz-radio-group formControlName="organizationType">
<label nz-radio nzValue="0"> 公司 </label>
<label nz-radio nzValue="1"> 部门 </label>
</nz-radio-group>
</nz-form-control>
</nz-form-item>
}
<nz-form-item>
<nz-form-label> 状态 </nz-form-label>
<nz-form-control [nzErrorTip]="errorTpl">
<nz-switch formControlName="status"></nz-switch>
</nz-form-control>
</nz-form-item>
</form>
</ng-template>
<ng-template #errorTpl let-control>
<form-error-tips [control]="control"></form-error-tips>
</ng-template>
<ng-template #confirmTpl>
<nz-space>
<button *nzSpaceItem nz-button nzType="primary" (click)="onConfirm()">确定</button>
<button *nzSpaceItem nz-button nzType="default" (click)="onCancel()">取消</button>
</nz-space>
</ng-template>
</div>

7
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;
}
}
}

186
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<NzSafeAny>()
drawerRef?: NzDrawerRef
isOrg = false
searchValue = ''
parentId?: number
nodes: NzSafeAny[] = []
expandedKeys: string[] = []
form!: FormGroup
initForm() {
this.form = this.fb.group({
organizationId: this.fb.control<number | null>(null, []),
organizationName: this.fb.control('', [FormValidators.required('请输入组织名称')]),
organizationType: this.fb.control<string>('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<NzSafeAny>,
nzFooter: TemplateRef<NzSafeAny>,
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
}
}

8
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'

15
web-admin-app/src/app/components/layout/layout.component.less

@ -1,15 +0,0 @@
:host {
display: block;
height: 100%;
}
.app-width {
::ng-deep {
router-outlet+* {
display: block;
width: 100%;
height: 100%;
// overflow: hidden;
}
}
}

14
web-admin-app/src/app/components/layout/layout.component.ts

@ -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 {
}

74
web-admin-app/src/app/components/select-user-by-org/select-user-by-org.component.html

@ -0,0 +1,74 @@
<div
class="cursor-pointer trigger min-h-[100px] max-h-[200px] overflow-auto p-3"
(click)="onTriggerClick(selectUserModalTpl)"
>
@if (selectedKeys.size > 0) {
<ng-container [ngTemplateOutlet]="selectedUserTpl"></ng-container>
} @else {
<div class="p-3 h-full flex min-h-[100px] items-center justify-center w-full text-black opacity-50">
<i nz-icon nzType="plus" class="text-large"></i>
<span class="ml-2">
{{ placeholder }}
</span>
</div>
}
</div>
<ng-template #selectedUserTpl>
@for (uid of selectedKeys; track $index) {
<span class="mr-2 mb-2">
<nz-tag>{{ allGetedDataMap.get(uid).userName }}</nz-tag>
</span>
}
</ng-template>
<ng-template #selectUserModalTpl>
<div class="cursor-pointer trigger min-h-[100px] max-h-[200px] overflow-auto p-3">
<ng-container [ngTemplateOutlet]="selectedUserTpl"></ng-container>
</div>
<div class="mt-3">
<nz-card
nzTitle="员工"
[nzBordered]="true"
class="user-select"
nzSize="small"
[nzBodyStyle]="{ padding: '0px' }"
>
<div class="h-96 flex">
<div class="flex-1 org py-3 px-2 overflow-auto">
<app-component-org-tree [createable]="false" (onOrgSelectedChange)="onOrgSelectedChange($event)" />
</div>
<div class="flex-1 flex flex-col overflow-hidden relative user-list">
<div class="hd flex items-center justify-between py-2 px-3">
<!-- <a nz-button nzType="link" class="flex"> 已选 1/{{ currentUsers.length }} </a> -->
<span class="flex"> 全选 </span>
<label
nz-checkbox
[nzIndeterminate]="indeterminate"
[nzChecked]="allChecked"
(nzCheckedChange)="onAllCheckedChange($event)"
>
</label>
</div>
<div class="bd flex-1 overflow-auto">
<ul>
@for (item of currentUsers; track $index) {
<li class="item flex items-center justify-between py-2 px-3">
<span class="flex-1"> {{ item.userName }} </span>
<label
nz-checkbox
(nzCheckedChange)="onUserCheckedChange($event, item.userId)"
[nzValue]="item.userId"
[nzChecked]="selectedKeys.has(item.userId)"
>
</label>
</li>
}
</ul>
</div>
</div>
</div>
</nz-card>
</div>
</ng-template>

21
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;
}
}
}
}

128
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<number, NzSafeAny>()
currentUsers: NzSafeAny[] = []
selectedKeys = new Set<number>()
indeterminate = false
allChecked = false
ngOnInit(): void {}
onTriggerClick(nzContent: TemplateRef<NzSafeAny>) {
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 {}
}

21
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 local = inject(LocalHttpInterceptorService)
// const accessData = local.getAccess()
// let token = accessData?.access_token
// if (token) {
// return true
// }
const router = inject(Router)
const api = inject(ApiService)
if (!api.authInfo) {
return router.createUrlTree(['/login'])
// const api = inject(ApiService)
// if (!localStorage.getItem('sc')) {
// return router.createUrlTree(['/login'])
// }
// return api.getAuthInfo(true).pipe(map((r) => !!r))
}
return true
}

23
web-admin-app/src/app/pages/component-org-tree/component-org-tree.component.html

@ -1,23 +0,0 @@
<div class="flex items-center">
<div class="flex-1 pr-2">
<nz-input-group [nzSuffix]="suffixIcon">
<input type="text" nz-input placeholder="请输入关键字" [(ngModel)]="searchValue" />
</nz-input-group>
<ng-template #suffixIcon>
<span nz-icon nzType="search"></span>
</ng-template>
</div>
@if (createable) {
<button nz-button nzType="primary">添加</button>
}
</div>
<div class="py-4">
<nz-tree
nzBlockNode
[nzData]="nodes"
[nzSearchValue]="searchValue"
(nzClick)="nzEvent($event)"
(nzExpandChange)="nzEvent($event)"
(nzSearchValueChange)="nzEvent($event)"
></nz-tree>
</div>

58
web-admin-app/src/app/pages/component-org-tree/component-org-tree.component.ts

@ -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)
}
}

3
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'],

63
web-admin-app/src/app/pages/fixed-asset/basic/basic-category/basic-category.component.html

@ -0,0 +1,63 @@
<app-page class="p-3">
<div class="flex flex-1">
<nz-card [nzBordered]="false" class="org shadow" nzSize="small">
<app-component-basic-category-tree #treeEl (onSelectedChange)="onSelectedChange($event)" />
</nz-card>
<div class="flex-1 pl-3">
<nz-card [nzBordered]="false" nzTitle="分类信息">
<form nz-form nzLayout="vertical" [formGroup]="createForm" class="w-72">
<nz-form-item>
<nz-form-label [nzRequired]="true"> 名称 </nz-form-label>
<nz-form-control [nzErrorTip]="errorTpl">
<input type="text" nz-input formControlName="categoryName" placeholder="请输入名称" />
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label> 安全库存 </nz-form-label>
<nz-form-control [nzErrorTip]="errorTpl">
<nz-input-number
nzPlaceHolder="请输入"
[nzMin]="0"
class="!w-full"
formControlName="safetyLimit"
/>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label> 安全库存上限 </nz-form-label>
<nz-form-control [nzErrorTip]="errorTpl">
<nz-input-number
nzPlaceHolder="请输入"
[nzMin]="0"
class="!w-full"
formControlName="upperLimit"
/>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label> 安全库存下限 </nz-form-label>
<nz-form-control [nzErrorTip]="errorTpl">
<nz-input-number
nzPlaceHolder="请输入"
[nzMin]="0"
class="!w-full"
formControlName="lowerLimit"
/>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-control>
<nz-space>
<button *nzSpaceItem nz-button nzType="primary" (click)="onConfirm()">确定</button>
</nz-space>
</nz-form-control>
</nz-form-item>
</form>
</nz-card>
</div>
</div>
</app-page>
<ng-template #errorTpl let-control>
<form-error-tips [control]="control"></form-error-tips>
</ng-template>

0
web-admin-app/src/app/components/form-error-tips/form-error-tips.component.less → web-admin-app/src/app/pages/fixed-asset/basic/basic-category/basic-category.component.less

82
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<NzSafeAny>
@ViewChild('formContentTpl') formContentTpl!: TemplateRef<NzSafeAny>
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()
})
}
}
}

1
web-admin-app/src/app/pages/fixed-asset/basic/basic-goods-stock/basic-goods-stock.component.html

@ -0,0 +1 @@
<p>basic-goods-stock works!</p>

0
web-admin-app/src/app/components/range-picker/range-picker.component.less → web-admin-app/src/app/pages/fixed-asset/basic/basic-goods-stock/basic-goods-stock.component.less

12
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 {
}

108
web-admin-app/src/app/pages/fixed-asset/basic/basic-maintainer/basic-maintainer.component.html

@ -0,0 +1,108 @@
<app-page class="p-3" [actions]="actionsTpl">
<ng-template #actionsTpl>
<nz-space>
<button *nzSpaceItem nz-button nzType="primary" (click)="onCreate()">新建</button>
</nz-space>
</ng-template>
<div class="flex-1 overflow-hidden">
<app-server-paginated-table [options]="table" [renderColumn]="renderColumnTpl" [formGroup]="queryForm">
<ng-template #renderColumnTpl let-data let-key="key" let-row="row">
@switch (key) {
@case ('status') {
<!-- <nz-badge
[nzText]="data === 0 ? '在职' : '离职'"
[nzStatus]="data === 0 ? 'processing' : 'error'"
/> -->
}
@default {
{{ data }}
}
}
</ng-template>
<ng-container *appTableForm>
<app-query-item label="名称" class="w-60">
<input nz-input placeholder="请输入" formControlName="name" />
</app-query-item>
<app-query-item label="编码" class="w-60">
<input nz-input placeholder="请输入" formControlName="code" />
</app-query-item>
<app-query-item label="统一社会信用代码">
<input nz-input placeholder="请输入" formControlName="uscc" />
</app-query-item>
</ng-container>
</app-server-paginated-table>
</div>
</app-page>
<ng-template #drawerFooterTpl>
<nz-space>
<button *nzSpaceItem nz-button nzType="primary" (click)="onConfirm()">确定</button>
<button *nzSpaceItem nz-button nzType="default" (click)="onCancel()">取消</button>
</nz-space>
</ng-template>
<ng-template #formContentTpl>
<form nz-form nzLayout="vertical" [formGroup]="createForm">
<nz-form-item>
<nz-form-label nzRequired> 名称 </nz-form-label>
<nz-form-control [nzErrorTip]="errorTpl">
<input type="text" nz-input formControlName="name" placeholder="请输入名称" />
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label> 编码 </nz-form-label>
<nz-form-control [nzErrorTip]="errorTpl">
<input type="text" nz-input formControlName="code" placeholder="请输入编码" />
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label> 统一社会信用代码 </nz-form-label>
<nz-form-control [nzErrorTip]="errorTpl">
<input type="text" nz-input formControlName="uscc" placeholder="请输入统一社会信用代码" />
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label> 商务联系人 </nz-form-label>
<nz-form-control [nzErrorTip]="errorTpl">
<input type="text" nz-input formControlName="businessContactor" placeholder="请输入商务联系人" />
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label> 商务联系方式 </nz-form-label>
<nz-form-control [nzErrorTip]="errorTpl">
<input type="text" nz-input formControlName="businessContact" placeholder="请输入商务联系方式" />
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label> 售后联系人 </nz-form-label>
<nz-form-control [nzErrorTip]="errorTpl">
<input type="text" nz-input formControlName="afterSalesContactor" placeholder="请输入售后联系人" />
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label> 售后联系方式 </nz-form-label>
<nz-form-control [nzErrorTip]="errorTpl">
<input type="text" nz-input formControlName="afterSalesContact" placeholder="请输入售后联系方式" />
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label> 地址 </nz-form-label>
<nz-form-control [nzErrorTip]="errorTpl">
<textarea nz-input formControlName="address" placeholder="请输入地址"></textarea>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label> 备注 </nz-form-label>
<nz-form-control [nzErrorTip]="errorTpl">
<textarea nz-input formControlName="notes" placeholder="请输入备注"></textarea>
</nz-form-control>
</nz-form-item>
</form>
</ng-template>
<ng-template #errorTpl let-control>
<form-error-tips [control]="control"></form-error-tips>
</ng-template>

0
web-admin-app/src/app/components/user-form/user-form.component.less → web-admin-app/src/app/pages/fixed-asset/basic/basic-maintainer/basic-maintainer.component.less

136
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<NzSafeAny>
@ViewChild('formContentTpl') formContentTpl!: TemplateRef<NzSafeAny>
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()
},
})
}
}

75
web-admin-app/src/app/pages/fixed-asset/basic/basic-manufacturer/basic-manufacturer.component.html

@ -0,0 +1,75 @@
<app-page class="p-3" [actions]="actionsTpl">
<ng-template #actionsTpl>
<nz-space>
<button *nzSpaceItem nz-button nzType="primary" (click)="onCreate()">新建</button>
</nz-space>
</ng-template>
<div class="overflow-hidden flex-1">
<app-server-paginated-table [options]="table" [renderColumn]="renderColumnTpl" [formGroup]="queryForm">
<ng-template #renderColumnTpl let-data let-key="key" let-row="row">
@switch (key) {
@case ('status') {
<!-- <nz-badge
[nzText]="data === 0 ? '在职' : '离职'"
[nzStatus]="data === 0 ? 'processing' : 'error'"
/> -->
}
@default {
{{ data }}
}
}
</ng-template>
<ng-container *appTableForm>
<app-query-item label="名称" class="w-60">
<input nz-input placeholder="请输入" formControlName="name" />
</app-query-item>
<app-query-item label="编码" class="w-60">
<input nz-input placeholder="请输入" formControlName="code" />
</app-query-item>
</ng-container>
</app-server-paginated-table>
</div>
</app-page>
<ng-template #drawerFooterTpl>
<nz-space>
<button *nzSpaceItem nz-button nzType="primary" (click)="onConfirm()">确定</button>
<button *nzSpaceItem nz-button nzType="default" (click)="onCancel()">取消</button>
</nz-space>
</ng-template>
<ng-template #formContentTpl>
<form nz-form nzLayout="vertical" [formGroup]="createForm">
<nz-form-item>
<nz-form-label nzRequired> 名称 </nz-form-label>
<nz-form-control [nzErrorTip]="errorTpl">
<input type="text" nz-input formControlName="name" placeholder="请输入名称" />
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label> 编码 </nz-form-label>
<nz-form-control [nzErrorTip]="errorTpl">
<input type="text" nz-input formControlName="code" placeholder="请输入编码" />
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label> 地址 </nz-form-label>
<nz-form-control [nzErrorTip]="errorTpl">
<textarea nz-input formControlName="address" placeholder="请输入地址"></textarea>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label> 备注 </nz-form-label>
<nz-form-control [nzErrorTip]="errorTpl">
<textarea nz-input formControlName="notes" placeholder="请输入备注"></textarea>
</nz-form-control>
</nz-form-item>
</form>
</ng-template>
<ng-template #errorTpl let-control>
<form-error-tips [control]="control"></form-error-tips>
</ng-template>

0
web-admin-app/src/app/pages/component-org-tree/component-org-tree.component.less → web-admin-app/src/app/pages/fixed-asset/basic/basic-manufacturer/basic-manufacturer.component.less

130
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<NzSafeAny>
@ViewChild('formContentTpl') formContentTpl!: TemplateRef<NzSafeAny>
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()
},
})
}
}

108
web-admin-app/src/app/pages/fixed-asset/basic/basic-supplier/basic-supplier.component.html

@ -0,0 +1,108 @@
<app-page class="p-3" [actions]="actionsTpl">
<ng-template #actionsTpl>
<nz-space>
<button *nzSpaceItem nz-button nzType="primary" (click)="onCreate()">新建</button>
</nz-space>
</ng-template>
<div class="flex-1 overflow-hidden">
<app-server-paginated-table [options]="table" [renderColumn]="renderColumnTpl" [formGroup]="queryForm">
<ng-template #renderColumnTpl let-data let-key="key" let-row="row">
@switch (key) {
@case ('status') {
<!-- <nz-badge
[nzText]="data === 0 ? '在职' : '离职'"
[nzStatus]="data === 0 ? 'processing' : 'error'"
/> -->
}
@default {
{{ data }}
}
}
</ng-template>
<ng-container *appTableForm>
<app-query-item label="名称" class="w-60">
<input nz-input placeholder="请输入" formControlName="name" />
</app-query-item>
<app-query-item label="编码" class="w-60">
<input nz-input placeholder="请输入" formControlName="code" />
</app-query-item>
<app-query-item label="统一社会信用代码">
<input nz-input placeholder="请输入" formControlName="uscc" />
</app-query-item>
</ng-container>
</app-server-paginated-table>
</div>
</app-page>
<ng-template #drawerFooterTpl>
<nz-space>
<button *nzSpaceItem nz-button nzType="primary" (click)="onConfirm()">确定</button>
<button *nzSpaceItem nz-button nzType="default" (click)="onCancel()">取消</button>
</nz-space>
</ng-template>
<ng-template #formContentTpl>
<form nz-form nzLayout="vertical" [formGroup]="createForm">
<nz-form-item>
<nz-form-label nzRequired> 名称 </nz-form-label>
<nz-form-control [nzErrorTip]="errorTpl">
<input type="text" nz-input formControlName="name" placeholder="请输入名称" />
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label> 编码 </nz-form-label>
<nz-form-control [nzErrorTip]="errorTpl">
<input type="text" nz-input formControlName="code" placeholder="请输入编码" />
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label> 统一社会信用代码 </nz-form-label>
<nz-form-control [nzErrorTip]="errorTpl">
<input type="text" nz-input formControlName="uscc" placeholder="请输入统一社会信用代码" />
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label> 商务联系人 </nz-form-label>
<nz-form-control [nzErrorTip]="errorTpl">
<input type="text" nz-input formControlName="businessContactor" placeholder="请输入商务联系人" />
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label> 商务联系方式 </nz-form-label>
<nz-form-control [nzErrorTip]="errorTpl">
<input type="text" nz-input formControlName="businessContact" placeholder="请输入商务联系方式" />
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label> 售后联系人 </nz-form-label>
<nz-form-control [nzErrorTip]="errorTpl">
<input type="text" nz-input formControlName="afterSalesContactor" placeholder="请输入售后联系人" />
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label> 售后联系方式 </nz-form-label>
<nz-form-control [nzErrorTip]="errorTpl">
<input type="text" nz-input formControlName="afterSalesContact" placeholder="请输入售后联系方式" />
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label> 地址 </nz-form-label>
<nz-form-control [nzErrorTip]="errorTpl">
<textarea nz-input formControlName="address" placeholder="请输入地址"></textarea>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label> 备注 </nz-form-label>
<nz-form-control [nzErrorTip]="errorTpl">
<textarea nz-input formControlName="notes" placeholder="请输入备注"></textarea>
</nz-form-control>
</nz-form-item>
</form>
</ng-template>
<ng-template #errorTpl let-control>
<form-error-tips [control]="control"></form-error-tips>
</ng-template>

0
web-admin-app/src/app/pages/system/system.component.less → web-admin-app/src/app/pages/fixed-asset/basic/basic-supplier/basic-supplier.component.less

135
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<NzSafeAny>
@ViewChild('formContentTpl') formContentTpl!: TemplateRef<NzSafeAny>
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()
},
})
}
}

77
web-admin-app/src/app/pages/fixed-asset/basic/basic-warehouse/basic-warehouse.component.html

@ -0,0 +1,77 @@
<app-page class="p-3" [actions]="actionsTpl">
<ng-template #actionsTpl>
<nz-space>
<button *nzSpaceItem nz-button nzType="primary" (click)="onCreate()">新建</button>
</nz-space>
</ng-template>
<div class="flex flex-1">
<div class="flex-1">
<app-server-paginated-table [options]="table" [renderColumn]="renderColumnTpl" [formGroup]="queryForm">
<ng-template #renderColumnTpl let-data let-key="key" let-row="row">
@switch (key) {
@case ('status') {
<nz-badge
[nzText]="data === 0 ? '启用' : '禁用'"
[nzStatus]="data === 0 ? 'processing' : 'error'"
/>
}
@default {
{{ data }}
}
}
</ng-template>
<ng-container *appTableForm>
<app-query-item label="名称" class="w-60">
<input nz-input placeholder="请输入" formControlName="name" />
</app-query-item>
<app-query-item label="状态">
<nz-select
nzPlacement="bottomRight"
nzBorderless
class="!w-20"
[nzDropdownMatchSelectWidth]="false"
formControlName="status"
nzAllowClear
>
<nz-option [nzValue]="0" nzLabel="启用"></nz-option>
<nz-option [nzValue]="1" nzLabel="禁用"></nz-option>
</nz-select>
</app-query-item>
</ng-container>
</app-server-paginated-table>
</div>
</div>
</app-page>
<ng-template #drawerFooterTpl>
<nz-space>
<button *nzSpaceItem nz-button nzType="primary" (click)="onConfirm()">确定</button>
<button *nzSpaceItem nz-button nzType="default" (click)="onCancel()">取消</button>
</nz-space>
</ng-template>
<ng-template #formContentTpl>
<form nz-form nzLayout="vertical" [formGroup]="createForm">
<nz-form-item>
<nz-form-label nzRequired> 名称 </nz-form-label>
<nz-form-control [nzErrorTip]="errorTpl">
<input type="text" nz-input formControlName="name" placeholder="请输入名称" />
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label nzRequired> 状态 </nz-form-label>
<nz-form-control [nzErrorTip]="errorTpl">
<nz-radio-group formControlName="status">
<label nz-radio [nzValue]="0"> 启用 </label>
<label nz-radio [nzValue]="1"> 禁用 </label>
</nz-radio-group>
</nz-form-control>
</nz-form-item>
</form>
</ng-template>
<ng-template #errorTpl let-control>
<form-error-tips [control]="control"></form-error-tips>
</ng-template>

0
web-admin-app/src/app/pages/fixed-asset/basic/basic-warehouse/basic-warehouse.component.less

125
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<NzSafeAny>
@ViewChild('formContentTpl') formContentTpl!: TemplateRef<NzSafeAny>
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()
},
})
}
}

55
web-admin-app/src/app/pages/fixed-asset/basic/save-position/save-position.component.html

@ -0,0 +1,55 @@
<app-page class="p-3" [actions]="actionsTpl">
<ng-template #actionsTpl>
<nz-space>
<button *nzSpaceItem nz-button nzType="primary" (click)="onCreate()">新建</button>
</nz-space>
</ng-template>
<div class="flex flex-1">
<div class="flex-1">
<app-server-paginated-table [options]="table" [renderColumn]="renderColumnTpl" [formGroup]="queryForm">
<ng-template #renderColumnTpl let-data let-key="key" let-row="row">
@switch (key) {
@case ('status') {
<!-- <nz-badge
[nzText]="data === 0 ? '在职' : '离职'"
[nzStatus]="data === 0 ? 'processing' : 'error'"
/> -->
}
@default {
{{ data }}
}
}
</ng-template>
<ng-container *appTableForm>
<app-query-item label="名称" class="w-60">
<input nz-input placeholder="请输入" formControlName="name" />
</app-query-item>
</ng-container>
</app-server-paginated-table>
</div>
</div>
</app-page>
<ng-template #drawerFooterTpl>
<nz-space>
<button *nzSpaceItem nz-button nzType="primary" (click)="onConfirm()">确定</button>
<button *nzSpaceItem nz-button nzType="default" (click)="onCancel()">取消</button>
</nz-space>
</ng-template>
<ng-template #formContentTpl>
<form nz-form nzLayout="vertical" [formGroup]="createForm">
<nz-form-item>
<nz-form-label nzRequired> 名称 </nz-form-label>
<nz-form-control [nzErrorTip]="errorTpl">
<input type="text" nz-input formControlName="name" placeholder="请输入名称" />
</nz-form-control>
</nz-form-item>
</form>
</ng-template>
<ng-template #errorTpl let-control>
<form-error-tips [control]="control"></form-error-tips>
</ng-template>

0
web-admin-app/src/app/pages/fixed-asset/basic/save-position/save-position.component.less

122
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<NzSafeAny>
@ViewChild('formContentTpl') formContentTpl!: TemplateRef<NzSafeAny>
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()
},
})
}
}

48
web-admin-app/src/app/pages/fixed-asset/fixed-asset.component.html

@ -1,4 +1,6 @@
<div class="bg-white shadow w-48 flex-shrink-0 pt-3 h-full overflow-y-auto overflow-x-hidden">
<div
class="menu bg-white shadow fixed left-0 top-12 bottom-0 z-20 w-48 flex-shrink-0 pt-3 h-full overflow-y-auto overflow-x-hidden"
>
<ul nz-menu nzMode="inline">
<li nz-menu-item [nzPaddingLeft]="12" [routerLink]="['/fixed-asset/ledger']" nzMatchRouter>固资台账</li>
<li
@ -96,10 +98,48 @@
</li>
<li nz-menu-item [nzPaddingLeft]="12" [routerLink]="['/fixed-asset/flow']" nzMatchRouter>固资流程</li>
<li nz-menu-item [nzPaddingLeft]="12" [routerLink]="['/fixed-asset/kucun']" nzMatchRouter>库存物品</li>
<li nz-menu-item [nzPaddingLeft]="12" [routerLink]="['/fixed-asset/pandian']" nzMatchRouter>盘点管理</li>
<li nzMatchRouter [nzPaddingLeft]="12" nz-submenu nzTitle="盘点管理">
<ul>
<li nz-menu-item [nzPaddingLeft]="24" [routerLink]="['/fixed-asset/stocktaking/job']" nzMatchRouter>
盘点计划
</li>
<li nz-menu-item [nzPaddingLeft]="24" [routerLink]="['/fixed-asset/stocktaking/plan']" nzMatchRouter>
盘点任务
</li>
</ul>
</li>
<li nz-menu-item [nzPaddingLeft]="12" [routerLink]="['/fixed-asset/alert']" nzMatchRouter>预警中心</li>
<li nz-menu-item [nzPaddingLeft]="12" [routerLink]="['/fixed-asset/basic']" nzMatchRouter>基础数据</li>
<li nzMatchRouter [nzPaddingLeft]="12" nz-submenu nzTitle="基础数据">
<ul>
<li nz-menu-item [nzPaddingLeft]="24" [routerLink]="['/fixed-asset/basic/goods-stock']" nzMatchRouter>
物品档案
</li>
<li nz-menu-item [nzPaddingLeft]="24" [routerLink]="['/fixed-asset/basic/category']" nzMatchRouter>
物品分类
</li>
<li nz-menu-item [nzPaddingLeft]="24" [routerLink]="['/fixed-asset/basic/manufacturer']" nzMatchRouter>
生产商
</li>
<li nz-menu-item [nzPaddingLeft]="24" [routerLink]="['/fixed-asset/basic/supplier']" nzMatchRouter>
供应商
</li>
<li nz-menu-item [nzPaddingLeft]="24" [routerLink]="['/fixed-asset/basic/maintainer']" nzMatchRouter>
维保商
</li>
<li nz-menu-item [nzPaddingLeft]="24" [routerLink]="['/fixed-asset/basic/save-position']" nzMatchRouter>
存放位置
</li>
<li nz-menu-item [nzPaddingLeft]="24" [routerLink]="['/fixed-asset/basic/warehouse']" nzMatchRouter>
存放仓库
</li>
</ul>
</li>
<li nz-menu-item [nzPaddingLeft]="12" [routerLink]="['/fixed-asset/system']" nzMatchRouter>系统设置</li>
</ul>
</div>
<router-outlet></router-outlet>
<div class="pl-48 overflow-hidden">
<router-outlet></router-outlet>
</div>

10
web-admin-app/src/app/pages/fixed-asset/fixed-asset.component.less

@ -1,4 +1,6 @@
:host {
display: flex !important;
width: 100%;
}
// :host {
// display: flex !important;
// width: auto;
// overflow: hidden;
// }

4
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'

2
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'

2
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'

4
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',
})

2
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'

2
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'

2
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'

2
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'

6
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',
})

6
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',
})

6
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',
})

6
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',
})

6
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',
})

6
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',
})

6
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',
})

6
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',
})

6
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',
})

179
web-admin-app/src/app/pages/fixed-asset/stocktaking/stockaking-job/stockaking-job.component.html

@ -0,0 +1,179 @@
<app-page class="p-3">
<div class="flex-1 overflow-hidden">
<app-server-paginated-table
[options]="table"
[tableAction]="tableActionTpl"
[renderColumn]="renderColumnTpl"
[formGroup]="queryForm"
>
<ng-template #renderColumnTpl let-data let-key="key" let-row="row">
@switch (key) {
@case ('fullStocktaking') {
@switch (data) {
@case (0) {
<nz-badge [nzText]="'禁用'" [nzStatus]="'error'" />
}
@case (1) {
<nz-badge [nzText]="'启用'" [nzStatus]="'processing'" />
}
@default {
-
}
}
}
@case ('status') {
@switch (data) {
@case (0) {
<nz-badge [nzText]="'未开始'" [nzStatus]="'default'" />
}
@case (1) {
<nz-badge [nzText]="'进行中'" [nzStatus]="'processing'" />
}
@case (2) {
<nz-badge [nzText]="'取消'" [nzStatus]="'error'" />
}
@case (3) {
<nz-badge [nzText]="'已完成'" [nzStatus]="'success'" />
}
@default {
-
}
}
}
@default {
{{ data }}
}
}
</ng-template>
<ng-template #tableActionTpl>
<nz-space>
<button *nzSpaceItem nz-button nzType="primary" (click)="onCreate()">新建</button>
<button *nzSpaceItem [disabled]="table.ref.selected.size === 0" nz-button (click)="onBegin()">
开始盘点
</button>
<button *nzSpaceItem [disabled]="table.ref.selected.size === 0" nz-button (click)="onStop()">
结束盘点
</button>
</nz-space>
</ng-template>
<ng-container *appTableForm>
<app-query-item label="名称" class="w-60">
<input nz-input placeholder="请输入" formControlName="name" />
</app-query-item>
<app-query-item label="编码" class="w-60">
<input nz-input placeholder="请输入" formControlName="code" />
</app-query-item>
<app-query-item label="统一社会信用代码">
<input nz-input placeholder="请输入" formControlName="uscc" />
</app-query-item>
</ng-container>
</app-server-paginated-table>
</div>
</app-page>
<ng-template #drawerFooterTpl>
<nz-space>
<button *nzSpaceItem nz-button nzType="primary" (click)="onConfirm()">确定</button>
<button *nzSpaceItem nz-button nzType="default" (click)="onCancel()">取消</button>
</nz-space>
</ng-template>
<ng-template #formContentTpl>
<form nz-form nzLayout="vertical" [formGroup]="createForm">
<nz-form-item>
<nz-form-label nzRequired> 名称 </nz-form-label>
<nz-form-control [nzErrorTip]="errorTpl">
<input type="text" nz-input formControlName="name" placeholder="请输入名称" />
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label> 全员盘点 </nz-form-label>
<nz-form-control [nzErrorTip]="errorTpl">
<nz-radio-group formControlName="fullStocktaking">
<label nz-radio [nzValue]="1">启用</label>
<label nz-radio [nzValue]="0">禁用</label>
</nz-radio-group>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label> 负责人 </nz-form-label>
<nz-form-control [nzErrorTip]="errorTpl">
<app-select-user-by-org />
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label> 盘点人 </nz-form-label>
<nz-form-control [nzErrorTip]="errorTpl"> </nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label> 备注 </nz-form-label>
<nz-form-control [nzErrorTip]="errorTpl">
<textarea nz-input formControlName="notes" placeholder="请输入备注"></textarea>
</nz-form-control>
</nz-form-item>
<h2>盘点范围</h2>
<nz-form-item>
<nz-form-label> 购置开始日期 </nz-form-label>
<nz-form-control>
<nz-date-picker nzShowTime formControlName="stocktakingStartDate" />
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label> 购置结束日期 </nz-form-label>
<nz-form-control>
<nz-date-picker nzShowTime formControlName="stocktakingStartDate" />
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label> 资产分类 </nz-form-label>
<nz-form-control>
<nz-select> </nz-select>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label> 资产状态 </nz-form-label>
<nz-form-control>
<nz-select> </nz-select>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label> 位置 </nz-form-label>
<nz-form-control>
<nz-select> </nz-select>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label> 仓库 </nz-form-label>
<nz-form-control>
<nz-select> </nz-select>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label> 所属公司 </nz-form-label>
<nz-form-control>
<nz-select> </nz-select>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label> 使用公司/部门 </nz-form-label>
<nz-form-control>
<nz-select> </nz-select>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label> 保管人 </nz-form-label>
<nz-form-control>
<nz-select> </nz-select>
</nz-form-control>
</nz-form-item>
</form>
</ng-template>
<ng-template #errorTpl let-control>
<form-error-tips [control]="control"></form-error-tips>
</ng-template>

0
web-admin-app/src/app/pages/fixed-asset/stocktaking/stockaking-job/stockaking-job.component.less

162
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<NzSafeAny>
@ViewChild('formContentTpl') formContentTpl!: TemplateRef<NzSafeAny>
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()
},
})
}
}

1
web-admin-app/src/app/pages/fixed-asset/stocktaking/stockaking-plan/stockaking-plan.component.html

@ -0,0 +1 @@
<p>stockaking-plan works!</p>

0
web-admin-app/src/app/pages/fixed-asset/stocktaking/stockaking-plan/stockaking-plan.component.less

21
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 {}

7
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;
}

9
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(['/'])
})
}

164
web-admin-app/src/app/pages/org-setting/org-setting.component.html

@ -1,40 +1,84 @@
<app-page class="p-3" [actions]="actionsTpl">
<ng-template #actionsTpl>
<nz-space>
<button *nzSpaceItem nz-button nzType="primary">新建</button>
<button
*nzSpaceItem
nz-button
nzType="primary"
[disabled]="organization?.organizationType !== '2'"
(click)="onCreate()"
>
新建
</button>
</nz-space>
</ng-template>
<div class="flex flex-1">
<nz-card [nzBordered]="false" class="org shadow" nzSize="small">
<app-component-org-tree />
<app-component-org-tree class="block w-60" (onOrgSelectedChange)="onOrgSelectedChange($event)" />
</nz-card>
<div class="flex-1 pl-3">
<app-server-paginated-table [options]="table">
<app-server-paginated-table [options]="table" [renderColumn]="renderColumnTpl" [formGroup]="queryForm">
<ng-template #renderColumnTpl let-data let-key="key" let-row="row">
@switch (key) {
@case ('avatar') {
@if (data) {
<nz-avatar [nzSrc]="data"></nz-avatar>
} @else {
<nz-avatar [nzText]="row.userName[0]" class="!bg-orange-400"></nz-avatar>
}
}
@case ('status') {
<nz-badge
[nzText]="data === 0 ? '在职' : '离职'"
[nzStatus]="data === 0 ? 'processing' : 'error'"
/>
}
@case ('sex') {
<nz-tag>
@switch (data) {
@case ('0') {
}
@case ('1') {
}
@default {
未知
}
}
</nz-tag>
}
@default {
{{ data }}
}
}
</ng-template>
<ng-container *appTableAction>
<nz-space>
<button *nzSpaceItem nz-button nzType="link">删除</button>
</nz-space>
</ng-container>
<ng-container *appTableForm>
<app-query-item label="工号">
<input nz-input placeholder="请输入" formControlName="name" />
<app-query-item label="账号名">
<input nz-input placeholder="请输入" formControlName="loginName" />
</app-query-item>
<app-query-item label="姓名">
<input nz-input placeholder="请输入" formControlName="name" />
<input nz-input placeholder="请输入" formControlName="userName" />
</app-query-item>
<app-query-item label="手机号">
<input nz-input placeholder="请输入" formControlName="name" />
<input nz-input placeholder="请输入" formControlName="phone" />
</app-query-item>
<app-query-item label="类型">
<app-query-item label="状态">
<nz-select
nzPlacement="bottomRight"
nzBorderless
class="!w-auto"
[nzDropdownMatchSelectWidth]="false"
formControlName="status"
nzAllowClear
>
<nz-option nzValue="123" nzLabel="前台员工"></nz-option>
<nz-option nzValue="22" nzLabel="后台员工"></nz-option>
<nz-option nzValue="221" nzLabel="临时员工"></nz-option>
<nz-option [nzValue]="0" nzLabel="在职"></nz-option>
<nz-option [nzValue]="1" nzLabel="离职"></nz-option>
</nz-select>
</app-query-item>
<app-query-item label="性别">
@ -43,17 +87,103 @@
nzBorderless
class="!w-auto"
[nzDropdownMatchSelectWidth]="false"
formControlName="sex"
nzAllowClear
>
<nz-option nzValue="123" nzLabel="男"></nz-option>
<nz-option nzValue="22" nzLabel="女"></nz-option>
<nz-option [nzValue]="0" nzLabel="男"></nz-option>
<nz-option [nzValue]="1" nzLabel="女"></nz-option>
<nz-option [nzValue]="2" nzLabel="未知"></nz-option>
</nz-select>
</app-query-item>
<!-- <app-query-item label="创建时间">
<app-date-query></app-date-query>
</app-query-item> -->
</ng-container>
</app-server-paginated-table>
</div>
</div>
</app-page>
<ng-template #drawerFooterTpl>
<nz-space>
<button *nzSpaceItem nz-button nzType="primary" (click)="onConfirm()">确定</button>
<button *nzSpaceItem nz-button nzType="default" (click)="onCancel()">取消</button>
</nz-space>
</ng-template>
<ng-template #formContentTpl>
<form nz-form nzLayout="vertical" [formGroup]="createForm">
<nz-form-item>
<nz-form-label nzRequired> 姓名 </nz-form-label>
<nz-form-control [nzErrorTip]="errorTpl">
<input type="text" nz-input formControlName="userName" placeholder="请输入姓名" />
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label nzRequired> 账号名 </nz-form-label>
<nz-form-control [nzErrorTip]="errorTpl">
<input type="text" nz-input formControlName="loginName" placeholder="请输入账号名" />
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label nzRequired> 联系电话 </nz-form-label>
<nz-form-control [nzErrorTip]="errorTpl">
<input type="text" nz-input formControlName="phone" placeholder="请输入联系电话" />
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label> 邮箱 </nz-form-label>
<nz-form-control [nzErrorTip]="errorTpl">
<input type="text" nz-input formControlName="email" placeholder="请输入邮箱" />
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label> 密码 </nz-form-label>
<nz-form-control [nzErrorTip]="errorTpl">
<input type="password" nz-input formControlName="password" placeholder="请输入密码" />
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label> 确认密码 </nz-form-label>
<nz-form-control [nzErrorTip]="errorTpl">
<input type="password" nz-input formControlName="repassword" placeholder="请输入密码" />
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label> 状态 </nz-form-label>
<nz-form-control [nzErrorTip]="errorTpl">
<nz-radio-group formControlName="status">
<label nz-radio nzValue="0"> 在职 </label>
<label nz-radio nzValue="1"> 离职 </label>
</nz-radio-group>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label> 头像 </nz-form-label>
<nz-form-control [nzErrorTip]="errorTpl">
<input type="hidden" nz-input formControlName="avatar" />
<div class="mb-2" *ngIf="iconPreview">
<img [src]="iconPreview" class="h-20 w-20" />
</div>
<button class="upload-btn" nz-button [nzLoading]="uploadLoading">
<i nz-icon nzType="upload"></i>
上传图片
<input type="file" (change)="onFileChange($event)" accept=".jpg,.jpeg,.png" />
</button>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label> 性别 </nz-form-label>
<nz-form-control [nzErrorTip]="errorTpl">
<nz-radio-group formControlName="sex">
<label nz-radio nzValue="0"></label>
<label nz-radio nzValue="1"></label>
<label nz-radio nzValue="2"> 未知 </label>
</nz-radio-group>
</nz-form-control>
</nz-form-item>
</form>
</ng-template>
<ng-template #errorTpl let-control>
<form-error-tips [control]="control"></form-error-tips>
</ng-template>

218
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<NzSafeAny>
@ViewChild('formContentTpl') formContentTpl!: TemplateRef<NzSafeAny>
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: '编辑', onClick: this.onCreate.bind(this) },
{ title: '删除', onClick: this.deleteItem.bind(this) },
])
.setRowOperate([{ title: '查看', premissions: [] }, { title: '编辑' }, { title: '删除' }])
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()
}
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',
},
],
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()
})
}
}
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)
})
}
}

34
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'
// })
// })
}
}
}

13
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(() => {})
})
}
}

12
web-admin-app/src/app/pages/profile/profile.component.html

@ -2,18 +2,10 @@
<nz-card [nzBordered]="false">
<nz-descriptions class="ml-16">
<nz-descriptions-item nzTitle="用户名">
{{ api.authInfo.username }}
{{ api.authInfo?.loginName }}
</nz-descriptions-item>
<nz-descriptions-item nzTitle="姓名">
{{ api.authInfo.name }}
</nz-descriptions-item>
<nz-descriptions-item nzTitle="状态">
@if (api.authInfo.enable) {
<nz-badge nzStatus="success" nzText="启用"></nz-badge>
} @else {
<nz-badge nzStatus="errot" nzText="禁用"></nz-badge>
}
{{ api.authInfo?.userName }}
</nz-descriptions-item>
</nz-descriptions>
</nz-card>

4
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 {}
}

1
web-admin-app/src/app/pages/system/system.component.html → web-admin-app/src/app/pages/system/index/system.component.html

@ -1 +1,2 @@
<div>ad</div>
<router-outlet />

0
web-admin-app/src/app/pages/system/index/system.component.less

0
web-admin-app/src/app/pages/system/system.component.ts → web-admin-app/src/app/pages/system/index/system.component.ts

1
web-admin-app/src/app/pages/system/system-user/system-user.component.html

@ -0,0 +1 @@
<p>system-user works!</p>

0
web-admin-app/src/app/pages/system/system-user/system-user.component.less

11
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 {}

16
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 }

272
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<JwResponse<AuthDTO>>('/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 ?? [])
}
login(data: {}) {
return this.http.post<JwResponse>('/api/oauth/login', data)
} catch (error) {}
return authInfo
}
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,
}
})
removeAuthData() {
localStorage.removeItem(this.AUTH_KEY_NAME)
}
changeUserPassword(id: string, password: string) {
return this.http.put('/api/user/reset/password', {
id,
password,
})
upload(data: FormData) {
return this.http.post<JwResponse>('/api/common/upload', data)
}
getDashboardCounter() {
return this.http.get<JwResponse<ConsoleCountDTO>>(`/api/console/count`)
login(data: {}) {
return this.http.post<JwResponse>('/api/oauth/login', data).pipe(
tap((res) => {
localStorage.setItem(this.AUTH_KEY_NAME, JSON.stringify(res.body))
}),
)
}
getDashboardExpire() {
return this.http.get<JwResponse<ConsoleExpireDTO[]>>(`/api/console/expire`)
logout() {
return this.http.post<JwResponse>('/api/oauth/logout', null)
}
getDashboardClientTop() {
return this.http.get<JwResponse<ConsoleClientTopDTO[]>>(`/api/console/client/top`)
getOrgTree() {
return this.http.post<JwResponse>('/api/umsOrganization/tree', null)
}
getUserInfo(id: string) {
return this.http.get<JwResponse<UserDTO>>(`/api/user/${id}`).pipe()
saveOrg(data: NzSafeAny) {
if (Utils.isEmpty(data.organizationId)) {
return this.http.post<JwResponse>('/api/umsOrganization/add', data)
}
changePassword(data: {}) {
return this.http.put<JwResponse>('/api/user/password', data)
return this.http.post<JwResponse>('/api/umsOrganization/update', data)
}
getUserPage(p: {}, q: {}) {
const params = Utils.objectToURLSearchParams({ ...p, ...q })
return this.http.get<JwResponse>(`/api/user/pages?${params}`)
deleteOrg(id: number) {
return this.http.post<JwResponse>('/api/umsOrganization/delete', [id])
}
saveUser(user: any) {
if (user.id) {
return this.http.put<JwResponse>('/api/user', user)
} else {
return this.http.post<JwResponse>('/api/user', user)
}
getUserPage(data: {}) {
return this.http.post<JwResponse>('/api/umsUser/list', data)
}
deleteUser(id: string) {
return this.http.delete<JwResponse>(`/api/user/${id}`)
deleteUser(ids: number[]) {
return this.http.post<JwResponse>(`/api/umsUser/delete`, ids)
}
getUserGroupTree() {
return this.http.get<JwResponse<any[]>>('/api/user/group/tree').pipe(
map((res) => {
return this._parseUserGroupTree(res.data)
}),
)
saveUser(data: NzSafeAny) {
if (Utils.isEmpty(data.userId)) {
return this.http.post<JwResponse>('/api/umsUser/add', data)
}
return this.http.post<JwResponse>('/api/umsUser/update', data)
}
saveUserGroup(group: Partial<UserGroupTreeItem>) {
if (group.id) {
return this.http.put<JwResponse>('/api/user/group', group)
} else {
return this.http.post<JwResponse>('/api/user/group', group)
getBasicPositionPage(data: {}) {
return this.http.post<JwResponse>('/api/eamBasicPosition/list', data)
}
saveBasicPosition(data: NzSafeAny) {
if (Utils.isEmpty(data.positionId)) {
return this.http.post<JwResponse>('/api/eamBasicPosition/add', data)
}
updateUserStatus(id: string) {
return this.http.put<JwResponse>(`/api/user/enable/${id}`, null)
return this.http.post<JwResponse>('/api/eamBasicPosition/update', data)
}
deleteUserGroup(id: string) {
return this.http.delete<JwResponse>(`/api/user/group/${id}`)
deleteBasicPosition(ids: number[]) {
return this.http.post<JwResponse>(`/api/eamBasicPosition/delete`, ids)
}
getAllRole() {
return this.http.get<JwResponse<RoleListDTO[]>>(`/api/sysRole/list`)
getBasicMaintenanceVendorPage(data: {}) {
return this.http.post<JwResponse>('/api/eamBasicMaintenanceVendor/list', data)
}
getRolePage(p: {}, q: {}) {
const params = Utils.objectToURLSearchParams({ ...p, ...q })
return this.http.get<JwResponse>(`/api/sysRole/pages?${params}`)
saveBasicMaintenanceVendor(data: NzSafeAny) {
if (Utils.isEmpty(data.maintenanceVendorId)) {
return this.http.post<JwResponse>('/api/eamBasicMaintenanceVendor/add', data)
}
getAllPermission() {
return this.http.get<JwResponse<PermissionDTO[]>>('/api/authority/tree')
return this.http.post<JwResponse>('/api/eamBasicMaintenanceVendor/update', data)
}
getRoleById(id: string) {
return this.http.get<JwResponse<RoleFormDTO>>(`/api/sysRole/${id}`)
deleteBasicMaintenanceVendor(ids: number[]) {
return this.http.post<JwResponse>(`/api/eamBasicMaintenanceVendor/delete`, ids)
}
deleteRole(id: string) {
return this.http.delete<JwResponse>(`/api/sysRole/${id}`)
getBasicManufacturersVendorPage(data: {}) {
return this.http.post<JwResponse>('/api/eamBasicManufacturersVendor/list', data)
}
saveRole(role: NullableProps<RoleFormDTO>) {
if (role.id) {
return this.http.put<JwResponse>('/api/sysRole', role)
} else {
return this.http.post<JwResponse>('/api/sysRole', role)
saveBasicManufacturersVendor(data: NzSafeAny) {
if (Utils.isEmpty(data.manufacturersVendorId)) {
return this.http.post<JwResponse>('/api/eamBasicManufacturersVendor/add', data)
}
return this.http.post<JwResponse>('/api/eamBasicManufacturersVendor/update', data)
}
authorize(v: {}) {
return this.http.post<JwResponse>('/api/client/license', v)
deleteBasicManufacturersVendor(ids: number[]) {
return this.http.post<JwResponse>(`/api/eamBasicManufacturersVendor/delete`, ids)
}
getSysLog(p: {}, q: {}) {
const params = Utils.objectToURLSearchParams({ ...p, ...q })
return this.http.get<JwResponse>(`/api/sysLog/pages?${params}`)
getBasicSupplierVendorPage(data: {}) {
return this.http.post<JwResponse>('/api/eamBasicSupplierVendor/list', data)
}
getEntityPage(p: {}, q: {}) {
const params = Utils.objectToURLSearchParams({ ...p, ...q })
return this.http.get<JwResponse>(`/api/client/pages?${params}`)
saveBasicSupplierVendor(data: NzSafeAny) {
if (Utils.isEmpty(data.supplierVendorId)) {
return this.http.post<JwResponse>('/api/eamBasicSupplierVendor/add', data)
}
getEntityAuthorizeList(clientId: string) {
return this.http.get<JwResponse<AuthorizeItemDTO[]>>(`/api/licenseLog/${clientId}/list`)
return this.http.post<JwResponse>('/api/eamBasicSupplierVendor/update', data)
}
getEntityDetail(id: string) {
return this.http.get<JwResponse<EntityDetailDTO>>(`/api/client/${id}`)
deleteBasicSupplierVendor(ids: number[]) {
return this.http.post<JwResponse>(`/api/eamBasicSupplierVendor/delete`, ids)
}
saveEntity(entity: Partial<NullableProps<EntityDTO>>) {
if (entity.id) {
return this.http.put<JwResponse>('/api/client', entity)
} else {
return this.http.post<JwResponse>('/api/client', entity)
getBasicWarehousePage(data: {}) {
return this.http.post<JwResponse>('/api/eamBasicWarehouse/list', data)
}
saveBasicWarehouse(data: NzSafeAny) {
if (Utils.isEmpty(data.warehouseId)) {
return this.http.post<JwResponse>('/api/eamBasicWarehouse/add', data)
}
deleteEntity(id: string) {
return this.http.delete<JwResponse>(`/api/client/${id}`)
return this.http.post<JwResponse>('/api/eamBasicWarehouse/update', data)
}
getProductPage(p: {}, q: {}) {
const params = Utils.objectToURLSearchParams({ ...p, ...q })
return this.http.get<JwResponse>(`/api/product/pages?${params}`)
deleteBasicWarehouse(ids: number[]) {
return this.http.post<JwResponse>(`/api/eamBasicWarehouse/delete`, ids)
}
getAllProduct() {
return this.http.get<JwResponse<{ id: string; name: string }[]>>(`/api/product/list`)
getBasicCategoryTree() {
return this.http.post<JwResponse>('/api/eamBasicCategory/tree', null)
}
saveProduct(entity: Partial<NullableProps<ProductDTO>>) {
if (entity.id) {
return this.http.put<JwResponse>('/api/product', entity)
} else {
return this.http.post<JwResponse>('/api/product', entity)
addBasicCategoryTree(data: {}) {
return this.http.post<JwResponse>('/api/eamBasicCategory/add', data)
}
updateBasicCategoryTree(data: {}) {
return this.http.post<JwResponse>('/api/eamBasicCategory/update', data)
}
deleteProduct(id: string) {
return this.http.delete<JwResponse>(`/api/product/${id}`)
deleteBasicCategory(ids: number[]) {
return this.http.post<JwResponse>('/api/eamBasicCategory/delete', ids)
}
getProductVersionPage(p: {}, q: {}) {
const params = Utils.objectToURLSearchParams({ ...p, ...q })
return this.http.get<JwResponse>(`/api/product/pages?${params}`)
getStocktakingJobPage(data: {}) {
return this.http.post<JwResponse>('/api/eamStocktakingJob/list', data)
}
saveVersion(entity: Partial<NullableProps<ProductDTO>>) {
if (entity.id) {
return this.http.put<JwResponse>('/api/product', entity)
} else {
return this.http.post<JwResponse>('/api/product', entity)
saveStocktakingJob(data: NzSafeAny) {
if (Utils.isEmpty(data.stocktakingJobId)) {
return this.http.post<JwResponse>('/api/eamStocktakingJob/add', data)
}
return this.http.post<JwResponse>('/api/eamStocktakingJob/update', data)
}
deleteStocktakingJob(ids: number[]) {
return this.http.post<JwResponse>(`/api/eamStocktakingJob/delete`, ids)
}
deleteVersion(id: string, pid: string) {
return this.http.delete<JwResponse>(`/api/product/${id}`)
beginStocktakingJob(ids: number[]) {
return this.http.post<JwResponse>(`/api/eamStocktakingJob/start`, ids)
}
stopStocktakingJob(ids: number[]) {
return this.http.post<JwResponse>(`/api/eamStocktakingJob/complete`, ids)
}
/**
*
*
* -------------------------------
*
*
*/
getProductDetail(pid: string) {
return this.http.get<JwResponse>(`/api/product/${pid}`)
getEntityPage(p: {}, q: {}) {
const params = Utils.objectToURLSearchParams({ ...p, ...q })
return this.http.get<JwResponse>(`/api/client/pages?${params}`)
}
}

60
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<string, any>, 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<string, any>) {
localStorage.setItem(this.tokenName, JSON.stringify(accessData))
}
removeAccess() {
localStorage.removeItem(this.tokenName)
}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
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<string, string> = token ? { Authorization: `Bearer ${token}` } : {}
const Authorization: Record<string, string> = 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
}
}

0
web-admin-app/src/app/components/app-page/app-page.component.html → web-admin-app/src/app/shared/components/app-page/app-page.component.html

0
web-admin-app/src/app/components/app-page/app-page.component.less → web-admin-app/src/app/shared/components/app-page/app-page.component.less

2
web-admin-app/src/app/components/app-page/app-page.component.ts → 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',
})

0
web-admin-app/src/app/components/form-error-tips/form-error-tips.component.html → web-admin-app/src/app/shared/components/form-error-tips/form-error-tips.component.html

0
web-admin-app/src/app/shared/components/form-error-tips/form-error-tips.component.less

0
web-admin-app/src/app/components/form-error-tips/form-error-tips.component.ts → web-admin-app/src/app/shared/components/form-error-tips/form-error-tips.component.ts

2
web-admin-app/src/app/components/header/header.component.html → web-admin-app/src/app/shared/components/header/header.component.html

@ -66,7 +66,7 @@
<a nz-button nzType="text" nz-dropdown [nzDropdownMenu]="menu">
<nz-avatar nzSrc="/assets/images/avatar4.png" />
<span class="ml-2">
{{ api.authInfo.name || 'admin' }}
{{ api.authInfo?.userName ?? '-' }}
</span>
<span nz-icon nzType="down"></span>
</a>

0
web-admin-app/src/app/components/header/header.component.less → web-admin-app/src/app/shared/components/header/header.component.less

10
web-admin-app/src/app/components/header/header.component.ts → 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('退出成功')
},

6
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'

0
web-admin-app/src/app/components/layout/layout.component.html → web-admin-app/src/app/shared/components/layout/layout.component.html

15
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;
// }
// }
// }

8
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 {}

0
web-admin-app/src/app/components/range-picker/range-picker.component.html → web-admin-app/src/app/shared/components/range-picker/range-picker.component.html

0
web-admin-app/src/app/shared/components/range-picker/range-picker.component.less

0
web-admin-app/src/app/components/range-picker/range-picker.component.ts → web-admin-app/src/app/shared/components/range-picker/range-picker.component.ts

0
web-admin-app/src/app/components/server-paginated-table/date-query/date-query.component.html → web-admin-app/src/app/shared/components/server-paginated-table/date-query/date-query.component.html

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save