diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..55af8e5 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +version 2 \ No newline at end of file diff --git a/web-admin-app/README.md b/web-admin-app/README.md index 113013a..0c7d82b 100644 --- a/web-admin-app/README.md +++ b/web-admin-app/README.md @@ -85,4 +85,11 @@ - ~~盘点计划 状态 启用/禁用 #~~ - ~~归还 #~~ - ~~库存 列表字段 / 仓库、分类字段~~ -- ~~ 我处理 不要作废 ~~ \ No newline at end of file +- ~~ 我处理 不要作废 ~~ + + +# v2 + +## 10-10 + +- \ No newline at end of file diff --git a/web-admin-app/proxy/devserver.js b/web-admin-app/proxy/devserver.js index 512dd5f..cabcc03 100644 --- a/web-admin-app/proxy/devserver.js +++ b/web-admin-app/proxy/devserver.js @@ -1,6 +1,6 @@ // const remoteTarget = "http://10.168.1.60:8300"; -const remoteTarget = 'http://47.109.27.8:8280/' -const localTarget = 'http://47.109.27.8:8280/' +const remoteTarget = 'http://47.109.27.8:8282/' +const localTarget = 'http://47.109.27.8:8282/' const devProxy = (remote) => { let config = {} diff --git a/web-admin-app/src/app/app.config.ts b/web-admin-app/src/app/app.config.ts index 05d75d1..84d5189 100644 --- a/web-admin-app/src/app/app.config.ts +++ b/web-admin-app/src/app/app.config.ts @@ -26,7 +26,7 @@ const disabledLog = () => { } } -disabledLog() +// disabledLog() export function initializeApp(configService: ServerPaginatedTableService) { return () => { diff --git a/web-admin-app/src/app/app.routes.ts b/web-admin-app/src/app/app.routes.ts index a2a738a..cb55822 100644 --- a/web-admin-app/src/app/app.routes.ts +++ b/web-admin-app/src/app/app.routes.ts @@ -62,6 +62,24 @@ import { FixedAssetStorageComponent } from './pages/fixed-asset/ledger/fixed-ass import { HomeComponent } from './pages/home/home.component' import { LicensePageComponent } from './pages/license/license.component' import { SystemLicenseComponent } from './pages/system/license/license.component' +import { RegistrationComponent } from './pages/fixed-asset/registration/registration.component' +import { SystemWarehouseComponent } from './pages/system/system-warehouse/system-warehouse.component' +import { SystemAddressComponent } from './pages/system/system-address/system-address.component' +import { BasicFlowFormComponent } from './pages/fixed-asset/basic/basic-flow-form/basic-flow-form.component' +import { BasicFlowFormManageComponent } from './pages/fixed-asset/basic/basic-flow-form-manage/basic-flow-form-manage.component' +import { MaintainRecordComponent } from './pages/fixed-asset/maintain/maintain-record/maintain-record.component' +import { MaintainOnOffComponent } from './pages/fixed-asset/maintain/maintain-on-off/maintain-on-off.component' +import { AssetManagementComponent } from './pages/fixed-asset/asset-management/asset-management.component' +import { AssetUserGroupComponent } from './pages/fixed-asset/basic/asset-user-group/asset-user-group.component' +import { InspectionPlanComponent } from './pages/fixed-asset/plan-task/inspection-plan/inspection-plan.component' +import { InspectionTaskComponent } from './pages/fixed-asset/plan-task/inspection-task/inspection-task.component' +import { InspectionCalendarComponent } from './pages/fixed-asset/plan-task/inspection-calendar/inspection-calendar.component' +import { MaintenanceTaskComponent } from './pages/fixed-asset/plan-task/maintenance-task/maintenance-task.component' +import { MaintenanceCalendarComponent } from './pages/fixed-asset/plan-task/maintenance-calendar/maintenance-calendar.component' +import { MaintenancePlanComponent } from './pages/fixed-asset/plan-task/maintenance-plan/maintenance-plan.component' +import { StocktakingPlanComponent } from './pages/fixed-asset/plan-task/stocktaking-plan/stocktaking-plan.component' +import { StocktakingTaskComponent } from './pages/fixed-asset/plan-task/stocktaking-task/stocktaking-task.component' +import { StocktakingCalendarComponent } from './pages/fixed-asset/plan-task/stocktaking-calendar/stocktaking-calendar.component' export const routes: Routes = [ { @@ -172,6 +190,27 @@ export const routes: Routes = [ }, }, }, + { + path: 'place', + title: '场所地址', + children: [ + { + path: '', + redirectTo: 'warehouse', + pathMatch: 'full', + }, + { + path: 'warehouse', + title: '仓库管理', + component: SystemWarehouseComponent, + }, + { + path: 'address', + title: '地址管理', + component: SystemAddressComponent, + }, + ], + }, { path: 'flow', canActivate: [permissionGuard], @@ -311,6 +350,16 @@ export const routes: Routes = [ }, ], }, + { + path: 'registration', + component: RegistrationComponent, + title: '资产登记', + }, + { + path: 'management', + component: AssetManagementComponent, + title: '资产管理', + }, { path: 'repair', title: '维护维保', @@ -389,6 +438,27 @@ export const routes: Routes = [ }, ], }, + { + path: 'maintain', + title: '运维管理', + children: [ + { + path: '', + pathMatch: 'full', + redirectTo: 'record', + }, + { + path: 'record', + component: MaintainRecordComponent, + title: '维修登记', + }, + { + path: 'on-off', + title: '开关机', + component: MaintainOnOffComponent, + }, + ], + }, { path: 'basic', title: '基础数据', @@ -396,7 +466,26 @@ export const routes: Routes = [ { path: '', pathMatch: 'full', - redirectTo: 'goods-stock', + redirectTo: 'category', + }, + { + path: 'flow-form', + title: '流程表单', + children: [ + { + path: '', + pathMatch: 'full', + redirectTo: 'list', + }, + { + path: 'list', + component: BasicFlowFormComponent, + }, + { + path: 'manage/:id', + component: BasicFlowFormManageComponent, + }, + ], }, { path: 'repair-type', @@ -411,7 +500,7 @@ export const routes: Routes = [ { path: 'category', component: BasicCategoryComponent, - title: '物品分类', + title: '资产分类', }, { path: 'save-position', @@ -438,6 +527,63 @@ export const routes: Routes = [ component: BasicWarehouseComponent, title: '存放仓库', }, + { + path: 'team', + component: AssetUserGroupComponent, + title: '班组管理', + }, + ], + }, + { + path: 'inspection', + title: '巡检管理', + children: [ + { + path: '', + pathMatch: 'full', + redirectTo: 'plan', + }, + { + title: '巡检计划', + path: 'plan', + component: InspectionPlanComponent, + }, + { + title: '巡检任务', + path: 'task', + component: InspectionTaskComponent, + }, + { + title: '巡检日历', + path: 'calendar', + component: InspectionCalendarComponent, + }, + ], + }, + { + path: 'maintenance', + title: '保养管理', + children: [ + { + path: '', + pathMatch: 'full', + redirectTo: 'plan', + }, + { + title: '保养计划', + path: 'plan', + component: MaintenancePlanComponent, + }, + { + title: '保养任务', + path: 'task', + component: MaintenanceTaskComponent, + }, + { + title: '保养日历', + path: 'calendar', + component: MaintenanceCalendarComponent, + }, ], }, { @@ -447,41 +593,67 @@ export const routes: Routes = [ { path: '', pathMatch: 'full', - redirectTo: 'job', + redirectTo: 'plan', }, { - path: 'job', - - title: '盘点任务', - children: [ - { - path: '', - pathMatch: 'full', - redirectTo: 'list', - }, - { - path: 'list', - component: StockakingJobComponent, - }, - { - path: 'detail/:id', - title: '盘点明细', - component: StocktakingDetailComponent, - }, - ], + title: '盘点计划', + path: 'plan', + component: StocktakingPlanComponent, }, { - path: 'job', - component: StockakingJobComponent, title: '盘点任务', + path: 'task', + component: StocktakingTaskComponent, }, { - path: 'plan', - component: StockakingPlanComponent, - title: '盘点计划', + title: '盘点日历', + path: 'calendar', + component: StocktakingCalendarComponent, }, ], }, + // { + // path: 'stocktaking', + // title: '盘点管理', + // children: [ + // { + // path: '', + // pathMatch: 'full', + // redirectTo: 'job', + // }, + // { + // path: 'job', + + // title: '盘点任务', + // children: [ + // { + // path: '', + // pathMatch: 'full', + // redirectTo: 'list', + // }, + // { + // path: 'list', + // component: StockakingJobComponent, + // }, + // { + // path: 'detail/:id', + // title: '盘点明细', + // component: StocktakingDetailComponent, + // }, + // ], + // }, + // { + // path: 'job', + // component: StockakingJobComponent, + // title: '盘点任务', + // }, + // { + // path: 'plan', + // component: StockakingPlanComponent, + // title: '盘点计划', + // }, + // ], + // }, { path: 'alert', title: '预警中心', diff --git a/web-admin-app/src/app/components/asset-basic-team-form/asset-basic-team-form.component.html b/web-admin-app/src/app/components/asset-basic-team-form/asset-basic-team-form.component.html new file mode 100644 index 0000000..12c4240 --- /dev/null +++ b/web-admin-app/src/app/components/asset-basic-team-form/asset-basic-team-form.component.html @@ -0,0 +1,44 @@ + diff --git a/web-admin-app/src/app/components/asset-basic-team-form/asset-basic-team-form.component.less b/web-admin-app/src/app/components/asset-basic-team-form/asset-basic-team-form.component.less new file mode 100644 index 0000000..e69de29 diff --git a/web-admin-app/src/app/components/asset-basic-team-form/asset-basic-team-form.component.ts b/web-admin-app/src/app/components/asset-basic-team-form/asset-basic-team-form.component.ts new file mode 100644 index 0000000..01c5a41 --- /dev/null +++ b/web-admin-app/src/app/components/asset-basic-team-form/asset-basic-team-form.component.ts @@ -0,0 +1,92 @@ +import { Component, Input, OnInit, inject } from '@angular/core' +import { FormBuilder, FormGroup } from '@angular/forms' +import { ApiService } from 'app/services' +import { SharedModule } from 'app/shared/shared.module' +import { FormValidators, Utils } from 'app/utils' +import { NzMessageService } from 'ng-zorro-antd/message' +import { OrgSelectComponent } from '../org-select/org-select.component' +import { SelectUserByOrgComponent } from '../select-user-by-org/select-user-by-org.component' +import { PositionSelectComponent } from '../position-select/position-select.component' +import { NzSafeAny } from 'ng-zorro-antd/core/types' +import { NZ_MODAL_DATA } from 'ng-zorro-antd/modal' +import { SupplierSelectComponent } from '../supplier-select/supplier-select.component' +import { AssetSelectComponent } from '../asset-select/asset-select.component' +import { WarehouseSelectComponent } from '../warehouse-select/warehouse-select.component' + +@Component({ + selector: 'app-asset-basic-team-form', + standalone: true, + imports: [ + SharedModule, + SelectUserByOrgComponent, + SupplierSelectComponent, + AssetSelectComponent, + OrgSelectComponent, + PositionSelectComponent, + WarehouseSelectComponent, + ], + templateUrl: './asset-basic-team-form.component.html', + styleUrl: './asset-basic-team-form.component.less', +}) +export class AssetBasicTeamFormComponent { + constructor( + private fb: FormBuilder, + private api: ApiService, + private msg: NzMessageService, + ) {} + + readonly data: NzSafeAny = inject(NZ_MODAL_DATA) + + formGroup!: FormGroup + + groupIndex = 0 + + uploadLoading = false + + ngOnInit(): void { + this.formGroup = this.fb.group({ + teamId: this.fb.control(null, []), + teamName: this.fb.control('', [FormValidators.required('请输入')]), + teamKey: this.fb.control('', [FormValidators.required('请输入')]), + // useUserId: this.fb.control(null, [FormValidators.required('请选择')]), + // useOrganizationId: this.fb.control(null, [FormValidators.required('请选择')]), + status: this.fb.control(1, [FormValidators.required('请选择')]), + + _value: this.fb.control([], [FormValidators.required('请选择')]), + remark: this.fb.control(null, []), + }) + + this.patchValues() + } + + patchValues() { + const { value: data, preview } = this.data + if (data) { + this.formGroup.patchValue({ + ...data, + _value: data?._value?.map((i: NzSafeAny) => i.userId), + }) + } + if (preview) { + this.formGroup.disable() + } + } + + public getValues() { + let values = null + if (FormValidators.validateFormGroup(this.formGroup)) { + const v = this.formGroup.value + + values = { + ...v, + _value: this.selectedUser, + } + } + return values + } + + selectedUser = [] + onUerChange(e: any) { + this.selectedUser = e + } +} diff --git a/web-admin-app/src/app/components/asset-form/asset-form.component.html b/web-admin-app/src/app/components/asset-form/asset-form.component.html index 92eb724..2196318 100644 --- a/web-admin-app/src/app/components/asset-form/asset-form.component.html +++ b/web-admin-app/src/app/components/asset-form/asset-form.component.html @@ -30,11 +30,35 @@ }
+ +
资产分类 - +
@@ -163,6 +187,60 @@
+
+ @if (extraFields.length > 0) { +
扩展信息
+
+ @for (item of extraFields; track item.key) { +
+ + {{ item.name }} + + @switch (item.type) { + @case ('DATE') { + + } + @case ('RADIO') { + + + + + + } + @case ('NUMBER') { + + } + @default { + + } + } + + +
+ } +
+ } +
diff --git a/web-admin-app/src/app/components/asset-form/asset-form.component.ts b/web-admin-app/src/app/components/asset-form/asset-form.component.ts index e69b4bf..f87b24b 100644 --- a/web-admin-app/src/app/components/asset-form/asset-form.component.ts +++ b/web-admin-app/src/app/components/asset-form/asset-form.component.ts @@ -1,5 +1,5 @@ -import { Component, Input, OnInit, inject } from '@angular/core' -import { FormBuilder, FormGroup } from '@angular/forms' +import { Component, Input, OnInit, ViewChild, inject } from '@angular/core' +import { FormArray, FormBuilder, FormGroup } from '@angular/forms' import { ApiService } from 'app/services' import { SharedModule } from 'app/shared/shared.module' import { FormValidators, Utils } from 'app/utils' @@ -40,6 +40,8 @@ export class AssetFormComponent implements OnInit { private msg: NzMessageService, ) {} + @ViewChild('assetCategorySelect') assetCategorySelect!: AssetCategorySelectComponent + readonly data: NzSafeAny = inject(NZ_MODAL_DATA) formGroup!: FormGroup @@ -56,13 +58,22 @@ export class AssetFormComponent implements OnInit { financialCategory: NzSafeAny[] = [] + flowForms: NzSafeAny[] = [] + + extraFields: NzSafeAny[] = [] ngOnInit(): void { + // this.api.getFlowFormList().subscribe((res) => { + // this.flowForms = res.body + // }) this.formGroup = this.fb.group({ assetId: this.fb.control(null, []), name: this.fb.control('', [FormValidators.required('请输入')]), categoryId: this.fb.control(null, [FormValidators.required('请选择')]), ownCompanyId: this.fb.control(null, [FormValidators.required('请选择')]), status: this.fb.control(null, [FormValidators.required('请选择')]), + + // flowForm: this.fb.control(null, [FormValidators.required('请选择')]), + sourceId: this.fb.control(null, []), unit: this.fb.control(null, []), positionId: this.fb.control(null, []), @@ -96,6 +107,8 @@ export class AssetFormComponent implements OnInit { taxAmountRate: this.fb.control(null, []), totalAmountPrice: this.fb.control(null, []), registerDate: this.fb.control(null, []), + + _extInfo: this.fb.array([]), }) this.patchValues() @@ -105,10 +118,52 @@ export class AssetFormComponent implements OnInit { }) } + get extInfo(): FormArray { + return this.formGroup.get('_extInfo') as FormArray + } + + onExtraChange(v: any) { + let extraFields: NzSafeAny[] = [] + try { + const formValue = this.assetCategorySelect.originTreeData.find((f) => f.categoryId === Number(v)) + ?._assetExtTemp + extraFields = formValue ?? [] + } catch (error) {} + + this.setExtraFields(extraFields) + } + + ext = null + setExtraFields(fields: NzSafeAny[]) { + this.extInfo.clear() + this.extraFields = fields + .sort((a, b) => a.sort - b.sort) + .map((i) => { + let val = i.value + if (i.type === 'RADIO') { + val = i.value?.value + } else if (i.type === 'DATE') { + val = new Date(i.value) + } + + this.extInfo.push( + this.fb.group({ + key: this.fb.control(i.key), + name: this.fb.control(i.name), + remark: this.fb.control(i.remark), + sort: this.fb.control(i.sort), + type: this.fb.control(i.type), + value: this.fb.control(val), + fields: this.fb.control(i.type === 'RADIO' ? i.value?.fields : []), + }), + ) + return i + }) + } + patchValues() { const { value: data, preview } = this.data if (data) { - console.log('data', data) this.formGroup.patchValue({ ...data, useUserId: data._useUser?.userId ? [data._useUser?.userId] : [], @@ -123,6 +178,7 @@ export class AssetFormComponent implements OnInit { maintenanceVendor: data._maintenanceVendor?.maintenanceVendorId, manufacturersVendorId: data._manufacturersVendor?.manufacturersVendorId, }) + this.setExtraFields(data._extInfo) } if (preview) { this.formGroup.disable() @@ -133,7 +189,7 @@ export class AssetFormComponent implements OnInit { let values = null if (FormValidators.validateFormGroup(this.formGroup)) { const v = this.formGroup.getRawValue() - console.log('v', v) + values = { ...v, useUserId: v.useUserId?.[0], @@ -143,6 +199,18 @@ export class AssetFormComponent implements OnInit { positionId: v.positionId, useOrganizationId: v.useOrganizationId, responsiblePerson: v.responsiblePerson?.[0], + _extInfo: this.extInfo.value.map((v: any) => { + if (v.type === 'RADIO') { + return { + ...v, + value: { + value: v.value, + fields: v.fields.map((i: string) => i), + }, + } + } + return v + }), } } return values diff --git a/web-admin-app/src/app/components/component-basic-category-tree/component-basic-category-tree.component.ts b/web-admin-app/src/app/components/component-basic-category-tree/component-basic-category-tree.component.ts index be46009..ff465ca 100644 --- a/web-admin-app/src/app/components/component-basic-category-tree/component-basic-category-tree.component.ts +++ b/web-admin-app/src/app/components/component-basic-category-tree/component-basic-category-tree.component.ts @@ -1,13 +1,17 @@ +import { CommonModule } from '@angular/common' import { Component, EventEmitter, Input, OnInit, Output, TemplateRef } from '@angular/core' -import { FormBuilder, FormGroup } from '@angular/forms' +import { FormBuilder, FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms' import { ApiService } from 'app/services' import { SharedModule } from 'app/shared/shared.module' import { FormValidators } from 'app/utils' +import { NzButtonModule } from 'ng-zorro-antd/button' import { NzSafeAny } from 'ng-zorro-antd/core/types' import { NzDrawerRef, NzDrawerService } from 'ng-zorro-antd/drawer' +import { NzDropDownModule } from 'ng-zorro-antd/dropdown' +import { NzInputModule } from 'ng-zorro-antd/input' import { NzMessageService } from 'ng-zorro-antd/message' import { NzModalService } from 'ng-zorro-antd/modal' -import { NzFormatEmitEvent, NzTreeNodeOptions } from 'ng-zorro-antd/tree' +import { NzFormatEmitEvent, NzTreeModule, NzTreeNodeOptions } from 'ng-zorro-antd/tree' interface CateGoryInterface { categoryId: number @@ -54,7 +58,15 @@ export function buildCateTree(organizations: CateGoryInterface[]): NzTreeNodeOpt @Component({ selector: 'app-component-basic-category-tree', standalone: true, - imports: [SharedModule], + imports: [ + NzDropDownModule, + NzTreeModule, + NzInputModule, + CommonModule, + FormsModule, + ReactiveFormsModule, + NzButtonModule, + ], templateUrl: './component-basic-category-tree.component.html', styleUrl: './component-basic-category-tree.component.less', }) @@ -131,7 +143,6 @@ export class ComponentBasicCategoryTreeComponent { .subscribe((res) => { this.expandedKeys.push(String(parentId)) this.initTree() - this.msg.success(res.desc) }) } diff --git a/web-admin-app/src/app/components/flow-form-create/flow-form-create.component.html b/web-admin-app/src/app/components/flow-form-create/flow-form-create.component.html new file mode 100644 index 0000000..3ef3125 --- /dev/null +++ b/web-admin-app/src/app/components/flow-form-create/flow-form-create.component.html @@ -0,0 +1 @@ +

flow-form-create works!

diff --git a/web-admin-app/src/app/components/flow-form-create/flow-form-create.component.less b/web-admin-app/src/app/components/flow-form-create/flow-form-create.component.less new file mode 100644 index 0000000..e69de29 diff --git a/web-admin-app/src/app/components/flow-form-create/flow-form-create.component.ts b/web-admin-app/src/app/components/flow-form-create/flow-form-create.component.ts new file mode 100644 index 0000000..9b26c9a --- /dev/null +++ b/web-admin-app/src/app/components/flow-form-create/flow-form-create.component.ts @@ -0,0 +1,12 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-flow-form-create', + standalone: true, + imports: [], + templateUrl: './flow-form-create.component.html', + styleUrl: './flow-form-create.component.less' +}) +export class FlowFormCreateComponent { + +} diff --git a/web-admin-app/src/app/components/index.ts b/web-admin-app/src/app/components/index.ts index 2591bf1..64e445d 100644 --- a/web-admin-app/src/app/components/index.ts +++ b/web-admin-app/src/app/components/index.ts @@ -38,3 +38,6 @@ export * from './apply-asset-flow/eam-asset-purchase-apply/eam-asset-purchase-ap export * from './apply-asset-flow/eam-asset-employee-handover/eam-asset-employee-handover.component' export * from './apply-asset-flow/eam-asset-equipment-repair/eam-asset-equipment-repair.component' export * from './apply-asset-flow/eam-asset-stock-goods-use/eam-asset-stock-goods-use.component' + +export * from './status-tag/status-tag.component' +export * from './flow-form-create/flow-form-create.component' diff --git a/web-admin-app/src/app/components/maintain-record-form/maintain-record-form.component.html b/web-admin-app/src/app/components/maintain-record-form/maintain-record-form.component.html new file mode 100644 index 0000000..3bb7ce7 --- /dev/null +++ b/web-admin-app/src/app/components/maintain-record-form/maintain-record-form.component.html @@ -0,0 +1,84 @@ + diff --git a/web-admin-app/src/app/components/maintain-record-form/maintain-record-form.component.less b/web-admin-app/src/app/components/maintain-record-form/maintain-record-form.component.less new file mode 100644 index 0000000..e69de29 diff --git a/web-admin-app/src/app/components/maintain-record-form/maintain-record-form.component.ts b/web-admin-app/src/app/components/maintain-record-form/maintain-record-form.component.ts new file mode 100644 index 0000000..83764d7 --- /dev/null +++ b/web-admin-app/src/app/components/maintain-record-form/maintain-record-form.component.ts @@ -0,0 +1,117 @@ +import { Component, Input, OnInit, inject } from '@angular/core' +import { FormBuilder, FormGroup } from '@angular/forms' +import { ApiService } from 'app/services' +import { SharedModule } from 'app/shared/shared.module' +import { FormValidators, Utils } from 'app/utils' +import { NzMessageService } from 'ng-zorro-antd/message' +import { AssetCategorySelectComponent } from '../asset-category-select/asset-category-select.component' +import { OrgSelectComponent } from '../org-select/org-select.component' +import { ASSET_SOURCE_MAP, ASSET_STATUS, MAINTENANCE_STATUS, MAINTENANCE_TYPE, MAX_PAGE_SIZE } from 'app/constants' +import { SelectUserByOrgComponent } from '../select-user-by-org/select-user-by-org.component' +import { ManufacturerSelectComponent } from '../manufacturer-select/manufacturer-select.component' +import { PositionSelectComponent } from '../position-select/position-select.component' +import { MaintenanceSelectComponent } from '../maintenance-select/maintenance-select.component' +import { NzSafeAny } from 'ng-zorro-antd/core/types' +import { NZ_MODAL_DATA } from 'ng-zorro-antd/modal' +import { SupplierSelectComponent } from '../supplier-select/supplier-select.component' +import { AssetSelectComponent } from '../asset-select/asset-select.component' + +@Component({ + selector: 'app-maintain-record-form', + standalone: true, + imports: [SharedModule, SelectUserByOrgComponent, SupplierSelectComponent, AssetSelectComponent], + templateUrl: './maintain-record-form.component.html', + styleUrl: './maintain-record-form.component.less', +}) +export class MaintainRecordFormComponent { + constructor( + private fb: FormBuilder, + private api: ApiService, + private msg: NzMessageService, + ) {} + + readonly data: NzSafeAny = inject(NZ_MODAL_DATA) + + formGroup!: FormGroup + + groupIndex = 0 + + uploadLoading = false + + types: NzSafeAny[] = [] + + ngOnInit(): void { + this.formGroup = this.fb.group({ + id: this.fb.control(null, []), + name: this.fb.control('', [FormValidators.required('请输入')]), + repairTypeId: this.fb.control(null, [FormValidators.required('请输入')]), + businessId: this.fb.control(null, []), + plannedDate: this.fb.control(null, [FormValidators.required('请输入')]), + notes: this.fb.control(null, []), + attach: this.fb.control('', []), + assetIdList: this.fb.control([], []), + }) + this.api.getRepairTypePage({ pageSize: MAX_PAGE_SIZE }).subscribe((res) => { + this.types = res.body.rows + }) + this.patchValues() + } + + patchValues() { + const { value: v, preview } = this.data + if (v) { + this.api.getRepairDetail(v.id).subscribe((res) => { + const data = res.body + this.formGroup.patchValue({ + ...data, + repairTypeId: data._repairType?.repairTypeId, + + useUserId: data._useUser?.userId ? [data._useUser?.userId] : [], + manager: data._manager?.userId ? [data._manager?.userId] : [], + responsiblePerson: data._responsiblePerson?.userId ? [data._responsiblePerson?.userId] : [], + categoryId: data._category?.categoryId + '', + positionId: data._position?.positionId + '', + ownCompanyId: data._ownCompany?.organizationId + '', + useOrganizationId: data._useOrganization?.organizationId + '', + maintenanceVendor: data._maintenanceVendor?.maintenanceVendorId, + manufacturersVendorId: data._manufacturersVendor?.manufacturersVendorId, + }) + }) + } + if (preview) { + this.formGroup.disable() + } + } + + public getValues() { + let values = null + if (FormValidators.validateFormGroup(this.formGroup)) { + const v = this.formGroup.value + + values = { + ...v, + useUserId: v.useUserId?.[0], + manager: v.manager?.[0], + categoryId: v.categoryId?.[0], + ownCompanyId: v.ownCompanyId?.[0], + positionId: v.positionId, + useOrganizationId: v.useOrganizationId?.[0], + responsiblePerson: v.responsiblePerson?.[0], + assetIdList: v.assetIdList, + } + } + return values + } + + onFileChange(e: Event) { + const target = e.target as HTMLInputElement + const file = target.files![0] + target.value = '' + + const formdata = new FormData() + formdata.append('file', file) + this.api.upload(formdata).subscribe((res) => { + this.formGroup.get('attach')?.setValue(res.body.fileName) + }) + } +} diff --git a/web-admin-app/src/app/components/plan-task/calendar-list/calendar-list.component.html b/web-admin-app/src/app/components/plan-task/calendar-list/calendar-list.component.html new file mode 100644 index 0000000..b45d1f4 --- /dev/null +++ b/web-admin-app/src/app/components/plan-task/calendar-list/calendar-list.component.html @@ -0,0 +1,37 @@ + + +
    + @switch (date.getDate()) { + @case (8) { + @for (item of listDataMap.eight; track $index) { +
  • + +
  • + } + } + @case (10) { + @for (item of listDataMap.ten; track $index) { +
  • + +
  • + } + } + @case (11) { + @for (item of listDataMap.eleven; track $index) { +
  • + +
  • + } + } + } +
+ + @if (getMonthData(month); as monthData) { +
+
{{ monthData }}
+ Backlog number +
+ } +
+
+
diff --git a/web-admin-app/src/app/components/plan-task/calendar-list/calendar-list.component.less b/web-admin-app/src/app/components/plan-task/calendar-list/calendar-list.component.less new file mode 100644 index 0000000..5ae672a --- /dev/null +++ b/web-admin-app/src/app/components/plan-task/calendar-list/calendar-list.component.less @@ -0,0 +1,22 @@ +.events { + list-style: none; + margin: 0; + padding: 0; +} + +.events .ant-badge-status { + overflow: hidden; + white-space: nowrap; + width: 100%; + text-overflow: ellipsis; + font-size: 12px; +} + +.notes-month { + text-align: center; + font-size: 28px; +} + +.notes-month section { + font-size: 28px; +} \ No newline at end of file diff --git a/web-admin-app/src/app/components/plan-task/calendar-list/calendar-list.component.ts b/web-admin-app/src/app/components/plan-task/calendar-list/calendar-list.component.ts new file mode 100644 index 0000000..f154433 --- /dev/null +++ b/web-admin-app/src/app/components/plan-task/calendar-list/calendar-list.component.ts @@ -0,0 +1,54 @@ +import { Component, Input } from '@angular/core' +import { SharedModule } from 'app/shared/shared.module' +import { PlanTaskType } from 'app/types' +import { NzCalendarMode } from 'ng-zorro-antd/calendar' + +@Component({ + selector: 'app-calendar-list', + standalone: true, + imports: [SharedModule], + templateUrl: './calendar-list.component.html', + styleUrl: './calendar-list.component.less', +}) +export class CalendarListComponent { + constructor() {} + + @Input() type: PlanTaskType = 'inspection' + + date = new Date(2012, 11, 21) + + mode: NzCalendarMode = 'month' + + OnInit() {} + + panelChange(change: { date: Date; mode: string }): void { + console.log(change.date, change.mode) + } + + listDataMap = { + eight: [ + { type: 'warning', content: 'This is warning event.' }, + { type: 'success', content: 'This is usual event.' }, + ], + ten: [ + { type: 'warning', content: 'This is warning event.' }, + { type: 'success', content: 'This is usual event.' }, + { type: 'error', content: 'This is error event.' }, + ], + eleven: [ + { type: 'warning', content: 'This is warning event' }, + { type: 'success', content: 'This is very long usual event........' }, + { type: 'error', content: 'This is error event 1.' }, + { type: 'error', content: 'This is error event 2.' }, + { type: 'error', content: 'This is error event 3.' }, + { type: 'error', content: 'This is error event 4.' }, + ], + } + + getMonthData(date: Date): number | null { + if (date.getMonth() === 8) { + return 1394 + } + return null + } +} diff --git a/web-admin-app/src/app/components/plan-task/plan-form/plan-form.component.html b/web-admin-app/src/app/components/plan-task/plan-form/plan-form.component.html new file mode 100644 index 0000000..50f2fae --- /dev/null +++ b/web-admin-app/src/app/components/plan-task/plan-form/plan-form.component.html @@ -0,0 +1,152 @@ + diff --git a/web-admin-app/src/app/components/plan-task/plan-form/plan-form.component.less b/web-admin-app/src/app/components/plan-task/plan-form/plan-form.component.less new file mode 100644 index 0000000..a1934fd --- /dev/null +++ b/web-admin-app/src/app/components/plan-task/plan-form/plan-form.component.less @@ -0,0 +1,5 @@ +.modal-container { + height: 70vh; + + overflow: auto; +} \ No newline at end of file diff --git a/web-admin-app/src/app/components/plan-task/plan-form/plan-form.component.ts b/web-admin-app/src/app/components/plan-task/plan-form/plan-form.component.ts new file mode 100644 index 0000000..f6d2422 --- /dev/null +++ b/web-admin-app/src/app/components/plan-task/plan-form/plan-form.component.ts @@ -0,0 +1,160 @@ +import { Component, Input, OnInit, inject } from '@angular/core' +import { FormBuilder, FormGroup } from '@angular/forms' +import { ApiService } from 'app/services' +import { SharedModule } from 'app/shared/shared.module' +import { FormValidators, Utils } from 'app/utils' +import { NzMessageService } from 'ng-zorro-antd/message' + +import { NzSafeAny } from 'ng-zorro-antd/core/types' +import { NZ_MODAL_DATA } from 'ng-zorro-antd/modal' + +import { ActivatedRoute } from '@angular/router' +import { STOCKTAKING_JOB_STATUS_MAP } from 'app/constants' +import { + AssetSelectComponent, + OrgSelectComponent, + PositionSelectComponent, + SelectUserByOrgComponent, + SupplierSelectComponent, +} from 'app/components' + +@Component({ + selector: 'app-stocktaking-detail-form', + standalone: true, + imports: [ + SharedModule, + SelectUserByOrgComponent, + SupplierSelectComponent, + AssetSelectComponent, + OrgSelectComponent, + PositionSelectComponent, + ], + templateUrl: './plan-form.component.html', + styleUrl: './plan-form.component.less', +}) +export class PlanFormComponent { + constructor( + private fb: FormBuilder, + private api: ApiService, + private msg: NzMessageService, + private route: ActivatedRoute, + ) {} + + readonly data: NzSafeAny = inject(NZ_MODAL_DATA) + + STOCKTAKING_JOB_STATUS_MAP = STOCKTAKING_JOB_STATUS_MAP + + jobName = '' + + formGroup!: FormGroup + + groupIndex = 0 + + uploadLoading = false + + uploadImgLoading = false + + iconPreview = '' + + flowForms: NzSafeAny[] = [] + + teamList: NzSafeAny[] = [] + ngOnInit(): void { + this.api.getAssetTeamAll().subscribe((res) => { + this.teamList = res.body + }) + this.api.getFlowFormList().subscribe((res) => { + this.flowForms = res.body + }) + + this.formGroup = this.fb.group({ + jobId: this.fb.control(null, []), + status: this.fb.control(null, []), + name: this.fb.control(null, [FormValidators.required('请输入')]), + teamId: this.fb.control(null, [FormValidators.required('请选择')]), + cycleType: this.fb.control('once', [FormValidators.required('请选择')]), + duration: this.fb.control(0, [FormValidators.required('请选择')]), + actualStartTime: this.fb.control(null, [FormValidators.required('请选择')]), + expectedFinishTime: this.fb.control(null, [FormValidators.required('请选择')]), + expectedStartTime: this.fb.control(null, [FormValidators.required('请选择')]), + + limit: this.fb.control(false, [FormValidators.required('请选择')]), + order: this.fb.control(false, [FormValidators.required('请选择')]), + skipWeekend: this.fb.control(false, [FormValidators.required('请选择')]), + photo: this.fb.control(false, []), + + businessId: this.fb.control(null, []), + remark: this.fb.control(null, []), + + formTempId: this.fb.control(null, [FormValidators.required('请选择')]), + + assetIdList: this.fb.control([], []), + }) + + this.patchValues() + } + + patchValues() { + const { value: data, preview } = this.data + if (data) { + this.formGroup.patchValue({ + ...data, + }) + } + if (preview) { + this.formGroup.disable() + } + } + + public getValues() { + let values = null + console.log('this.formGroup', this.formGroup) + if (FormValidators.validateFormGroup(this.formGroup)) { + const v = this.formGroup.value + values = { + ...v, + assetIdList: v.assetIdList.map((i: NzSafeAny) => { + return { + ...i, + // assetId: i, + } + }), + // assetId + } + } + return values + } + + onFileChange(e: Event) { + const target = e.target as HTMLInputElement + const file = target.files![0] + target.value = '' + + const formdata = new FormData() + formdata.append('file', file) + this.api.upload(formdata).subscribe((res) => { + this.formGroup.get('attachment')?.setValue(res.body.fileName) + }) + } + + onImgChange(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.formGroup.get('img')?.setValue(res.body.fileName) + }) + } +} diff --git a/web-admin-app/src/app/components/plan-task/plan-list/plan-list.component.html b/web-admin-app/src/app/components/plan-task/plan-list/plan-list.component.html new file mode 100644 index 0000000..8ae1809 --- /dev/null +++ b/web-admin-app/src/app/components/plan-task/plan-list/plan-list.component.html @@ -0,0 +1,38 @@ + + + + + + +
+ + + @switch (key) { + @case ('status') { + + } + @case ('_value') { + {{ data?.length ?? 0 }} + } + + @default { + {{ data }} + } + } + + + + + + + + +
+
diff --git a/web-admin-app/src/app/components/plan-task/plan-list/plan-list.component.less b/web-admin-app/src/app/components/plan-task/plan-list/plan-list.component.less new file mode 100644 index 0000000..e69de29 diff --git a/web-admin-app/src/app/components/plan-task/plan-list/plan-list.component.ts b/web-admin-app/src/app/components/plan-task/plan-list/plan-list.component.ts new file mode 100644 index 0000000..faaf6ae --- /dev/null +++ b/web-admin-app/src/app/components/plan-task/plan-list/plan-list.component.ts @@ -0,0 +1,128 @@ +import { PlanTaskType } from 'app/types' +import { Component, Input, TemplateRef, ViewChild } from '@angular/core' +import { FormControl, FormGroup } from '@angular/forms' + +import { AnyObject, TableOption } from 'app/shared/components/server-paginated-table' +import { ApiService } from 'app/services' +import { SharedModule } from 'app/shared/shared.module' +import { lastValueFrom, of } from 'rxjs' + +import { NzModalRef, NzModalService } from 'ng-zorro-antd/modal' +import { NzMessageService } from 'ng-zorro-antd/message' +import { NzSafeAny } from 'ng-zorro-antd/core/types' +import { ASSET_TYPE } from 'app/constants' + +import { AssetBasicTeamFormComponent } from 'app/components/asset-basic-team-form/asset-basic-team-form.component' +import { StatusTagComponent } from 'app/components/status-tag/status-tag.component' +import { PlanFormComponent } from '../plan-form/plan-form.component' + +@Component({ + selector: 'app-plan-list', + standalone: true, + imports: [SharedModule, StatusTagComponent], + templateUrl: './plan-list.component.html', + styleUrl: './plan-list.component.less', +}) +export class PlanListComponent { + constructor( + private api: ApiService, + private modal: NzModalService, + private msg: NzMessageService, + ) {} + + @Input() type: PlanTaskType = 'inspection' + + queryForm = new FormGroup({ + name: new FormControl(), + + // status: new FormControl(), + }) + + table = new TableOption(this.fetchData.bind(this)) + + copyNum = 1 + + ASSET_TYPE = ASSET_TYPE + + ngOnInit(): void { + this.table + + .setColumn([ + { key: 'teamKey', title: '计划编号', visible: true }, + { key: 'teamName', title: '计划名称', visible: true }, + { key: 'status', title: '计划状态', visible: true }, + + { key: 'createUser', title: '执行计划', visible: true }, + { key: 'createTime', title: '开始时间', visible: true }, + { key: 'createTime', title: '截止时间', visible: true }, + { key: 'createTime', title: '执行周期', visible: true }, + { key: '_value', title: '下次执行', visible: true }, + { key: 'remark', title: '巡检设备数', visible: true }, + ]) + .setRowOperate([ + { + title: '查看', + onClick: (v) => { + this.onCreate(v, true) + }, + }, + { title: '修改', onClick: this.onCreate.bind(this) }, + { title: '删除', onClick: this.deleteItem.bind(this) }, + { title: '停用', onClick: this.deleteItem.bind(this) }, + { title: '启用', onClick: this.deleteItem.bind(this) }, + { title: '报表', onClick: this.deleteItem.bind(this) }, + ]) + } + + fetchData(p: {}, q: AnyObject) { + return this.api.getPlanPage({ ...p, ...q, platType: this.type }) + } + + onCopy(data: NzSafeAny) {} + + onCreate(data?: NzSafeAny, preview?: boolean) { + let nzTitle = data ? '编辑计划' : '添加计划' + if (preview) { + nzTitle = '预览计划' + } + this.modal.create({ + nzTitle, + nzContent: PlanFormComponent, + nzWidth: '80vw', + nzWrapClassName: 'modal-lg', + nzData: { + value: data, + preview, + }, + nzOnOk: async (e) => { + const vals = e.getValues() + if (vals) { + const res = await lastValueFrom( + this.api.savePlan({ + ...vals, + planType: this.type, + }), + ) + this.msg.success(res.desc) + this.table.ref.reload() + return true + } + + return false + }, + }) + } + + deleteItem(item?: NzSafeAny) { + const ids = item ? [item.teamId] : Array.from(this.table.ref.selected) + this.modal.confirm({ + nzTitle: '警告', + nzContent: `是否要删除${ids.length}个计划?`, + nzOnOk: async () => { + const res = await lastValueFrom(this.api.deleteUserTeam(ids)) + this.msg.success(res.desc) + this.table.ref.reload() + }, + }) + } +} diff --git a/web-admin-app/src/app/components/plan-task/repair-task-form/repair-task-form.component.html b/web-admin-app/src/app/components/plan-task/repair-task-form/repair-task-form.component.html new file mode 100644 index 0000000..8f321b6 --- /dev/null +++ b/web-admin-app/src/app/components/plan-task/repair-task-form/repair-task-form.component.html @@ -0,0 +1,73 @@ + diff --git a/web-admin-app/src/app/components/plan-task/repair-task-form/repair-task-form.component.less b/web-admin-app/src/app/components/plan-task/repair-task-form/repair-task-form.component.less new file mode 100644 index 0000000..e69de29 diff --git a/web-admin-app/src/app/components/plan-task/repair-task-form/repair-task-form.component.ts b/web-admin-app/src/app/components/plan-task/repair-task-form/repair-task-form.component.ts new file mode 100644 index 0000000..38ba81d --- /dev/null +++ b/web-admin-app/src/app/components/plan-task/repair-task-form/repair-task-form.component.ts @@ -0,0 +1,151 @@ +import { Component, Input, OnInit, inject } from '@angular/core' +import { FormBuilder, FormGroup } from '@angular/forms' +import { ApiService } from 'app/services' +import { SharedModule } from 'app/shared/shared.module' +import { FormValidators, Utils } from 'app/utils' +import { NzMessageService } from 'ng-zorro-antd/message' + +import { NzSafeAny } from 'ng-zorro-antd/core/types' +import { NZ_MODAL_DATA } from 'ng-zorro-antd/modal' + +import { ActivatedRoute } from '@angular/router' +import { STOCKTAKING_JOB_STATUS_MAP } from 'app/constants' +import { + AssetSelectComponent, + OrgSelectComponent, + PositionSelectComponent, + SelectUserByOrgComponent, + SupplierSelectComponent, +} from 'app/components' +import { UploadComponent } from '../../../shared/components/upload/upload.component' + +@Component({ + selector: 'app-stocktaking-detail-form', + standalone: true, + imports: [ + SharedModule, + SelectUserByOrgComponent, + SupplierSelectComponent, + AssetSelectComponent, + OrgSelectComponent, + PositionSelectComponent, + UploadComponent, + ], + templateUrl: './repair-task-form.component.html', + styleUrl: './repair-task-form.component.less', +}) +export class RepairTaskFormComponent { + constructor( + private fb: FormBuilder, + private api: ApiService, + private msg: NzMessageService, + private route: ActivatedRoute, + ) {} + + readonly data: NzSafeAny = inject(NZ_MODAL_DATA) + + STOCKTAKING_JOB_STATUS_MAP = STOCKTAKING_JOB_STATUS_MAP + + jobName = '' + + formGroup!: FormGroup + + groupIndex = 0 + + uploadLoading = false + + uploadImgLoading = false + + iconPreview = '' + + flowForms: NzSafeAny[] = [] + + teamList: NzSafeAny[] = [] + ngOnInit(): void { + this.api.getAssetTeamAll().subscribe((res) => { + this.teamList = res.body + }) + this.api.getFlowFormList().subscribe((res) => { + this.flowForms = res.body + }) + + this.formGroup = this.fb.group({ + name: this.fb.control(null, [FormValidators.required('请输入')]), + remark: this.fb.control(null, []), + + plannedDate: this.fb.control(null, [FormValidators.required('请选择')]), + + businessId: this.fb.control(null, []), + attachment: this.fb.control(null, []), + img: this.fb.control(null, []), + + assetIdList: this.fb.control([], []), + }) + + this.patchValues() + } + + patchValues() { + const { value: data, preview } = this.data + if (data) { + this.formGroup.patchValue({ + ...data, + }) + } + if (preview) { + this.formGroup.disable() + } + } + + public getValues() { + let values = null + console.log('this.formGroup', this.formGroup) + if (FormValidators.validateFormGroup(this.formGroup)) { + const v = this.formGroup.value + values = { + ...v, + assetIdList: v.assetIdList.map((i: NzSafeAny) => { + return { + ...i, + // assetId: i, + } + }), + // assetId + } + } + return values + } + + onFileChange(e: Event) { + const target = e.target as HTMLInputElement + const file = target.files![0] + target.value = '' + + const formdata = new FormData() + formdata.append('file', file) + this.api.upload(formdata).subscribe((res) => { + this.formGroup.get('attachment')?.setValue(res.body.fileName) + }) + } + + onImgChange(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.formGroup.get('img')?.setValue(res.body.fileName) + }) + } +} diff --git a/web-admin-app/src/app/components/plan-task/task-form/task-form.component.html b/web-admin-app/src/app/components/plan-task/task-form/task-form.component.html new file mode 100644 index 0000000..b83c878 --- /dev/null +++ b/web-admin-app/src/app/components/plan-task/task-form/task-form.component.html @@ -0,0 +1,95 @@ + diff --git a/web-admin-app/src/app/components/plan-task/task-form/task-form.component.less b/web-admin-app/src/app/components/plan-task/task-form/task-form.component.less new file mode 100644 index 0000000..e69de29 diff --git a/web-admin-app/src/app/components/plan-task/task-form/task-form.component.ts b/web-admin-app/src/app/components/plan-task/task-form/task-form.component.ts new file mode 100644 index 0000000..ed5b01c --- /dev/null +++ b/web-admin-app/src/app/components/plan-task/task-form/task-form.component.ts @@ -0,0 +1,152 @@ +import { Component, Input, OnInit, inject } from '@angular/core' +import { FormBuilder, FormGroup } from '@angular/forms' +import { ApiService } from 'app/services' +import { SharedModule } from 'app/shared/shared.module' +import { FormValidators, Utils } from 'app/utils' +import { NzMessageService } from 'ng-zorro-antd/message' + +import { NzSafeAny } from 'ng-zorro-antd/core/types' +import { NZ_MODAL_DATA } from 'ng-zorro-antd/modal' + +import { ActivatedRoute } from '@angular/router' +import { STOCKTAKING_JOB_STATUS_MAP, taskTypeTitle } from 'app/constants' +import { + AssetSelectComponent, + OrgSelectComponent, + PositionSelectComponent, + SelectUserByOrgComponent, + SupplierSelectComponent, +} from 'app/components' +import { UploadComponent } from '../../../shared/components/upload/upload.component' + +@Component({ + selector: 'app-stocktaking-detail-form', + standalone: true, + imports: [ + SharedModule, + SelectUserByOrgComponent, + SupplierSelectComponent, + AssetSelectComponent, + OrgSelectComponent, + PositionSelectComponent, + UploadComponent, + ], + templateUrl: './task-form.component.html', + styleUrl: './task-form.component.less', +}) +export class TaskFormComponent { + constructor( + private fb: FormBuilder, + private api: ApiService, + private msg: NzMessageService, + private route: ActivatedRoute, + ) {} + + readonly data: NzSafeAny = inject(NZ_MODAL_DATA) + + STOCKTAKING_JOB_STATUS_MAP = STOCKTAKING_JOB_STATUS_MAP + + formGroup!: FormGroup + + groupIndex = 0 + + uploadLoading = false + + uploadImgLoading = false + + iconPreview = '' + + flowForms: NzSafeAny[] = [] + + teamList: NzSafeAny[] = [] + ngOnInit(): void { + this.api.getAssetTeamAll().subscribe((res) => { + this.teamList = res.body + }) + this.api.getFlowFormList().subscribe((res) => { + this.flowForms = res.body + }) + + this.formGroup = this.fb.group({ + name: this.fb.control(null, [FormValidators.required('请输入')]), + remark: this.fb.control(null, []), + + plannedDate: this.fb.control(null, [FormValidators.required('请选择')]), + + businessId: this.fb.control(null, []), + attachment: this.fb.control(null, []), + img: this.fb.control(null, []), + + assetIdList: this.fb.control([], []), + }) + + this.patchValues() + } + + title?: string + + patchValues() { + const { value: data, preview, type } = this.data + this.title = taskTypeTitle.get(type) + if (data) { + this.formGroup.patchValue({ + ...data, + }) + } + if (preview) { + this.formGroup.disable() + } + } + + public getValues() { + let values = null + console.log('this.formGroup', this.formGroup) + if (FormValidators.validateFormGroup(this.formGroup)) { + const v = this.formGroup.value + values = { + ...v, + assetIdList: v.assetIdList.map((i: NzSafeAny) => { + return { + ...i, + // assetId: i, + } + }), + // assetId + } + } + return values + } + + onFileChange(e: Event) { + const target = e.target as HTMLInputElement + const file = target.files![0] + target.value = '' + + const formdata = new FormData() + formdata.append('file', file) + this.api.upload(formdata).subscribe((res) => { + this.formGroup.get('attachment')?.setValue(res.body.fileName) + }) + } + + onImgChange(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.formGroup.get('img')?.setValue(res.body.fileName) + }) + } +} diff --git a/web-admin-app/src/app/components/plan-task/task-list/task-list.component.html b/web-admin-app/src/app/components/plan-task/task-list/task-list.component.html new file mode 100644 index 0000000..4cb001d --- /dev/null +++ b/web-admin-app/src/app/components/plan-task/task-list/task-list.component.html @@ -0,0 +1,32 @@ + + +
+ + + @switch (key) { + @case ('status') { + + } + @case ('_value') { + {{ data?.length ?? 0 }} + } + + @default { + {{ data }} + } + } + + + + + + + + +
+
diff --git a/web-admin-app/src/app/components/plan-task/task-list/task-list.component.less b/web-admin-app/src/app/components/plan-task/task-list/task-list.component.less new file mode 100644 index 0000000..e69de29 diff --git a/web-admin-app/src/app/components/plan-task/task-list/task-list.component.ts b/web-admin-app/src/app/components/plan-task/task-list/task-list.component.ts new file mode 100644 index 0000000..35a1149 --- /dev/null +++ b/web-admin-app/src/app/components/plan-task/task-list/task-list.component.ts @@ -0,0 +1,153 @@ +import { PlanTaskType } from 'app/types' +import { Component, Input, TemplateRef, ViewChild } from '@angular/core' +import { FormControl, FormGroup } from '@angular/forms' + +import { AnyObject, TableOption } from 'app/shared/components/server-paginated-table' +import { ApiService } from 'app/services' +import { SharedModule } from 'app/shared/shared.module' +import { lastValueFrom, of } from 'rxjs' + +import { NzModalRef, NzModalService } from 'ng-zorro-antd/modal' +import { NzMessageService } from 'ng-zorro-antd/message' +import { NzSafeAny } from 'ng-zorro-antd/core/types' +import { ASSET_TYPE } from 'app/constants' + +import { AssetBasicTeamFormComponent } from 'app/components/asset-basic-team-form/asset-basic-team-form.component' +import { StatusTagComponent } from 'app/components/status-tag/status-tag.component' +import { PlanFormComponent } from '../plan-form/plan-form.component' + +@Component({ + selector: 'app-task-list', + standalone: true, + imports: [SharedModule, StatusTagComponent], + templateUrl: './task-list.component.html', + styleUrl: './task-list.component.less', +}) +export class TaskListComponent { + constructor( + private api: ApiService, + private modal: NzModalService, + private msg: NzMessageService, + ) {} + + @Input() type: PlanTaskType = 'inspection' + + queryForm = new FormGroup({ + name: new FormControl(), + + // status: new FormControl(), + }) + + table = new TableOption(this.fetchData.bind(this)) + + copyNum = 1 + + ASSET_TYPE = ASSET_TYPE + + ngOnInit(): void { + this.table + + .setColumn([ + { key: 'teamKey', title: '任务名称', visible: true }, + { key: 'teamName', title: '任务状态', visible: true }, + { key: 'status', title: '任务来源', visible: true }, + + { key: 'createUser', title: '开始时间', visible: true }, + { key: 'createTime', title: '任务时长', visible: true }, + { key: 'createTime', title: '完成时间', visible: true }, + { key: 'createTime', title: '设备总数', visible: true }, + { key: '_value', title: '待处理设备数', visible: true }, + { key: 'remark', title: '已处理设备数', visible: true }, + { key: 'remark', title: '执行班组', visible: true }, + ]) + .setRowOperate([ + { + title: '查看', + onClick: (v) => { + this.onCreate(v, true) + }, + }, + { title: '受理', onClick: this.shouli.bind(this) }, + { title: '指派', onClick: this.zhipai.bind(this) }, + { title: '处置', onClick: this.chuzhi.bind(this) }, + { title: '报表', onClick: this.deleteItem.bind(this) }, + ]) + } + + fetchData(p: {}, q: AnyObject) { + return this.api.getTaskPage({ ...p, ...q, jobType: this.type }) + } + + shouli(item?: NzSafeAny) { + const ids = item ? [item.teamId] : Array.from(this.table.ref.selected) + this.modal.confirm({ + nzTitle: '是否确定受理当前设备流程?', + nzContent: `受理后你将作为该任务的责任人,其他人员无法受理!`, + nzOnOk: async () => { + const res = await lastValueFrom(this.api.deleteUserTeam(ids)) + this.msg.success(res.desc) + this.table.ref.reload() + }, + }) + } + zhipai(item?: NzSafeAny) { + const ids = item ? [item.teamId] : Array.from(this.table.ref.selected) + this.modal.confirm({ + nzTitle: '请选择设备任务处置人员', + nzContent: ``, + nzOnOk: async () => { + const res = await lastValueFrom(this.api.deleteUserTeam(ids)) + this.msg.success(res.desc) + this.table.ref.reload() + }, + }) + } + + chuzhi(data: NzSafeAny) {} + + onCreate(data?: NzSafeAny, preview?: boolean) { + let nzTitle = data ? '编辑任务' : '添加任务' + if (preview) { + nzTitle = '预览任务' + } + this.modal.create({ + nzTitle, + nzContent: PlanFormComponent, + nzWidth: '80vw', + nzWrapClassName: 'modal-lg', + nzData: { + value: data, + preview, + }, + nzOnOk: async (e) => { + const vals = e.getValues() + if (vals) { + const res = await lastValueFrom( + this.api.savePlan({ + ...vals, + planType: this.type, + }), + ) + this.msg.success(res.desc) + this.table.ref.reload() + return true + } + + return false + }, + }) + } + + deleteItem(item?: NzSafeAny) { + const ids = item ? [item.teamId] : Array.from(this.table.ref.selected) + this.modal.confirm({ + nzTitle: '警告', + nzContent: `是否要删除${ids.length}个任务?`, + nzOnOk: async () => { + const res = await lastValueFrom(this.api.deleteUserTeam(ids)) + this.msg.success(res.desc) + this.table.ref.reload() + }, + }) + } +} diff --git a/web-admin-app/src/app/components/select-user-by-org/select-user-by-org.component.ts b/web-admin-app/src/app/components/select-user-by-org/select-user-by-org.component.ts index b89c777..444f0b1 100644 --- a/web-admin-app/src/app/components/select-user-by-org/select-user-by-org.component.ts +++ b/web-admin-app/src/app/components/select-user-by-org/select-user-by-org.component.ts @@ -1,5 +1,14 @@ import { CommonModule } from '@angular/common' -import { ChangeDetectorRef, Component, Input, OnInit, TemplateRef, forwardRef } from '@angular/core' +import { + ChangeDetectorRef, + Component, + EventEmitter, + Input, + OnInit, + Output, + 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' @@ -55,6 +64,8 @@ export class SelectUserByOrgComponent implements ControlValueAccessor, OnInit { @Input() size: 'small' | 'default' = 'default' + @Output() onSelect = new EventEmitter() + allGetedDataMap = new Map() currentUsers: NzSafeAny[] = [] @@ -80,6 +91,7 @@ export class SelectUserByOrgComponent implements ControlValueAccessor, OnInit { nzOnOk: () => { this.selectedKeys = new Set([...this.tempSelectedKeys]) this.onChange(Array.from(this.selectedKeys)) + this.handleSelect() }, nzOnCancel: () => { this.tempSelectedKeys.clear() @@ -87,6 +99,16 @@ export class SelectUserByOrgComponent implements ControlValueAccessor, OnInit { }) } + handleSelect() { + const selected: NzSafeAny[] = [] + this.allGetedDataMap.forEach((i) => { + if (this.selectedKeys.has(i.userId)) { + selected.push(i) + } + }) + this.onSelect.emit(selected) + } + onOrgSelectedChange(v?: NzSafeAny, uid?: number) { this.api .getUserPage({ @@ -148,6 +170,7 @@ export class SelectUserByOrgComponent implements ControlValueAccessor, OnInit { getUserById(id: number) { this.api.getUserDetail(id).subscribe((res) => { this.allGetedDataMap.set(id, res.body) + this.handleSelect() }) } diff --git a/web-admin-app/src/app/components/status-tag/status-tag.component.html b/web-admin-app/src/app/components/status-tag/status-tag.component.html new file mode 100644 index 0000000..bc5c372 --- /dev/null +++ b/web-admin-app/src/app/components/status-tag/status-tag.component.html @@ -0,0 +1,11 @@ +@switch (status) { + @case (0) { + + } + @case (1) { + + } + @default { + {{ status }} + } +} diff --git a/web-admin-app/src/app/components/status-tag/status-tag.component.less b/web-admin-app/src/app/components/status-tag/status-tag.component.less new file mode 100644 index 0000000..e69de29 diff --git a/web-admin-app/src/app/components/status-tag/status-tag.component.ts b/web-admin-app/src/app/components/status-tag/status-tag.component.ts new file mode 100644 index 0000000..66bb64e --- /dev/null +++ b/web-admin-app/src/app/components/status-tag/status-tag.component.ts @@ -0,0 +1,17 @@ +import { Component, Input } from '@angular/core' +import { NzBadgeModule } from 'ng-zorro-antd/badge' + +@Component({ + selector: 'app-status-tag', + standalone: true, + imports: [NzBadgeModule], + templateUrl: './status-tag.component.html', + styleUrl: './status-tag.component.less', +}) +export class StatusTagComponent { + constructor() {} + + @Input() status: number = 0 + + ngOnInit() {} +} diff --git a/web-admin-app/src/app/constants/index.ts b/web-admin-app/src/app/constants/index.ts index 7f453b6..ab40ee1 100644 --- a/web-admin-app/src/app/constants/index.ts +++ b/web-admin-app/src/app/constants/index.ts @@ -1,3 +1,5 @@ +import { PlanTaskType } from 'app/types' + export const MAX_PAGE_SIZE = 10000000 export const LOCALSTORAGKEY = { @@ -16,6 +18,12 @@ export const ASSET_STATUS = [ { label: '已报废', value: 8 }, ] +export const FLOW_FORM_TYPES = [ + { value: 'DATE', label: '日期' }, + { value: 'NUMBER', label: '数字' }, + { value: 'RADIO', label: '单选' }, + { value: 'STRING', label: '文本' }, +] export const ASSET_STATUS_MAP = () => { return ASSET_STATUS.reduce( (map, item) => { @@ -26,6 +34,37 @@ export const ASSET_STATUS_MAP = () => { ) } +// 业务类型: +// ALLOCATE-资产调拨, +// BORROW-资产借用, +// COLLECTION-资产领用, +// OUTBOUND-资产出库, +// RETURN-资产归还, +// RETURN_INVENTORY-资产退库, +// STORAGE-资产入库"), +// TRANSFER("transfer", "资产转移"),\n +// REPAIR_FAULT("repair_fault", "故障登记"), +// REPAIR("repair", "设备报修"), +// RETIREMENT("retirement", "资产报废"), +// CLEAN("clean", "资产清理"), +// UNKNOWN("null", "未知操作"); + +export const ASSET_TYPE = [ + { label: '资产入库', value: 'STORAGE' }, + { label: '资产领用', value: 'COLLECTION' }, + { label: '资产退库', value: 'RETURN_INVENTORY' }, + { label: '资产借用', value: 'BORROW' }, + { label: '资产归还', value: 'RETURN' }, + { label: '资产调拨', value: 'ALLOCATE' }, + { label: '资产转移', value: 'TRANSFER' }, + { label: '资产报废', value: 'RETIREMENT' }, + // { label: '资产出库', value: 'OUTBOUND' }, + // { label: '故障登记', value: 'REPAIR_FAULT' }, + // { label: '设备报修', value: 'REPAIR' }, + // { label: '资产清理', value: 'CLEAN' }, + // { label: '未知操作', value: 'UNKNOWN' }, +] + export const ASSET_SOURCE_MAP = new Map([ [0, '捐赠'], [1, '赠送'], @@ -81,3 +120,10 @@ export const FLOW_STATUS = new Map([ [5, '已废弃'], [6, '流程异常'], ]) + +export const taskTypeTitle = new Map([ + ['inspection', '巡检'], + ['maintenance', '保养'], + ['repair', '报修'], + ['stocktaking', '盘点'], +]) diff --git a/web-admin-app/src/app/pages/fixed-asset/asset-management/asset-management.component.html b/web-admin-app/src/app/pages/fixed-asset/asset-management/asset-management.component.html new file mode 100644 index 0000000..0db5ad5 --- /dev/null +++ b/web-admin-app/src/app/pages/fixed-asset/asset-management/asset-management.component.html @@ -0,0 +1,73 @@ + + + + + + +
+ + + @switch (key) { + @case ('status') { + + {{ ASSET_STATUS_MAP[data] }} + + } + @case ('_useUser') { + {{ data?.userName ?? '-' }} + } + @case ('_warehouse') { + {{ data?.name ?? '-' }} + } + @case ('_position') { + {{ data?.name ?? '-' }} + } + @case ('_head') { + {{ data?.userName ?? '-' }} + } + @case ('_ownCompany') { + {{ data?.organizationName ?? '-' }} + } + @case ('_useOrganization') { + {{ data?.organizationName ?? '-' }} + } + @case ('_category') { + {{ data?.categoryName ?? '-' }} + } + @default { + {{ data }} + } + } + + + + + + + + + + + + + + + + + +
+
diff --git a/web-admin-app/src/app/pages/fixed-asset/asset-management/asset-management.component.less b/web-admin-app/src/app/pages/fixed-asset/asset-management/asset-management.component.less new file mode 100644 index 0000000..e69de29 diff --git a/web-admin-app/src/app/pages/fixed-asset/asset-management/asset-management.component.ts b/web-admin-app/src/app/pages/fixed-asset/asset-management/asset-management.component.ts new file mode 100644 index 0000000..d6b0302 --- /dev/null +++ b/web-admin-app/src/app/pages/fixed-asset/asset-management/asset-management.component.ts @@ -0,0 +1,194 @@ +import { Component, TemplateRef, ViewChild } from '@angular/core' +import { FormControl, FormGroup } from '@angular/forms' + +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' +import { lastValueFrom, of } from 'rxjs' +import { AssetFormComponent, ManufacturerSelectComponent, PositionSelectComponent } from 'app/components' +import { NzModalRef, NzModalService } from 'ng-zorro-antd/modal' +import { NzMessageService } from 'ng-zorro-antd/message' +import { NzSafeAny } from 'ng-zorro-antd/core/types' +import { ASSET_SOURCE_MAP, ASSET_STATUS, ASSET_STATUS_MAP, ASSET_TYPE } from 'app/constants' +import { Utils } from 'app/utils' + +@Component({ + selector: 'app-asset-management', + standalone: true, + imports: [SharedModule, AssetFormComponent, PositionSelectComponent, ManufacturerSelectComponent], + templateUrl: './asset-management.component.html', + styleUrl: './asset-management.component.less', +}) +export class AssetManagementComponent { + constructor( + private api: ApiService, + private modal: NzModalService, + private msg: NzMessageService, + ) {} + + queryForm = new FormGroup({ + name: new FormControl(), + model: new FormControl(), + status: new FormControl(), + assetCode: new FormControl(), + serialNumber: new FormControl(), + sourceId: new FormControl(), + positionId: new FormControl(), + manufacturersVendorId: new FormControl(), + }) + + ASSET_STATUS_MAP = ASSET_STATUS_MAP() + + ASSET_SOURCE_MAP = ASSET_SOURCE_MAP + + table = new TableOption(this.fetchData.bind(this)) + + copyNum = 1 + + ASSET_TYPE = ASSET_TYPE + + ngOnInit(): void { + this.table + .setConfig({ + selectable: true, + rowKey: 'assetId', + }) + .setColumn([ + { key: 'assetCode', title: '业务编号', visible: true }, + { key: 'name', title: '流程名称', visible: true }, + { key: '_category', title: '流程类型', visible: true }, + { key: 'status', title: '流程状态', visible: true }, + { key: '_ownCompany', title: '紧急程度', visible: true }, + { key: '_useOrganization', title: '发起人', visible: true }, + { key: '_position', title: '创建时间', visible: true }, + { key: '_position', title: '当前节点', visible: true }, + { key: '_position', title: '备注', visible: true }, + ]) + .setRowOperate([ + { + title: '查看', + onClick: (v) => { + this.onCreate(v, true) + }, + }, + { title: '修改', onClick: this.onCreate.bind(this) }, + { title: '复制', onClick: this.onCopy.bind(this) }, + { title: '二维码', onClick: this.qrcode.bind(this) }, + { title: '删除', onClick: this.deleteItem.bind(this) }, + ]) + } + + fetchData(p: {}, q: AnyObject) { + return this.api.getAssetManagerPage({ ...p, ...q }) + } + + onCopy(data: NzSafeAny) {} + + onCreate(data?: NzSafeAny, preview?: boolean) { + let nzTitle = data ? '编辑资产' : '添加资产' + if (preview) { + nzTitle = '预览资产' + } + this.modal.create({ + nzTitle, + nzContent: AssetFormComponent, + nzWidth: '80vw', + nzWrapClassName: 'modal-lg', + nzData: { + value: data, + preview, + }, + nzOnOk: async (e) => { + const vals = e.getValues() + if (vals) { + const res = await lastValueFrom(this.api.saveAsset(vals)) + this.msg.success(res.desc) + this.table.ref.reload() + return true + } + + return false + }, + }) + } + + deleteItem(item?: NzSafeAny) { + const ids = item ? [item.assetId] : Array.from(this.table.ref.selected) + this.modal.confirm({ + nzTitle: '警告', + nzContent: `是否要删除${ids.length}个资产?`, + nzOnOk: async () => { + const res = await lastValueFrom(this.api.deleteAsset(ids)) + this.msg.success(res.desc) + this.table.ref.reload() + }, + }) + } + + confirmAsset() { + const ids = Array.from(this.table.ref.selected).map((i) => Number(i)) + this.modal.confirm({ + nzTitle: '警告', + nzContent: `是否对选择的${ids.length}个资产进行确认?`, + nzOnOk: async () => { + const res = await lastValueFrom(this.api.confirmAsset(ids)) + this.msg.success(res.desc) + this.table.ref.reload() + }, + }) + } + + qrcode(d: NzSafeAny) { + this.msg.loading('二维码生成中...') + this.api.assetQrcode(d.assetId).subscribe((res) => { + Utils.downLoadFile(res, 'application/pdf') + this.msg.remove() + this.msg.success('二维码生成成功') + }) + } + + downloadTemplate() { + this.msg.loading('模板下载中...') + this.api.downloadAssetTemplate().subscribe((res) => { + Utils.downLoadFile(res, 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8') + this.msg.remove() + this.msg.success('模板下载成功') + }) + } + + importModalRef?: NzModalRef + importExcel(nzContent: TemplateRef<{}>) { + this.importModalRef = this.modal.create({ + nzTitle: '资产数据导入', + nzContent, + nzWidth: 800, + nzFooter: null, + }) + } + + onFileChange(e: Event) { + const target = e.target as HTMLInputElement + const file = target.files![0] + target.value = '' + const formdata = new FormData() + formdata.append('file', file) + this.api.uploadAsset(formdata).subscribe((res) => { + this.importModalRef?.close() + this.msg.success(res.desc) + this.table.ref.reload() + }) + } + exportExcel() { + const ids = Array.from(this.table.ref.selected).map((i) => Number(i)) + if (ids.length === 0) { + return + } + this.msg.loading('Excel生成中...') + this.api.exportAsset(ids).subscribe((res) => { + Utils.downLoadFile(res, 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8') + this.msg.remove() + this.msg.success('Excel生成成功') + }) + } +} diff --git a/web-admin-app/src/app/pages/fixed-asset/basic/asset-user-group/asset-user-group.component.html b/web-admin-app/src/app/pages/fixed-asset/basic/asset-user-group/asset-user-group.component.html new file mode 100644 index 0000000..07d7d90 --- /dev/null +++ b/web-admin-app/src/app/pages/fixed-asset/basic/asset-user-group/asset-user-group.component.html @@ -0,0 +1,59 @@ + + + + + + +
+ + + @switch (key) { + @case ('status') { + + } + @case ('_value') { + {{ data?.length ?? 0 }} + } + + @default { + {{ data }} + } + } + + + + + + + + + + + +
+
diff --git a/web-admin-app/src/app/pages/fixed-asset/basic/asset-user-group/asset-user-group.component.less b/web-admin-app/src/app/pages/fixed-asset/basic/asset-user-group/asset-user-group.component.less new file mode 100644 index 0000000..e69de29 diff --git a/web-admin-app/src/app/pages/fixed-asset/basic/asset-user-group/asset-user-group.component.ts b/web-admin-app/src/app/pages/fixed-asset/basic/asset-user-group/asset-user-group.component.ts new file mode 100644 index 0000000..c6c4f8e --- /dev/null +++ b/web-admin-app/src/app/pages/fixed-asset/basic/asset-user-group/asset-user-group.component.ts @@ -0,0 +1,125 @@ +import { Component, TemplateRef, ViewChild } from '@angular/core' +import { FormControl, FormGroup } from '@angular/forms' + +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' +import { lastValueFrom, of } from 'rxjs' +import { + AssetFormComponent, + ManufacturerSelectComponent, + PositionSelectComponent, + StatusTagComponent, +} from 'app/components' +import { NzModalRef, NzModalService } from 'ng-zorro-antd/modal' +import { NzMessageService } from 'ng-zorro-antd/message' +import { NzSafeAny } from 'ng-zorro-antd/core/types' +import { ASSET_SOURCE_MAP, ASSET_STATUS, ASSET_STATUS_MAP, ASSET_TYPE } from 'app/constants' +import { Utils } from 'app/utils' +import { AssetBasicTeamFormComponent } from 'app/components/asset-basic-team-form/asset-basic-team-form.component' + +@Component({ + selector: 'app-asset-management', + standalone: true, + imports: [ + SharedModule, + AssetFormComponent, + PositionSelectComponent, + ManufacturerSelectComponent, + StatusTagComponent, + ], + templateUrl: './asset-user-group.component.html', + styleUrl: './asset-user-group.component.less', +}) +export class AssetUserGroupComponent { + constructor( + private api: ApiService, + private modal: NzModalService, + private msg: NzMessageService, + ) {} + + queryForm = new FormGroup({ + teamName: new FormControl(), + + // status: new FormControl(), + }) + + table = new TableOption(this.fetchData.bind(this)) + + copyNum = 1 + + ASSET_TYPE = ASSET_TYPE + + ngOnInit(): void { + this.table + + .setColumn([ + { key: 'teamKey', title: '班组编号', visible: true }, + { key: 'teamName', title: '班组名称', visible: true }, + { key: 'status', title: '班组状态', visible: true }, + + { key: 'createUser', title: '创建人', visible: true }, + { key: 'createTime', title: '创建时间', visible: true }, + { key: '_value', title: '成员数', visible: true }, + { key: 'remark', title: '备注', visible: true }, + ]) + .setRowOperate([ + { + title: '查看', + onClick: (v) => { + this.onCreate(v, true) + }, + }, + { title: '修改', onClick: this.onCreate.bind(this) }, + + { title: '删除', onClick: this.deleteItem.bind(this) }, + ]) + } + + fetchData(p: {}, q: AnyObject) { + return this.api.getAssetTeamPage({ ...p, ...q }) + } + + onCopy(data: NzSafeAny) {} + + onCreate(data?: NzSafeAny, preview?: boolean) { + let nzTitle = data ? '编辑班组' : '添加班组' + if (preview) { + nzTitle = '预览班组' + } + this.modal.create({ + nzTitle, + nzContent: AssetBasicTeamFormComponent, + nzWidth: '800px', + nzData: { + value: data, + preview, + }, + nzOnOk: async (e) => { + const vals = e.getValues() + if (vals) { + const res = await lastValueFrom(this.api.saveUserTeam(vals)) + this.msg.success(res.desc) + this.table.ref.reload() + return true + } + + return false + }, + }) + } + + deleteItem(item?: NzSafeAny) { + const ids = item ? [item.teamId] : Array.from(this.table.ref.selected) + this.modal.confirm({ + nzTitle: '警告', + nzContent: `是否要删除${ids.length}个班组?`, + nzOnOk: async () => { + const res = await lastValueFrom(this.api.deleteUserTeam(ids)) + this.msg.success(res.desc) + this.table.ref.reload() + }, + }) + } +} diff --git a/web-admin-app/src/app/pages/fixed-asset/basic/basic-category/basic-category.component.html b/web-admin-app/src/app/pages/fixed-asset/basic/basic-category/basic-category.component.html index 0ea4079..f5835d3 100644 --- a/web-admin-app/src/app/pages/fixed-asset/basic/basic-category/basic-category.component.html +++ b/web-admin-app/src/app/pages/fixed-asset/basic/basic-category/basic-category.component.html @@ -4,54 +4,278 @@
- -
- - 名称 - - - - - - 安全库存 - - - - - - 安全库存上限 - - - - - - 安全库存下限 - - - - - - - - - - - + + + + + + + +
+
+ + 名称 + + + + + + 安全库存 + + + + + + 安全库存上限 + + + + + + 安全库存下限 + + + + + + + +
+
+ + 扩展属性表单模板 + + + + + + + + + + 扩展属性 + +
+
+ + + + 序号 + 标识符 + 检查内容 + 类型 + + 结果 + 备注 + 操作 + + + + @for (item of formValue.controls; track $index) { + + + + + + + + + + + + + @for (item of FLOW_FORM_TYPES; track $index) { + + } + + + + @switch ( + formValue.controls.at($index)?.get('type')?.value + ) { + @case ('DATE') { + + } + @case ('RADIO') { + + +
+
+ + + +
+
+
+
+
+ +
+ } + @case ('NUMBER') { + + } + @default { + + } + } + + + + + + + + + } + + + + + + + + +
+
+
+
+
+
+
@@ -61,3 +285,7 @@ + + + + diff --git a/web-admin-app/src/app/pages/fixed-asset/basic/basic-category/basic-category.component.ts b/web-admin-app/src/app/pages/fixed-asset/basic/basic-category/basic-category.component.ts index 5da320c..5d5cda8 100644 --- a/web-admin-app/src/app/pages/fixed-asset/basic/basic-category/basic-category.component.ts +++ b/web-admin-app/src/app/pages/fixed-asset/basic/basic-category/basic-category.component.ts @@ -1,21 +1,24 @@ -import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core' +import { Component, inject, 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 { FormArray, FormBuilder, FormControl, 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 { FormValidators, Utils } from 'app/utils' import { ComponentBasicCategoryTreeComponent } from 'app/components' +import { ActivatedRoute, Router } from '@angular/router' +import { FLOW_FORM_TYPES } from 'app/constants' +import { UploadComponent } from 'app/shared/components/upload/upload.component' @Component({ selector: 'app-basic-category', standalone: true, - imports: [SharedModule, ComponentBasicCategoryTreeComponent], + imports: [SharedModule, ComponentBasicCategoryTreeComponent, UploadComponent], templateUrl: './basic-category.component.html', styleUrl: './basic-category.component.less', }) @@ -24,12 +27,13 @@ export class BasicCategoryComponent { private modal: NzModalService, private msg: NzMessageService, private drawer: NzDrawerService, - private api: ApiService, - private fb: FormBuilder, + public api: ApiService, ) {} @ViewChild('treeEl') treeEl!: ComponentBasicCategoryTreeComponent + step = 0 + queryForm!: FormGroup createForm!: FormGroup @@ -48,6 +52,7 @@ export class BasicCategoryComponent { safetyLimit: [0, []], lowerLimit: [0, []], upperLimit: [0, []], + _assetExtTemp: new FormArray([]), }) } initQueryForm() { @@ -62,7 +67,14 @@ export class BasicCategoryComponent { } onSelectedChange(v: NzSafeAny) { - this.createForm.patchValue(v) + this.createForm.patchValue({ + ...v, + }) + this.patchFormValue(v._assetExtTemp ?? []) + } + + get formValue(): FormArray { + return this.createForm.get('_assetExtTemp') as FormArray } onConfirm() { @@ -72,6 +84,18 @@ export class BasicCategoryComponent { this.api .updateBasicCategoryTree({ ...value, + _assetExtTemp: this.formValue.value.map((v: any) => { + if (v.type === 'RADIO') { + return { + ...v, + value: { + value: v.value, + fields: v.fields.map((i: string) => i), + }, + } + } + return v + }), }) .subscribe((res) => { this.msg.success(res.desc) @@ -80,4 +104,99 @@ export class BasicCategoryComponent { }) } } + + downloadTemplate() { + this.msg.loading('模板下载中...') + this.api.getFlowFormsTpl().subscribe((res) => { + Utils.downLoadFile(res, 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8') + this.msg.remove() + this.msg.success('模板下载成功') + }) + } + + fb = inject(FormBuilder) + onTplupload(e: NzSafeAny[]) { + this.patchFormValue(e) + } + + patchFormValue(e: NzSafeAny[]) { + this.formValue.clear() + e.forEach((v) => { + let value = v.value + const fieldsArrays = this.fb.array([]) + if (v.type === 'RADIO') { + let val = Object.create(null) + try { + val = typeof v.value === 'string' ? JSON.parse(v.value) : v.value + } catch (error) {} + val?.fields?.forEach((i: string) => { + fieldsArrays.push(this.fb.control(i)) + }) + value = val?.value + } + this.formValue.push( + new FormGroup({ + key: new FormControl(v.key, []), + value: new FormControl(value, []), + name: new FormControl(v.name, []), + type: new FormControl(v.type, []), + remark: new FormControl(v.remark, []), + sort: new FormControl(v.sort ?? 0, []), + fields: fieldsArrays, + }), + ) + }) + } + + formatRadioValue(fields: string[], value: string) {} + + router = inject(Router) + + FLOW_FORM_TYPES = FLOW_FORM_TYPES + + route = inject(ActivatedRoute) + getRadioFieldsFormArray(index: number): FormArray { + return this.formValue.at(index).get('fields') as FormArray + } + getRadioFields(index: number): any[] { + return this.getRadioFieldsFormArray(index).controls + } + + addRadioItem(idx: number) { + this.getRadioFieldsFormArray(idx).push(new FormControl()) + } + addFormItem() { + this.formValue.push( + new FormGroup({ + key: new FormControl(null, []), + value: new FormControl(null, []), + name: new FormControl(null, []), + type: new FormControl(null, []), + remark: new FormControl(null, []), + sort: new FormControl(null, []), + fields: this.fb.array([]), + }), + ) + } + + addFormValue() { + this.formValue.push( + new FormGroup({ + key: new FormControl(), + value: new FormControl(), + name: new FormControl(), + type: new FormControl(), + remark: new FormControl(), + sort: new FormControl(0), + }), + ) + } + + removeFormItem(idx: number) { + this.formValue.removeAt(idx) + } + + removeRadioItem(idx: number, idx2: number) { + this.getRadioFieldsFormArray(idx).removeAt(idx2) + } } diff --git a/web-admin-app/src/app/pages/fixed-asset/basic/basic-flow-form-manage/basic-flow-form-manage.component.html b/web-admin-app/src/app/pages/fixed-asset/basic/basic-flow-form-manage/basic-flow-form-manage.component.html new file mode 100644 index 0000000..fcc0186 --- /dev/null +++ b/web-admin-app/src/app/pages/fixed-asset/basic/basic-flow-form-manage/basic-flow-form-manage.component.html @@ -0,0 +1,219 @@ + + + + + + + +
+
+ @switch (step) { + @case (0) { + + } + @case (1) { + + } + @case (2) { + + } + } + + + + + + + + + + + + + 表单名称 + + + + + + 表单编号 + + + + + + 选择模板 + + + + + + + + + +
+
+ + + + 序号 + 标识符 + 检查内容 + 类型 + + 结果 + 备注 + 操作 + + + + @for (item of formValue.controls; track $index) { + + + + + + + + + + + + + @for (item of FLOW_FORM_TYPES; track $index) { + + } + + + + @switch (formValue.controls.at($index)?.get('type')?.value) { + @case ('DATE') { + + } + @case ('RADIO') { + + +
+
+ + + +
+
+
+
+
+ +
+ } + @case ('NUMBER') { + + } + @default { + + } + } + + + + + + + + + } + + + + + + + + +
+
+
+
+ 33 + + +
+
+
+
+ + + + diff --git a/web-admin-app/src/app/pages/fixed-asset/basic/basic-flow-form-manage/basic-flow-form-manage.component.less b/web-admin-app/src/app/pages/fixed-asset/basic/basic-flow-form-manage/basic-flow-form-manage.component.less new file mode 100644 index 0000000..271f62c --- /dev/null +++ b/web-admin-app/src/app/pages/fixed-asset/basic/basic-flow-form-manage/basic-flow-form-manage.component.less @@ -0,0 +1,8 @@ +.radio { + [nz-radio] { + display: block; + height: 32px; + line-height: 32px; + } + +} \ No newline at end of file diff --git a/web-admin-app/src/app/pages/fixed-asset/basic/basic-flow-form-manage/basic-flow-form-manage.component.ts b/web-admin-app/src/app/pages/fixed-asset/basic/basic-flow-form-manage/basic-flow-form-manage.component.ts new file mode 100644 index 0000000..e7db594 --- /dev/null +++ b/web-admin-app/src/app/pages/fixed-asset/basic/basic-flow-form-manage/basic-flow-form-manage.component.ts @@ -0,0 +1,198 @@ +import { Component, inject } from '@angular/core' +import { FormArray, FormBuilder, FormControl, FormGroup } from '@angular/forms' +import { ActivatedRoute, Router } from '@angular/router' +import { FLOW_FORM_TYPES } from 'app/constants' +import { ApiService } from 'app/services' +import { UploadComponent } from 'app/shared/components/upload/upload.component' +import { SharedModule } from 'app/shared/shared.module' +import { FormValidators, Utils } from 'app/utils' +import { NzSafeAny } from 'ng-zorro-antd/core/types' +import { NzMessageService } from 'ng-zorro-antd/message' +import { NzModalService } from 'ng-zorro-antd/modal' +import { lastValueFrom } from 'rxjs' + +@Component({ + selector: 'app-basic-flow-form-manage', + standalone: true, + imports: [SharedModule, UploadComponent], + templateUrl: './basic-flow-form-manage.component.html', + styleUrl: './basic-flow-form-manage.component.less', +}) +export class BasicFlowFormManageComponent { + constructor(public api: ApiService) {} + + step = 0 + + formJsonData = [] + + FLOW_FORM_TYPES = FLOW_FORM_TYPES + + formGroup = new FormGroup({ + formKey: new FormControl('', [FormValidators.required()]), + formName: new FormControl('', [FormValidators.required()]), + templatePath: new FormControl('', []), + _formValue: new FormArray([]), + }) + + msg = inject(NzMessageService) + + router = inject(Router) + + modal = inject(NzModalService) + + route = inject(ActivatedRoute) + + get formValue(): FormArray { + return this.formGroup.get('_formValue') as FormArray + } + + id: string | null = null + ngOnInit() { + const id = this.route.snapshot.paramMap.get('id') + if (id && id !== 'create') { + this.id = id + this.api.getFlowFormDetail(id).subscribe((res) => { + Object.entries(res.body).forEach(([k, v]) => { + if (k === '_formValue') { + this.patchFormValue(res.body[k] ?? []) + } else { + this.formGroup.get(k)?.setValue(v) + } + }) + console.log('this.formGroup', this.formGroup) + }) + } + } + + downloadTemplate() { + this.msg.loading('模板下载中...') + this.api.getFlowFormsTpl().subscribe((res) => { + Utils.downLoadFile(res, 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8') + this.msg.remove() + this.msg.success('模板下载成功') + }) + } + + fb = inject(FormBuilder) + onTplupload(e: NzSafeAny[]) { + this.patchFormValue(e) + } + + patchFormValue(e: NzSafeAny[]) { + this.formValue.clear() + e.forEach((v) => { + let value = v.value + const fieldsArrays = this.fb.array([]) + if (v.type === 'RADIO') { + let val = Object.create(null) + try { + val = typeof v.value === 'string' ? JSON.parse(v.value) : v.value + } catch (error) {} + val?.fields?.forEach((i: string) => { + fieldsArrays.push(this.fb.control(i)) + }) + value = val?.value + } + this.formValue.push( + new FormGroup({ + key: new FormControl(v.key, []), + value: new FormControl(value, []), + name: new FormControl(v.name, []), + type: new FormControl(v.type, []), + remark: new FormControl(v.remark, []), + sort: new FormControl(v.sort ?? 0, []), + fields: fieldsArrays, + }), + ) + }) + } + + nextStep(currentStep: number) { + if (currentStep === 0) { + if (!FormValidators.validateFormGroup(this.formGroup) || this.formValue.value.length === 0) { + this.msg.error('请完善表单信息') + return + } + } + if (currentStep === 2) { + this.handleSubmit() + } + this.step = currentStep + 1 + } + + handleSubmit() { + if (FormValidators.validateFormGroup(this.formGroup)) { + // if(this.formValue.value) + this.modal.confirm({ + nzTitle: '提交表单', + nzContent: '确定提交表单?', + nzOnOk: async () => { + const vals = this.formGroup.value + const res = await lastValueFrom( + this.id + ? this.api.updateFlowForm({ + ...vals, + id: this.id, + formTempId: this.id, + }) + : this.api.addFlowForm(vals), + ) + this.msg.success(res.desc) + this.router.navigate(['/fixed-asset/basic/flow-form/list']) + }, + }) + } + } + + getRadioFieldsFormArray(index: number): FormArray { + return this.formValue.at(index).get('fields') as FormArray + } + getRadioFields(index: number): any[] { + return this.getRadioFieldsFormArray(index).controls + } + cancel(currentStep: number) { + if (currentStep === 0) { + this.router.navigate(['/fixed-asset/basic/flow-form/list']) + return + } + this.step = currentStep - 1 + } + + addRadioItem(idx: number) { + this.getRadioFieldsFormArray(idx).push(new FormControl()) + } + addFormItem() { + this.formValue.push( + new FormGroup({ + key: new FormControl(null, []), + value: new FormControl(null, []), + name: new FormControl(null, []), + type: new FormControl(null, []), + remark: new FormControl(null, []), + sort: new FormControl(null, []), + fields: this.fb.array([]), + }), + ) + } + + addFormValue() { + this.formValue.push( + new FormGroup({ + key: new FormControl(), + value: new FormControl(), + name: new FormControl(), + type: new FormControl(), + remark: new FormControl(), + sort: new FormControl(0), + }), + ) + } + + removeFormItem(idx: number) { + this.formValue.removeAt(idx) + } + + removeRadioItem(idx: number, idx2: number) { + this.getRadioFieldsFormArray(idx).removeAt(idx2) + } +} diff --git a/web-admin-app/src/app/pages/fixed-asset/basic/basic-flow-form/basic-flow-form.component.html b/web-admin-app/src/app/pages/fixed-asset/basic/basic-flow-form/basic-flow-form.component.html new file mode 100644 index 0000000..26158d4 --- /dev/null +++ b/web-admin-app/src/app/pages/fixed-asset/basic/basic-flow-form/basic-flow-form.component.html @@ -0,0 +1,71 @@ + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + @switch (key) { + @case ('formStatus') { + + } + @default { + {{ data }} + } + } + + +
+
+ + +
+ + 审批人 + + + + +
+
+ + + + diff --git a/web-admin-app/src/app/pages/fixed-asset/basic/basic-flow-form/basic-flow-form.component.less b/web-admin-app/src/app/pages/fixed-asset/basic/basic-flow-form/basic-flow-form.component.less new file mode 100644 index 0000000..e69de29 diff --git a/web-admin-app/src/app/pages/fixed-asset/basic/basic-flow-form/basic-flow-form.component.ts b/web-admin-app/src/app/pages/fixed-asset/basic/basic-flow-form/basic-flow-form.component.ts new file mode 100644 index 0000000..c2ddccd --- /dev/null +++ b/web-admin-app/src/app/pages/fixed-asset/basic/basic-flow-form/basic-flow-form.component.ts @@ -0,0 +1,117 @@ +import { Component, inject, TemplateRef, ViewChild } from '@angular/core' +import { FormControl, FormGroup } from '@angular/forms' +import { Router } from '@angular/router' +import { StatusTagComponent } from 'app/components' +import { ApiService } from 'app/services' +import { AnyObject, TableOption } from 'app/shared/components/server-paginated-table' +import { SharedModule } from 'app/shared/shared.module' +import { FormValidators } from 'app/utils' +import { NzSafeAny } from 'ng-zorro-antd/core/types' +import { NzMessageService } from 'ng-zorro-antd/message' +import { NzModalService } from 'ng-zorro-antd/modal' +import { lastValueFrom, map } from 'rxjs' + +@Component({ + selector: 'app-basic-flow-form', + standalone: true, + imports: [SharedModule, StatusTagComponent], + templateUrl: './basic-flow-form.component.html', + styleUrl: './basic-flow-form.component.less', +}) +export class BasicFlowFormComponent { + constructor( + private api: ApiService, + private modal: NzModalService, + private msg: NzMessageService, + ) {} + + @ViewChild('createFormTpl') createFormTpl!: TemplateRef<{}> + + queryForm = new FormGroup({ + name: new FormControl(null), + }) + + createForm = new FormGroup({ + formId: new FormControl(''), + userId: new FormControl([], [FormValidators.required('请选择')]), + }) + + table = new TableOption(this.fetchData.bind(this)) + + ngOnInit(): void { + this.table + // .setConfig({ + // selectable: true, + // rowKey: 'id', + // }) + .setColumn([ + { key: 'formKey', title: '表单编号', visible: true }, + { key: 'formName', title: '表单名称', visible: true }, + { key: 'formStatus', title: '表单状态', visible: true }, + { key: 'createUserName', title: '创建人', visible: true }, + { key: 'createTime', title: '创建时间', visible: true }, + { key: 'updateTime', title: '最后修改时间', visible: true }, + { key: 'count', title: '项目数量', visible: true }, + ]) + .setRowOperate([ + { title: '编辑', onClick: this.onEdit.bind(this) }, + { title: '删除', onClick: this.onDelete.bind(this) }, + { title: '停用', onClick: this.onSetApprover.bind(this) }, + { title: '预览', onClick: this.onSetApprover.bind(this) }, + ]) + } + + router = inject(Router) + + onEdit(v: NzSafeAny) { + this.router.navigate(['/fixed-asset/basic/flow-form/manage/', v.formKey]) + } + + onDelete(data: NzSafeAny) { + this.modal.confirm({ + nzTitle: '警告', + nzContent: '是否要删除该流程表单?', + nzOnOk: async () => { + const res = await lastValueFrom(this.api.deleteFlowForm([data.formTempId])) + this.table.ref.reload() + this.msg.success(res.desc) + }, + }) + } + + fetchData(p: {}, q: AnyObject) { + return this.api.getFlowFormsList({ ...p, ...q }).pipe() + } + + onSetApprover(data?: NzSafeAny) { + if (data) { + this.createForm.patchValue({ + formId: data.formId, + userId: data._assignee.userId ? [data._assignee.userId] : [], + }) + } + this.modal.create({ + nzTitle: '设置审批人', + nzContent: this.createFormTpl, + nzOnOk: async () => { + if (FormValidators.validateFormGroup(this.createForm)) { + const vals = this.createForm.value + const res = await lastValueFrom( + this.api.setFlowFormsAssignee({ + ...vals, + userId: vals.userId?.[0], + }), + ) + this.msg.success(res.desc) + this.table.ref.reload() + this.createForm.reset() + return true + } + return false + }, + nzOnCancel: () => { + this.createForm.reset() + }, + }) + } +} diff --git a/web-admin-app/src/app/pages/fixed-asset/fixed-asset.component.html b/web-admin-app/src/app/pages/fixed-asset/fixed-asset.component.html index eb2f0a7..6edf87b 100644 --- a/web-admin-app/src/app/pages/fixed-asset/fixed-asset.component.html +++ b/web-admin-app/src/app/pages/fixed-asset/fixed-asset.component.html @@ -17,13 +17,16 @@ [routerLink]="['/fixed-asset/ledger']" nzMatchRouter > - 固资台账 + 资产台账 +
  • 资产登记
  • +
  • + 资产管理 +
  • +
  • +
      -
    • - 资产管理 -
    • -
    • - 资产入库 -
    • -
    • - 资产领用 -
    • -
    • - 资产退库 +
    • + 维修登记
    • -
    • - 资产借用 -
    • -
    • - 资产归还 +
    • + 开关机
    • +
    +
  • +
  • +
    • - 资产调拨 + 巡检计划
    • - 资产转移 + 巡检任务
    • - 资产报废 + 巡检日历
    • - -
  • -
    • - 维修登记 + 保养计划
    • - 故障登记 + 保养任务 +
    • +
    • + 保养日历
  • -
  • 盘点任务
  • +
  • + 盘点日历 +
  • -
  • - + -->
  • - 物品分类 + 资产分类 +
  • +
  • + 流程表单
  • 维修类型
  • +
  • + 维修类型 +
  • +
  • + 班组管理 +
  • diff --git a/web-admin-app/src/app/pages/fixed-asset/maintain/maintain-on-off/maintain-on-off.component.html b/web-admin-app/src/app/pages/fixed-asset/maintain/maintain-on-off/maintain-on-off.component.html new file mode 100644 index 0000000..baa68a2 --- /dev/null +++ b/web-admin-app/src/app/pages/fixed-asset/maintain/maintain-on-off/maintain-on-off.component.html @@ -0,0 +1,106 @@ + + + + + + + +
    + + + @switch (key) { + @case ('_category') { + {{ data?.categoryName }} + } + @case ('_ownCompany') { + {{ data?.organizationName }} + } + @case ('status') { + + {{ ASSET_STATUS_MAP[data] }} + + } + @case ('_useOrganization') { + {{ data?.organizationName }} + } + @case ('_position') { + {{ data?.name }} + } + @case ('deviceStatus') { + + 运行中 + + + 已关机 + + } + @default { + {{ data }} + } + } + + + + + + + + + + + + + @for (item of ASSET_STATUS_MAP | keyvalue; track $index) { + + } + + + + + + + + + + + + + +
    +
    diff --git a/web-admin-app/src/app/pages/fixed-asset/maintain/maintain-on-off/maintain-on-off.component.less b/web-admin-app/src/app/pages/fixed-asset/maintain/maintain-on-off/maintain-on-off.component.less new file mode 100644 index 0000000..e69de29 diff --git a/web-admin-app/src/app/pages/fixed-asset/maintain/maintain-on-off/maintain-on-off.component.ts b/web-admin-app/src/app/pages/fixed-asset/maintain/maintain-on-off/maintain-on-off.component.ts new file mode 100644 index 0000000..a4a349e --- /dev/null +++ b/web-admin-app/src/app/pages/fixed-asset/maintain/maintain-on-off/maintain-on-off.component.ts @@ -0,0 +1,105 @@ +import { Component, TemplateRef, ViewChild } from '@angular/core' +import { FormControl, FormGroup } from '@angular/forms' + +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' +import { lastValueFrom, of } from 'rxjs' +import { NzSafeAny } from 'ng-zorro-antd/core/types' +import { NzModalService } from 'ng-zorro-antd/modal' +import { NzMessageService } from 'ng-zorro-antd/message' +import { ASSET_STATUS_MAP, ASSET_TYPE } from 'app/constants' +import { PositionSelectComponent } from 'app/components' + +@Component({ + selector: 'app-maintain-on-off', + standalone: true, + imports: [SharedModule, PositionSelectComponent], + templateUrl: './maintain-on-off.component.html', + styleUrl: './maintain-on-off.component.less', +}) +export class MaintainOnOffComponent { + constructor( + private api: ApiService, + private modal: NzModalService, + private msg: NzMessageService, + ) {} + + queryForm = new FormGroup({ + model: new FormControl(), + name: new FormControl(), + status: new FormControl(), + assetCode: new FormControl(), + positionId: new FormControl(), + }) + + table = new TableOption(this.fetchData.bind(this)) + + ASSET_STATUS_MAP = ASSET_STATUS_MAP() + + ASSET_TYPE = ASSET_TYPE + ngOnInit(): void { + this.table + .setConfig({ + selectable: true, + rowKey: 'assetId', + }) + .setColumn([ + { key: 'serialNumber', title: '序号', visible: true }, + { key: 'assetCode', title: '资产编号', visible: true }, + { key: 'name', title: '资产名称', visible: true }, + { key: '_category', title: '资产分类', visible: true }, + { key: 'status', title: '资产状态', visible: true }, + { key: '_ownCompany', title: '所属公司', visible: true }, + { key: '_useOrganization', title: '使用组织', visible: true }, + { key: '_position', title: '位置信息', visible: true }, + { key: 'deviceStatus', title: '当前状态', visible: true }, + ]) + .setRowOperate([ + // { title: '修改', onClick: this.onCreate.bind(this) }, + + { + title: '开机', + visible(v) { + return v.deviceStatus === 'OFF' + }, + onClick: (v) => { + this.onOff([v.assetId], 1) + }, + }, + { + title: '关机', + visible(v) { + return v.deviceStatus === 'ON' + }, + onClick: (v) => { + this.onOff([v.assetId], 0) + }, + }, + { title: '记录', onClick: this.onOff.bind(this, [0]) }, + ]) + } + + fetchData(p: {}, q: AnyObject) { + return this.api.getDeviceOnOffPage({ ...p, ...q }) + } + + onOff(ids: any[], type: number) { + console.log('type', ids, type) + const typeText = type === 1 ? '开机' : '关机' + this.modal.confirm({ + nzTitle: '警告', + nzContent: `是否要${typeText}${ids.length}个设备?`, + nzOnOk: async () => { + const res = await lastValueFrom(this.api.onOffDevice(ids, type)) + this.msg.success(res.desc) + this.table.ref.reload() + }, + }) + } + + batchOnOff(type: number) { + this.onOff(Array.from(this.table.ref.selected), type) + } +} diff --git a/web-admin-app/src/app/pages/fixed-asset/maintain/maintain-record/maintain-record.component.html b/web-admin-app/src/app/pages/fixed-asset/maintain/maintain-record/maintain-record.component.html new file mode 100644 index 0000000..f9dc5af --- /dev/null +++ b/web-admin-app/src/app/pages/fixed-asset/maintain/maintain-record/maintain-record.component.html @@ -0,0 +1,38 @@ + + + + + + +
    + + + @switch (key) { + @default { + {{ data }} + } + } + + + + + + + + + + + + + + + +
    +
    diff --git a/web-admin-app/src/app/pages/fixed-asset/maintain/maintain-record/maintain-record.component.less b/web-admin-app/src/app/pages/fixed-asset/maintain/maintain-record/maintain-record.component.less new file mode 100644 index 0000000..e69de29 diff --git a/web-admin-app/src/app/pages/fixed-asset/maintain/maintain-record/maintain-record.component.ts b/web-admin-app/src/app/pages/fixed-asset/maintain/maintain-record/maintain-record.component.ts new file mode 100644 index 0000000..71b1197 --- /dev/null +++ b/web-admin-app/src/app/pages/fixed-asset/maintain/maintain-record/maintain-record.component.ts @@ -0,0 +1,97 @@ +import { Component, TemplateRef, ViewChild } from '@angular/core' +import { FormControl, FormGroup } from '@angular/forms' + +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' +import { lastValueFrom, of } from 'rxjs' +import { NzSafeAny } from 'ng-zorro-antd/core/types' +import { NzModalService } from 'ng-zorro-antd/modal' +import { NzMessageService } from 'ng-zorro-antd/message' +import { RepairFormComponent } from 'app/components' +import { MaintainRecordFormComponent } from 'app/components/maintain-record-form/maintain-record-form.component' + +@Component({ + selector: 'app-maintain-record', + standalone: true, + imports: [SharedModule], + templateUrl: './maintain-record.component.html', + styleUrl: './maintain-record.component.less', +}) +export class MaintainRecordComponent { + constructor( + private api: ApiService, + private modal: NzModalService, + private msg: NzMessageService, + ) {} + + queryForm = new FormGroup({ + name: new FormControl(''), + businessId: new FormControl(''), + }) + + table = new TableOption(this.fetchData.bind(this)) + + ngOnInit(): void { + this.table + // .setConfig({ + // selectable: true, + // rowKey: 'id', + // }) + .setColumn([ + { key: 'name', title: '业务名称', visible: true }, + { key: 'businessId', title: '业务编号', visible: true }, + { key: 'plannedDate', title: '计划完成时间', visible: true }, + + { key: 'notes', title: '备注', visible: true }, + { key: 'createTime', title: '创建时间', visible: true }, + ]) + .setRowOperate([ + { title: '修改', onClick: this.onCreate.bind(this) }, + + { title: '删除', onClick: this.deleteItem.bind(this) }, + ]) + } + + fetchData(p: {}, q: AnyObject) { + return this.api.getRepairPage({ ...p, ...q }) + } + + onCreate(data?: NzSafeAny, preview?: boolean) { + this.modal.create({ + nzTitle: data ? '编辑维修登记' : '添加维修登记', + nzContent: MaintainRecordFormComponent, + nzWidth: '80vw', + nzWrapClassName: 'modal-lg', + nzData: { + value: data, + preview, + }, + nzOnOk: async (e) => { + const vals = e.getValues() + if (vals) { + const res = await lastValueFrom(this.api.saveRepair(vals)) + this.msg.success(res.desc) + this.table.ref.reload() + return true + } + + return false + }, + }) + } + + deleteItem(item?: NzSafeAny) { + const ids = [item.id] + this.modal.confirm({ + nzTitle: '警告', + nzContent: `是否要删除${ids.length}个维修登记?`, + nzOnOk: async () => { + const res = await lastValueFrom(this.api.deleteRepair(ids)) + this.msg.success(res.desc) + this.table.ref.reload() + }, + }) + } +} diff --git a/web-admin-app/src/app/pages/fixed-asset/plan-task/inspection-calendar/inspection-calendar.component.html b/web-admin-app/src/app/pages/fixed-asset/plan-task/inspection-calendar/inspection-calendar.component.html new file mode 100644 index 0000000..9e8fcbf --- /dev/null +++ b/web-admin-app/src/app/pages/fixed-asset/plan-task/inspection-calendar/inspection-calendar.component.html @@ -0,0 +1 @@ + diff --git a/web-admin-app/src/app/pages/fixed-asset/plan-task/inspection-calendar/inspection-calendar.component.less b/web-admin-app/src/app/pages/fixed-asset/plan-task/inspection-calendar/inspection-calendar.component.less new file mode 100644 index 0000000..e69de29 diff --git a/web-admin-app/src/app/pages/fixed-asset/plan-task/inspection-calendar/inspection-calendar.component.ts b/web-admin-app/src/app/pages/fixed-asset/plan-task/inspection-calendar/inspection-calendar.component.ts new file mode 100644 index 0000000..d881a01 --- /dev/null +++ b/web-admin-app/src/app/pages/fixed-asset/plan-task/inspection-calendar/inspection-calendar.component.ts @@ -0,0 +1,12 @@ +import { Component } from '@angular/core' +import { CalendarListComponent } from 'app/components/plan-task/calendar-list/calendar-list.component' +import { SharedModule } from 'app/shared/shared.module' + +@Component({ + selector: 'app-inspection-calendar', + standalone: true, + imports: [SharedModule, CalendarListComponent], + templateUrl: './inspection-calendar.component.html', + styleUrl: './inspection-calendar.component.less', +}) +export class InspectionCalendarComponent {} diff --git a/web-admin-app/src/app/pages/fixed-asset/plan-task/inspection-plan/inspection-plan.component.html b/web-admin-app/src/app/pages/fixed-asset/plan-task/inspection-plan/inspection-plan.component.html new file mode 100644 index 0000000..ad67fb4 --- /dev/null +++ b/web-admin-app/src/app/pages/fixed-asset/plan-task/inspection-plan/inspection-plan.component.html @@ -0,0 +1 @@ + diff --git a/web-admin-app/src/app/pages/fixed-asset/plan-task/inspection-plan/inspection-plan.component.less b/web-admin-app/src/app/pages/fixed-asset/plan-task/inspection-plan/inspection-plan.component.less new file mode 100644 index 0000000..e69de29 diff --git a/web-admin-app/src/app/pages/fixed-asset/plan-task/inspection-plan/inspection-plan.component.ts b/web-admin-app/src/app/pages/fixed-asset/plan-task/inspection-plan/inspection-plan.component.ts new file mode 100644 index 0000000..1d1b9cf --- /dev/null +++ b/web-admin-app/src/app/pages/fixed-asset/plan-task/inspection-plan/inspection-plan.component.ts @@ -0,0 +1,13 @@ +import { Component } from '@angular/core' +import { PlanListComponent } from 'app/components/plan-task/plan-list/plan-list.component' +import { TaskListComponent } from 'app/components/plan-task/task-list/task-list.component' +import { SharedModule } from 'app/shared/shared.module' + +@Component({ + selector: 'app-inspection-plan', + standalone: true, + imports: [SharedModule, PlanListComponent], + templateUrl: './inspection-plan.component.html', + styleUrl: './inspection-plan.component.less', +}) +export class InspectionPlanComponent {} diff --git a/web-admin-app/src/app/pages/fixed-asset/plan-task/inspection-task/inspection-task.component.html b/web-admin-app/src/app/pages/fixed-asset/plan-task/inspection-task/inspection-task.component.html new file mode 100644 index 0000000..b07e295 --- /dev/null +++ b/web-admin-app/src/app/pages/fixed-asset/plan-task/inspection-task/inspection-task.component.html @@ -0,0 +1 @@ + diff --git a/web-admin-app/src/app/pages/fixed-asset/plan-task/inspection-task/inspection-task.component.less b/web-admin-app/src/app/pages/fixed-asset/plan-task/inspection-task/inspection-task.component.less new file mode 100644 index 0000000..e69de29 diff --git a/web-admin-app/src/app/pages/fixed-asset/plan-task/inspection-task/inspection-task.component.ts b/web-admin-app/src/app/pages/fixed-asset/plan-task/inspection-task/inspection-task.component.ts new file mode 100644 index 0000000..44665b0 --- /dev/null +++ b/web-admin-app/src/app/pages/fixed-asset/plan-task/inspection-task/inspection-task.component.ts @@ -0,0 +1,12 @@ +import { Component } from '@angular/core' +import { TaskListComponent } from 'app/components/plan-task/task-list/task-list.component' +import { SharedModule } from 'app/shared/shared.module' + +@Component({ + selector: 'app-inspection-task', + standalone: true, + imports: [SharedModule, TaskListComponent], + templateUrl: './inspection-task.component.html', + styleUrl: './inspection-task.component.less', +}) +export class InspectionTaskComponent {} diff --git a/web-admin-app/src/app/pages/fixed-asset/plan-task/maintenance-calendar/maintenance-calendar.component.html b/web-admin-app/src/app/pages/fixed-asset/plan-task/maintenance-calendar/maintenance-calendar.component.html new file mode 100644 index 0000000..b154ece --- /dev/null +++ b/web-admin-app/src/app/pages/fixed-asset/plan-task/maintenance-calendar/maintenance-calendar.component.html @@ -0,0 +1 @@ +

    maintenance-calendar works!

    diff --git a/web-admin-app/src/app/pages/fixed-asset/plan-task/maintenance-calendar/maintenance-calendar.component.less b/web-admin-app/src/app/pages/fixed-asset/plan-task/maintenance-calendar/maintenance-calendar.component.less new file mode 100644 index 0000000..e69de29 diff --git a/web-admin-app/src/app/pages/fixed-asset/plan-task/maintenance-calendar/maintenance-calendar.component.ts b/web-admin-app/src/app/pages/fixed-asset/plan-task/maintenance-calendar/maintenance-calendar.component.ts new file mode 100644 index 0000000..dfbe11e --- /dev/null +++ b/web-admin-app/src/app/pages/fixed-asset/plan-task/maintenance-calendar/maintenance-calendar.component.ts @@ -0,0 +1,12 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-maintenance-calendar', + standalone: true, + imports: [], + templateUrl: './maintenance-calendar.component.html', + styleUrl: './maintenance-calendar.component.less' +}) +export class MaintenanceCalendarComponent { + +} diff --git a/web-admin-app/src/app/pages/fixed-asset/plan-task/maintenance-plan/maintenance-plan.component.html b/web-admin-app/src/app/pages/fixed-asset/plan-task/maintenance-plan/maintenance-plan.component.html new file mode 100644 index 0000000..ed5167f --- /dev/null +++ b/web-admin-app/src/app/pages/fixed-asset/plan-task/maintenance-plan/maintenance-plan.component.html @@ -0,0 +1 @@ +

    maintenance-plan works!

    diff --git a/web-admin-app/src/app/pages/fixed-asset/plan-task/maintenance-plan/maintenance-plan.component.less b/web-admin-app/src/app/pages/fixed-asset/plan-task/maintenance-plan/maintenance-plan.component.less new file mode 100644 index 0000000..e69de29 diff --git a/web-admin-app/src/app/pages/fixed-asset/plan-task/maintenance-plan/maintenance-plan.component.ts b/web-admin-app/src/app/pages/fixed-asset/plan-task/maintenance-plan/maintenance-plan.component.ts new file mode 100644 index 0000000..700a87a --- /dev/null +++ b/web-admin-app/src/app/pages/fixed-asset/plan-task/maintenance-plan/maintenance-plan.component.ts @@ -0,0 +1,12 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-maintenance-plan', + standalone: true, + imports: [], + templateUrl: './maintenance-plan.component.html', + styleUrl: './maintenance-plan.component.less' +}) +export class MaintenancePlanComponent { + +} diff --git a/web-admin-app/src/app/pages/fixed-asset/plan-task/maintenance-task/maintenance-task.component.html b/web-admin-app/src/app/pages/fixed-asset/plan-task/maintenance-task/maintenance-task.component.html new file mode 100644 index 0000000..b4d674b --- /dev/null +++ b/web-admin-app/src/app/pages/fixed-asset/plan-task/maintenance-task/maintenance-task.component.html @@ -0,0 +1 @@ +

    maintenance-task works!

    diff --git a/web-admin-app/src/app/pages/fixed-asset/plan-task/maintenance-task/maintenance-task.component.less b/web-admin-app/src/app/pages/fixed-asset/plan-task/maintenance-task/maintenance-task.component.less new file mode 100644 index 0000000..e69de29 diff --git a/web-admin-app/src/app/pages/fixed-asset/plan-task/maintenance-task/maintenance-task.component.ts b/web-admin-app/src/app/pages/fixed-asset/plan-task/maintenance-task/maintenance-task.component.ts new file mode 100644 index 0000000..2e8cd2b --- /dev/null +++ b/web-admin-app/src/app/pages/fixed-asset/plan-task/maintenance-task/maintenance-task.component.ts @@ -0,0 +1,12 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-maintenance-task', + standalone: true, + imports: [], + templateUrl: './maintenance-task.component.html', + styleUrl: './maintenance-task.component.less' +}) +export class MaintenanceTaskComponent { + +} diff --git a/web-admin-app/src/app/pages/fixed-asset/plan-task/stocktaking-calendar/stocktaking-calendar.component.html b/web-admin-app/src/app/pages/fixed-asset/plan-task/stocktaking-calendar/stocktaking-calendar.component.html new file mode 100644 index 0000000..f1369e0 --- /dev/null +++ b/web-admin-app/src/app/pages/fixed-asset/plan-task/stocktaking-calendar/stocktaking-calendar.component.html @@ -0,0 +1 @@ +

    stocktaking-calendar works!

    diff --git a/web-admin-app/src/app/pages/fixed-asset/plan-task/stocktaking-calendar/stocktaking-calendar.component.less b/web-admin-app/src/app/pages/fixed-asset/plan-task/stocktaking-calendar/stocktaking-calendar.component.less new file mode 100644 index 0000000..e69de29 diff --git a/web-admin-app/src/app/pages/fixed-asset/plan-task/stocktaking-calendar/stocktaking-calendar.component.ts b/web-admin-app/src/app/pages/fixed-asset/plan-task/stocktaking-calendar/stocktaking-calendar.component.ts new file mode 100644 index 0000000..004aaf5 --- /dev/null +++ b/web-admin-app/src/app/pages/fixed-asset/plan-task/stocktaking-calendar/stocktaking-calendar.component.ts @@ -0,0 +1,12 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-stocktaking-calendar', + standalone: true, + imports: [], + templateUrl: './stocktaking-calendar.component.html', + styleUrl: './stocktaking-calendar.component.less' +}) +export class StocktakingCalendarComponent { + +} diff --git a/web-admin-app/src/app/pages/fixed-asset/plan-task/stocktaking-plan/stocktaking-plan.component.html b/web-admin-app/src/app/pages/fixed-asset/plan-task/stocktaking-plan/stocktaking-plan.component.html new file mode 100644 index 0000000..92aa86a --- /dev/null +++ b/web-admin-app/src/app/pages/fixed-asset/plan-task/stocktaking-plan/stocktaking-plan.component.html @@ -0,0 +1 @@ +

    stocktaking-plan works!

    diff --git a/web-admin-app/src/app/pages/fixed-asset/plan-task/stocktaking-plan/stocktaking-plan.component.less b/web-admin-app/src/app/pages/fixed-asset/plan-task/stocktaking-plan/stocktaking-plan.component.less new file mode 100644 index 0000000..e69de29 diff --git a/web-admin-app/src/app/pages/fixed-asset/plan-task/stocktaking-plan/stocktaking-plan.component.ts b/web-admin-app/src/app/pages/fixed-asset/plan-task/stocktaking-plan/stocktaking-plan.component.ts new file mode 100644 index 0000000..feda974 --- /dev/null +++ b/web-admin-app/src/app/pages/fixed-asset/plan-task/stocktaking-plan/stocktaking-plan.component.ts @@ -0,0 +1,12 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-stocktaking-plan', + standalone: true, + imports: [], + templateUrl: './stocktaking-plan.component.html', + styleUrl: './stocktaking-plan.component.less' +}) +export class StocktakingPlanComponent { + +} diff --git a/web-admin-app/src/app/pages/fixed-asset/plan-task/stocktaking-task/stocktaking-task.component.html b/web-admin-app/src/app/pages/fixed-asset/plan-task/stocktaking-task/stocktaking-task.component.html new file mode 100644 index 0000000..9f7cd97 --- /dev/null +++ b/web-admin-app/src/app/pages/fixed-asset/plan-task/stocktaking-task/stocktaking-task.component.html @@ -0,0 +1 @@ +

    stocktaking-task works!

    diff --git a/web-admin-app/src/app/pages/fixed-asset/plan-task/stocktaking-task/stocktaking-task.component.less b/web-admin-app/src/app/pages/fixed-asset/plan-task/stocktaking-task/stocktaking-task.component.less new file mode 100644 index 0000000..e69de29 diff --git a/web-admin-app/src/app/pages/fixed-asset/plan-task/stocktaking-task/stocktaking-task.component.ts b/web-admin-app/src/app/pages/fixed-asset/plan-task/stocktaking-task/stocktaking-task.component.ts new file mode 100644 index 0000000..a0329b7 --- /dev/null +++ b/web-admin-app/src/app/pages/fixed-asset/plan-task/stocktaking-task/stocktaking-task.component.ts @@ -0,0 +1,12 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-stocktaking-task', + standalone: true, + imports: [], + templateUrl: './stocktaking-task.component.html', + styleUrl: './stocktaking-task.component.less' +}) +export class StocktakingTaskComponent { + +} diff --git a/web-admin-app/src/app/pages/fixed-asset/registration/registration.component.html b/web-admin-app/src/app/pages/fixed-asset/registration/registration.component.html new file mode 100644 index 0000000..e24357a --- /dev/null +++ b/web-admin-app/src/app/pages/fixed-asset/registration/registration.component.html @@ -0,0 +1,283 @@ + + + + + + + + + + +
    + + + @switch (key) { + @case ('status') { + + {{ ASSET_STATUS_MAP[data] }} + + } + @case ('_useUser') { + {{ data?.userName ?? '-' }} + } + @case ('_warehouse') { + {{ data?.name ?? '-' }} + } + @case ('_position') { + {{ data?.name ?? '-' }} + } + @case ('_head') { + {{ data?.userName ?? '-' }} + } + @case ('_ownCompany') { + {{ data?.organizationName ?? '-' }} + } + @case ('_useOrganization') { + {{ data?.organizationName ?? '-' }} + } + @case ('_category') { + {{ data?.categoryName ?? '-' }} + } + @default { + {{ data }} + } + } + + + + + + + + + + + + + + + + + + + @for (item of ASSET_STATUS_MAP | keyvalue; track $index) { + + } + + + + + @for (item of ASSET_SOURCE_MAP | keyvalue; track $index) { + + } + + + + + + + + + + + + + +
    +
    + + +
    + + + 1、为了保证复制速度,一次最多可复制200个资产
    + 2、以下资产信息不可被复制:资产编码、资产编码(旧)、序列号、使用人、管理人、入库时间、累计折旧、残值、净值
    + 3、复制后的资产状态为空闲 +
    +
    +
    + + 复制数量 + + + + +
    +
    +
    + +
    +
    + + 模版文件 + + + + + + 文件 + + + + +
    + + + 按照要求填写Excel数据,系统会对部分字段做验证!
    + 资产导入规则 字段填写要求:
    + 1、资产编码:资产编号由后台自动生成,导入数据时不填写
    + 2、资产分类:填写系统中存在的资产分类名称,若资产分类存在重名时,请同时填写上资产分类的id
    + 3、所属公司:填写系统中存在的公司名称,若公司存在重名时,请同时填写上公司的id
    + 4、使用组织:填写系统中存在的组织名称,若组织存在重名时,请同时填写上组织的id
    + 5、管理人员:填写系统中存在的管理员姓名,若管理员姓名存在重名时,请同时填写上管理员id
    + 6、供应商:填写系统中存在的供应商名称,若供应商存在重名时,请同时填写上供应商的id
    + 7、资产厂商:填写系统中存在的资产厂商名称,若资产厂商存在重名时,请同时填写上资产厂商的id
    + 8、使用人员:填写系统中存在的账户姓名,若账户姓名存在重名时,请同时填写上使用人员id
    + 9、存放位置:填写系统中存在的存放位置名称,若存放位置名称存在重名时,请同时填写上存放位置id
    + 10、维保信息_维保厂商:填写系统中存在的维保厂商名称,若维保厂商名称存在重名时,请同时填写上维保厂商id
    + 11、日期格式:yyyy-MM-dd HH:mm:ss
    + 12、财务信息:保留2位小数,若您填写超过2位小数后,系统会自动做四舍五入处理
    +
    +
    +
    +
    diff --git a/web-admin-app/src/app/pages/fixed-asset/registration/registration.component.less b/web-admin-app/src/app/pages/fixed-asset/registration/registration.component.less new file mode 100644 index 0000000..e69de29 diff --git a/web-admin-app/src/app/pages/fixed-asset/registration/registration.component.ts b/web-admin-app/src/app/pages/fixed-asset/registration/registration.component.ts new file mode 100644 index 0000000..bcde03d --- /dev/null +++ b/web-admin-app/src/app/pages/fixed-asset/registration/registration.component.ts @@ -0,0 +1,208 @@ +import { Component, TemplateRef, ViewChild } from '@angular/core' +import { FormControl, FormGroup } from '@angular/forms' + +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' +import { lastValueFrom, of } from 'rxjs' +import { AssetFormComponent, ManufacturerSelectComponent, PositionSelectComponent } from 'app/components' +import { NzModalRef, NzModalService } from 'ng-zorro-antd/modal' +import { NzMessageService } from 'ng-zorro-antd/message' +import { NzSafeAny } from 'ng-zorro-antd/core/types' +import { ASSET_SOURCE_MAP, ASSET_STATUS, ASSET_STATUS_MAP } from 'app/constants' +import { Utils } from 'app/utils' + +@Component({ + selector: 'app-fixed-asset-registration', + standalone: true, + imports: [SharedModule, AssetFormComponent, PositionSelectComponent, ManufacturerSelectComponent], + templateUrl: './registration.component.html', + styleUrl: './registration.component.less', +}) +export class RegistrationComponent { + constructor( + private api: ApiService, + private modal: NzModalService, + private msg: NzMessageService, + ) {} + + queryForm = new FormGroup({ + name: new FormControl(), + model: new FormControl(), + status: new FormControl(), + assetCode: new FormControl(), + serialNumber: new FormControl(), + sourceId: new FormControl(), + positionId: new FormControl(), + manufacturersVendorId: new FormControl(), + }) + + @ViewChild('copyTpl') copyTpl!: TemplateRef + + ASSET_STATUS_MAP = ASSET_STATUS_MAP() + + ASSET_SOURCE_MAP = ASSET_SOURCE_MAP + + table = new TableOption(this.fetchData.bind(this)) + + copyNum = 1 + + ngOnInit(): void { + this.table + .setConfig({ + selectable: true, + rowKey: 'assetId', + }) + .setColumn([ + { key: 'assetCode', title: '资产编号', visible: true }, + { key: 'name', title: '资产名称', visible: true }, + { key: '_category', title: '资产分类', visible: true }, + { key: 'status', title: '资产状态', visible: true }, + { key: '_ownCompany', title: '所属公司', visible: true }, + { key: '_useOrganization', title: '使用组织', visible: true }, + { key: '_position', title: '存放位置', visible: true }, + ]) + .setRowOperate([ + { + title: '查看', + onClick: (v) => { + this.onCreate(v, true) + }, + }, + { title: '修改', onClick: this.onCreate.bind(this) }, + { title: '复制', onClick: this.onCopy.bind(this) }, + { title: '二维码', onClick: this.qrcode.bind(this) }, + { title: '删除', onClick: this.deleteItem.bind(this) }, + ]) + } + + fetchData(p: {}, q: AnyObject) { + return this.api.getAssetPage({ ...p, ...q }) + } + + onCopy(data: NzSafeAny) { + this.modal.create({ + nzTitle: '复制资产', + nzWidth: 600, + nzContent: this.copyTpl, + nzOnOk: async () => { + if (!this.copyNum) { + this.msg.error('请输入复制数量') + return false + } + const res = await lastValueFrom(this.api.copyAsset(this.copyNum, data.assetId)) + this.msg.success(res.desc) + this.table.ref.reload() + return true + }, + }) + } + + onCreate(data?: NzSafeAny, preview?: boolean) { + let nzTitle = data ? '编辑资产' : '添加资产' + if (preview) { + nzTitle = '预览资产' + } + this.modal.create({ + nzTitle, + nzContent: AssetFormComponent, + nzWidth: '80vw', + nzWrapClassName: 'modal-lg', + nzData: { + value: data, + preview, + }, + nzOnOk: async (e) => { + const vals = e.getValues() + if (vals) { + const res = await lastValueFrom(this.api.saveAsset(vals)) + this.msg.success(res.desc) + this.table.ref.reload() + return true + } + + return false + }, + }) + } + + deleteItem(item?: NzSafeAny) { + const ids = item ? [item.assetId] : Array.from(this.table.ref.selected) + this.modal.confirm({ + nzTitle: '警告', + nzContent: `是否要删除${ids.length}个资产?`, + nzOnOk: async () => { + const res = await lastValueFrom(this.api.deleteAsset(ids)) + this.msg.success(res.desc) + this.table.ref.reload() + }, + }) + } + + confirmAsset() { + const ids = Array.from(this.table.ref.selected).map((i) => Number(i)) + this.modal.confirm({ + nzTitle: '警告', + nzContent: `是否对选择的${ids.length}个资产进行确认?`, + nzOnOk: async () => { + const res = await lastValueFrom(this.api.confirmAsset(ids)) + this.msg.success(res.desc) + this.table.ref.reload() + }, + }) + } + + qrcode(d: NzSafeAny) { + this.msg.loading('二维码生成中...') + this.api.assetQrcode(d.assetId).subscribe((res) => { + Utils.downLoadFile(res, 'application/pdf') + this.msg.remove() + this.msg.success('二维码生成成功') + }) + } + + downloadTemplate() { + this.msg.loading('模板下载中...') + this.api.downloadAssetTemplate().subscribe((res) => { + Utils.downLoadFile(res, 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8') + this.msg.remove() + this.msg.success('模板下载成功') + }) + } + + importModalRef?: NzModalRef + importExcel(nzContent: TemplateRef<{}>) { + this.importModalRef = this.modal.create({ + nzTitle: '资产数据导入', + nzContent, + nzWidth: 800, + nzFooter: null, + }) + } + + onFileChange(e: Event) { + const target = e.target as HTMLInputElement + const file = target.files![0] + target.value = '' + const formdata = new FormData() + formdata.append('file', file) + this.api.uploadAsset(formdata).subscribe((res) => { + this.importModalRef?.close() + this.msg.success(res.desc) + this.table.ref.reload() + }) + } + exportExcel() { + const ids = Array.from(this.table.ref.selected).map((i) => Number(i)) + if (ids.length === 0) { + return + } + this.msg.loading('Excel生成中...') + this.api.exportAsset(ids).subscribe((res) => { + Utils.downLoadFile(res, 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8') + this.msg.remove() + this.msg.success('Excel生成成功') + }) + } +} diff --git a/web-admin-app/src/app/pages/flow/flow-main/flow-main.component.html b/web-admin-app/src/app/pages/flow/flow-main/flow-main.component.html index 574932e..412ec50 100644 --- a/web-admin-app/src/app/pages/flow/flow-main/flow-main.component.html +++ b/web-admin-app/src/app/pages/flow/flow-main/flow-main.component.html @@ -1,37 +1,124 @@ - -
    - @for (item of assetFlows; track $index) { -
    - -
    -
    -
    - +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    + + +
    + @for (item of assetFlows; track $index) { +
    +
    +
    +
    +
    + +
    +
    +
    +
    + {{ item.name }} +
    +
    +
    +
    +
    + } +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    报修维修
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    巡检任务
    -
    -
    - {{ item.name }} -
    -
    {{ item.formKey }}
    - @if (item._assignee) { -
    - 审批人:{{ item._assignee.userName }} +
    +
    +
    +
    +
    +
    +
    +
    - } +
    +
    +
    保养任务
    +
    - - @if (item.enabled) { -
    发起流程
    - } @else { -
    没有表单
    - } -
    - +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    盘点任务
    +
    +
    +
    +
    - } -
    - + + +
    diff --git a/web-admin-app/src/app/pages/flow/flow-main/flow-main.component.less b/web-admin-app/src/app/pages/flow/flow-main/flow-main.component.less index 8bf95c1..0b2a335 100644 --- a/web-admin-app/src/app/pages/flow/flow-main/flow-main.component.less +++ b/web-admin-app/src/app/pages/flow/flow-main/flow-main.component.less @@ -1,7 +1,7 @@ .icon { - width: 48px; - height: 48px; - border-radius: 8px; + width: 60px; + height: 60px; + border-radius: 50%; overflow: hidden; background-image: linear-gradient(135deg, #77abf4, #2f7deb); font-size: 32px; diff --git a/web-admin-app/src/app/pages/flow/flow-main/flow-main.component.ts b/web-admin-app/src/app/pages/flow/flow-main/flow-main.component.ts index 927dd3a..baf85cb 100644 --- a/web-admin-app/src/app/pages/flow/flow-main/flow-main.component.ts +++ b/web-admin-app/src/app/pages/flow/flow-main/flow-main.component.ts @@ -9,8 +9,12 @@ import { EamAssetPurchaseApplyComponent, EamAssetStockGoodsUseComponent, } from 'app/components' +import { RepairTaskFormComponent } from 'app/components/plan-task/repair-task-form/repair-task-form.component' +import { TaskFormComponent } from 'app/components/plan-task/task-form/task-form.component' +import { taskTypeTitle } from 'app/constants' import { ApiService } from 'app/services' import { SharedModule } from 'app/shared/shared.module' +import { PlanTaskType } from 'app/types' import { NzSafeAny } from 'ng-zorro-antd/core/types' import { NzMessageService } from 'ng-zorro-antd/message' import { NzModalService } from 'ng-zorro-antd/modal' @@ -88,4 +92,35 @@ export class FlowMainComponent implements OnInit { }, }) } + + createTask(type: PlanTaskType) { + const nzTitle = '创建' + taskTypeTitle.get(type) + '任务' + this.modal.create({ + nzTitle, + nzContent: type === 'repair' ? RepairTaskFormComponent : TaskFormComponent, + nzWrapClassName: 'modal-lg', + nzWidth: '80vw', + + nzData: { + value: null, + preview: false, + }, + nzOnOk: async (e: NzSafeAny) => { + const vals = e.getValues() + console.log('vals', vals) + if (vals) { + if (type === 'repair') { + const res = await lastValueFrom(this.api.createRapairTask(vals)) + this.msg.success(res.desc) + } + + return true + } + return false + }, + nzOnCancel: () => { + console.log('Cancel') + }, + }) + } } diff --git a/web-admin-app/src/app/pages/system/index/system.component.html b/web-admin-app/src/app/pages/system/index/system.component.html index 407bca9..21bb1d5 100644 --- a/web-admin-app/src/app/pages/system/index/system.component.html +++ b/web-admin-app/src/app/pages/system/index/system.component.html @@ -20,6 +20,22 @@ > 角色管理 +
  • +
      +
    • + 仓库管理 +
    • +
    • + 地址管理 +
    • +
    +
  • +
    + + + +
    + +
    + + 名称 + + + + + + 安全库存 + + + + + + 安全库存上限 + + + + + + 安全库存下限 + + + + + + + + + + + +
    +
    +
    +
    + + + + + diff --git a/web-admin-app/src/app/pages/system/system-address/system-address.component.less b/web-admin-app/src/app/pages/system/system-address/system-address.component.less new file mode 100644 index 0000000..e69de29 diff --git a/web-admin-app/src/app/pages/system/system-address/system-address.component.ts b/web-admin-app/src/app/pages/system/system-address/system-address.component.ts new file mode 100644 index 0000000..44abc83 --- /dev/null +++ b/web-admin-app/src/app/pages/system/system-address/system-address.component.ts @@ -0,0 +1,80 @@ +import { Component, TemplateRef, ViewChild } from '@angular/core' +import { FormBuilder, FormGroup } from '@angular/forms' +import { ComponentBasicCategoryTreeComponent } from 'app/components' +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' + +@Component({ + selector: 'app-system-address', + standalone: true, + imports: [SharedModule, ComponentBasicCategoryTreeComponent], + templateUrl: './system-address.component.html', + styleUrl: './system-address.component.less', +}) +export class SystemAddressComponent { + constructor( + private modal: NzModalService, + private msg: NzMessageService, + private drawer: NzDrawerService, + private api: ApiService, + private fb: FormBuilder, + ) {} + + @ViewChild('treeEl') treeEl!: ComponentBasicCategoryTreeComponent + + queryForm!: FormGroup + + createForm!: FormGroup + + drawerRef?: NzDrawerRef + + @ViewChild('drawerFooterTpl') drawerFooterTpl!: TemplateRef + + @ViewChild('formContentTpl') formContentTpl!: TemplateRef + + initCreateForm() { + this.createForm = this.fb.group({ + categoryId: [], + parentId: ['', [FormValidators.required('请输入')]], + 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) + + this.treeEl.initTree() + }) + } + } +} diff --git a/web-admin-app/src/app/pages/system/system-warehouse/system-warehouse.component.html b/web-admin-app/src/app/pages/system/system-warehouse/system-warehouse.component.html new file mode 100644 index 0000000..92bac12 --- /dev/null +++ b/web-admin-app/src/app/pages/system/system-warehouse/system-warehouse.component.html @@ -0,0 +1,81 @@ + + + + + + +
    +
    + + + @switch (key) { + @case ('status') { + + } + + @default { + {{ data }} + } + } + + + + + + + + + + + + + + +
    +
    +
    + + + + + + + + + +
    + + 名称 + + + + + + 状态 + + + + + + + +
    +
    + + + + diff --git a/web-admin-app/src/app/pages/system/system-warehouse/system-warehouse.component.less b/web-admin-app/src/app/pages/system/system-warehouse/system-warehouse.component.less new file mode 100644 index 0000000..e69de29 diff --git a/web-admin-app/src/app/pages/system/system-warehouse/system-warehouse.component.ts b/web-admin-app/src/app/pages/system/system-warehouse/system-warehouse.component.ts new file mode 100644 index 0000000..22c0a25 --- /dev/null +++ b/web-admin-app/src/app/pages/system/system-warehouse/system-warehouse.component.ts @@ -0,0 +1,125 @@ +import { Component, TemplateRef, ViewChild } from '@angular/core' +import { FormBuilder, FormControl, FormGroup } from '@angular/forms' + +import { AnyObject, TableOption } from 'app/shared/components/server-paginated-table' +import { ApiService } from 'app/services' +import { SharedModule } from 'app/shared/shared.module' +import { lastValueFrom, of } from 'rxjs' +import { NzSafeAny } from 'ng-zorro-antd/core/types' +import { NzModalService } from 'ng-zorro-antd/modal' +import { NzMessageService } from 'ng-zorro-antd/message' +import { FormValidators } from 'app/utils' +import { NzDrawerRef, NzDrawerService } from 'ng-zorro-antd/drawer' + +@Component({ + selector: 'app-system-warehouse', + standalone: true, + imports: [SharedModule], + templateUrl: './system-warehouse.component.html', + styleUrl: './system-warehouse.component.less', +}) +export class SystemWarehouseComponent { + constructor( + private modal: NzModalService, + private msg: NzMessageService, + private drawer: NzDrawerService, + private api: ApiService, + private fb: FormBuilder, + ) {} + + table = new TableOption(this.fetchData.bind(this)) + + queryForm!: FormGroup + + createForm!: FormGroup + + drawerRef?: NzDrawerRef + + @ViewChild('drawerFooterTpl') drawerFooterTpl!: TemplateRef + + @ViewChild('formContentTpl') formContentTpl!: TemplateRef + + initCreateForm() { + this.createForm = this.fb.group({ + warehouseId: [], + name: ['', [FormValidators.required('请输入')]], + status: [0, [FormValidators.required('请选择')]], + notes: ['', []], + }) + } + initQueryForm() { + this.queryForm = this.fb.group({ + name: [''], + status: [], + }) + } + + ngOnInit(): void { + this.table + + .setColumn([ + { key: 'warehouseId', title: '主键', visible: false }, + { key: 'name', title: '名称' }, + { key: 'status', title: '状态' }, + { key: 'createTime', title: '创建时间' }, + ]) + .setRowOperate([ + { title: '编辑', onClick: this.onCreate.bind(this) }, + { title: '删除', onClick: this.deleteItem.bind(this) }, + ]) + this.initQueryForm() + this.initCreateForm() + } + + fetchData(p: {}, q: AnyObject) { + return this.api.getBasicWarehousePage({ ...p, ...q }) + } + + onCreate(data?: NzSafeAny) { + if (data) { + this.createForm.patchValue(data) + } + this.drawerRef = this.drawer.create({ + nzTitle: data ? '编辑存放仓库' : '新增存放仓库', + nzContent: this.formContentTpl, + nzFooter: this.drawerFooterTpl, + nzWidth: 600, + nzOnCancel: this.onCancel.bind(this), + }) + } + + onConfirm() { + if (FormValidators.validateFormGroup(this.createForm)) { + const { value } = this.createForm + + this.api + .saveBasicWarehouse({ + ...value, + + // warehouseId: value.warehouseId ?? 0, + }) + .subscribe((res) => { + this.msg.success(res.desc) + this.onCancel() + this.table.ref.reload() + }) + } + } + + async onCancel() { + this.drawerRef?.close() + this.createForm.reset({ status: 0 }) + } + + deleteItem(item: NzSafeAny) { + this.modal.confirm({ + nzTitle: '警告', + nzContent: '是否要删除该存放仓库?', + nzOnOk: async () => { + const res = await lastValueFrom(this.api.deleteBasicWarehouse([item.warehouseId])) + this.msg.success(res.desc) + this.table.ref.reload() + }, + }) + } +} diff --git a/web-admin-app/src/app/services/api.service.ts b/web-admin-app/src/app/services/api.service.ts index 884612d..f70deff 100644 --- a/web-admin-app/src/app/services/api.service.ts +++ b/web-admin-app/src/app/services/api.service.ts @@ -522,6 +522,16 @@ export class ApiService { getRepairPage(data: {}) { return this.http.post('/api/eamRepair/list', data) } + getRepairDetail(id: string) { + return this.http.post('/api/eamRepair/query', null, { params: { id } }) + } + + getDeviceOnOffPage(data: {}) { + return this.http.post('/api/v2/device/list', data) + } + onOffDevice(ids: NzSafeAny[], type: number) { + return this.http.post(type === 1 ? '/api/v2/device/on' : '/api/v2/device/off', ids) + } saveRepair(data: NzSafeAny) { if (Utils.isEmpty(data.id)) { return this.http.post('/api/eamRepair/add', data) @@ -546,6 +556,7 @@ export class ApiService { } // flow + getFlowForms(data: {}) { return this.http.post(`/api/flForm/all`, data) } @@ -584,4 +595,76 @@ export class ApiService { startFlow(json: {}, form_key: string) { return this.http.post(`/api/flowable/definition/start/${form_key}`, json) } + + //v2 + + getFlowFormsList(data: {}) { + return this.http.post(`/api/v2/sysFormTemp/list`, data) + } + + uploadFlowFormTpl = (data: FormData) => { + return this.http.post(`/api/v2/sysFormTemp/importData`, data) + } + + getFlowFormsTpl() { + return this.http.post(`/api/v2/sysFormTemp/importTemplate`, null, { + observe: 'response', + responseType: 'blob' as 'json', + }) + } + + addFlowForm(data: NzSafeAny) { + return this.http.post(`/api/v2/sysFormTemp/add`, data) + } + updateFlowForm(data: NzSafeAny) { + return this.http.post(`/api/v2/sysFormTemp/update`, data) + } + + deleteFlowForm(idList: NzSafeAny) { + return this.http.post(`/api/v2/sysFormTemp/delete`, idList) + } + + getFlowFormDetail(id: string) { + return this.http.post(`/api/v2/sysFormTemp/query`, null, { + params: { + id, + }, + }) + } + getFlowFormList() { + return this.http.post(`/api/v2/sysFormTemp/all`, null) + } + getAssetManagerPage(data: {}) { + return this.http.post(`/api/v2/eamManager/list`, data) + } + getAssetTeamPage(data: {}) { + return this.http.post(`/api/v2/eamBasicTeam/list`, data) + } + getAssetTeamAll() { + return this.http.post(`/api/v2/eamBasicTeam/all`, null) + } + + saveUserTeam(data: NzSafeAny) { + if (Utils.isEmpty(data.teamId)) { + return this.http.post('/api/v2/eamBasicTeam/add', data) + } + return this.http.post('/api/v2/eamBasicTeam/update', data) + } + + deleteUserTeam(ids: number[]) { + return this.http.post('/api/v2/eamBasicTeam/delete', ids) + } + + getTaskPage(data: {}) { + return this.http.post(`/api/v2/flowable/device/list`, data) + } + getPlanPage(data: {}) { + return this.http.post(`/api/v2/plan/list`, data) + } + savePlan(data: {}) { + return this.http.post(`/api/v2/plan/add`, data) + } + createRapairTask(data: {}) { + return this.http.post(`/api/v2/flowable/device/start/repair`, data) + } } diff --git a/web-admin-app/src/app/shared/components/header/header.component.html b/web-admin-app/src/app/shared/components/header/header.component.html index a6c3e9c..65e6623 100644 --- a/web-admin-app/src/app/shared/components/header/header.component.html +++ b/web-admin-app/src/app/shared/components/header/header.component.html @@ -45,7 +45,7 @@ 'basic-warehouse:view' ]" > - 固资管理 + 资产管理
  • } diff --git a/web-admin-app/src/app/shared/components/upload/upload.component.html b/web-admin-app/src/app/shared/components/upload/upload.component.html new file mode 100644 index 0000000..6e4622b --- /dev/null +++ b/web-admin-app/src/app/shared/components/upload/upload.component.html @@ -0,0 +1,33 @@ +@if (drag) { +
    + +
    + +
    {{ placeholder }}
    +
    +
    +} @else { + +} +@if (preview) { +
      +
    • + +
      +
      +
      {{ preview.name || preview.url }}
      +
      +
      +
      +
    • +
    +} diff --git a/web-admin-app/src/app/shared/components/upload/upload.component.less b/web-admin-app/src/app/shared/components/upload/upload.component.less new file mode 100644 index 0000000..51db40f --- /dev/null +++ b/web-admin-app/src/app/shared/components/upload/upload.component.less @@ -0,0 +1,24 @@ +.dropUpload { + position: relative; + padding: 36px 0; + text-align: center; + font-size: 24px; + color: rgba(0, 0, 0, 0.35); + border: 1px dashed #e8e8e8; + border-radius: 4px; + background-color: #fafafa; + cursor: pointer; +} + + +.dropUpload input { + width: 100%; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + opacity: 0; + z-index: 2; + cursor: pointer; +} \ No newline at end of file diff --git a/web-admin-app/src/app/shared/components/upload/upload.component.ts b/web-admin-app/src/app/shared/components/upload/upload.component.ts new file mode 100644 index 0000000..7a07711 --- /dev/null +++ b/web-admin-app/src/app/shared/components/upload/upload.component.ts @@ -0,0 +1,130 @@ +import { Component, EventEmitter, forwardRef, inject, Input, Output } from '@angular/core' +import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms' +import { ApiService } from 'app/services' +import { JwResponse } from 'app/types' +import { NzButtonModule } from 'ng-zorro-antd/button' +import { NzCardModule } from 'ng-zorro-antd/card' +import { NzIconModule } from 'ng-zorro-antd/icon' +import { NzMessageService } from 'ng-zorro-antd/message' +import { Observable } from 'rxjs' + +@Component({ + selector: 'app-upload', + standalone: true, + imports: [NzIconModule, NzButtonModule, NzCardModule], + templateUrl: './upload.component.html', + styleUrl: './upload.component.less', + providers: [ + { + provide: NG_VALUE_ACCESSOR, + multi: true, + useExisting: forwardRef(() => UploadComponent), + }, + ], +}) +export class UploadComponent implements ControlValueAccessor { + constructor() {} + + api = inject(ApiService) + + @Input() drag = false + + @Input() placeholder = '选择文件' + + @Input() uploadFn: (data: FormData) => Observable = this.api.upload + + @Output() onUpload = new EventEmitter() + + msg = inject(NzMessageService) + + ngOnInit(): void {} + + preview: { + name: string + url: string + } | null = null + + uploadFile(file: File) { + if (!file) { + this.msg.error('文件不存在') + return + } + if (file.size / 1024 / 1024 >= 2) { + this.msg.error('文件大小不能超过2M') + return + } + if (this.isImage(file.name)) { + const fileReader = new FileReader() + fileReader.onload = () => { + const base64 = fileReader.result as string + this.preview = { + name: file.name, + url: base64, + } + } + fileReader.readAsDataURL(file) + } else { + } + + const formdata = new FormData() + formdata.append('file', file) + this.uploadFn(formdata).subscribe((res) => { + // this.createForm.get('avatar')?.setValue(res.body.fileName) + this.onChange(res.body.fileName ?? file.name) + this.onUpload.emit(res.body) + this.preview = { + name: res.body.fileName ?? file.name, + url: res.body.url, + } + }) + } + onFileChange(e: Event) { + const target = e.target as HTMLInputElement + const file = target.files![0] + target.value = '' + this.uploadFile(file) + } + + isImage(filePath: string): boolean { + const imageExtensions: string[] = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.tiff', '.svg'] + const extension: string = filePath.slice(filePath.lastIndexOf('.')).toLowerCase() + return imageExtensions.includes(extension) + } + + handleDrop(e: DragEvent) { + this.suppress(e) + const files = e.dataTransfer?.files + if (files) { + this.uploadFile(files[0]) + } + } + + suppress(e: Event) { + e.stopPropagation() + e.preventDefault() + } + + writeValue(obj: string): void { + if (obj) { + this.preview = { + url: obj, + name: obj, + } + } + } + + onTouched = () => {} + + onChange(v: string) { + console.log('upload', v) + } + registerOnChange(fn: any): void { + this.onChange = fn + } + + registerOnTouched(fn: any): void { + this.onTouched = fn + } + + setDisabledState?(isDisabled: boolean): void {} +} diff --git a/web-admin-app/src/app/shared/ng-zorro.ts b/web-admin-app/src/app/shared/ng-zorro.ts index bc01fea..4229cd2 100644 --- a/web-admin-app/src/app/shared/ng-zorro.ts +++ b/web-admin-app/src/app/shared/ng-zorro.ts @@ -50,8 +50,10 @@ import { NzOutletModule } from 'ng-zorro-antd/core/outlet' import { NzAlertModule } from 'ng-zorro-antd/alert' import { NzCollapseModule } from 'ng-zorro-antd/collapse' import { NzRateModule } from 'ng-zorro-antd/rate' +import { NzStepsModule } from 'ng-zorro-antd/steps' export const ngZorroModules = [ + NzStepsModule, NzRateModule, NzCollapseModule, NzAlertModule, diff --git a/web-admin-app/src/app/shared/shared.module.ts b/web-admin-app/src/app/shared/shared.module.ts index 42a97ba..5faff58 100644 --- a/web-admin-app/src/app/shared/shared.module.ts +++ b/web-admin-app/src/app/shared/shared.module.ts @@ -10,6 +10,8 @@ import { PermissionModule } from './permission/permission.module' import { RangePickerComponent } from './components/range-picker/range-picker.component' import { AppPageComponent } from './components/app-page/app-page.component' import { LayoutComponent, HeaderComponent, UserFormComponent } from './components' +// import { StatusTagComponent } from 'app/components' +// import { UploadComponent } from './components/upload/upload.component' @NgModule({ declarations: [AppPageComponent, LayoutComponent, HeaderComponent, UserFormComponent], @@ -20,8 +22,10 @@ import { LayoutComponent, HeaderComponent, UserFormComponent } from './component RouterOutlet, RouterModule, FormErrorTipsComponent, + // UploadComponent, PermissionModule, RangePickerComponent, + // StatusTagComponent, ...ngZorroModules, ], exports: [ @@ -39,6 +43,7 @@ import { LayoutComponent, HeaderComponent, UserFormComponent } from './component UserFormComponent, LayoutComponent, HeaderComponent, + ...ngZorroModules, ], }) diff --git a/web-admin-app/src/app/types/index.ts b/web-admin-app/src/app/types/index.ts index 7908ff8..cca789e 100644 --- a/web-admin-app/src/app/types/index.ts +++ b/web-admin-app/src/app/types/index.ts @@ -3,3 +3,5 @@ export * from './http' export type NullableProps = { [K in keyof T]: T[K] | null } + +export type PlanTaskType = 'inspection' | 'maintenance' | 'repair' | 'stocktaking'