([], [FormValidators.required('请选择')]),
+ })
+
+ table = new TableOption(this.fetchData.bind(this))
+
+ assetTotal = 0
+
+ deviceTotal = 0
+
+ queryForm = new FormGroup({
+ name: new FormControl(''),
+ })
+
+ FLOW_STATUS = flowIntStatus
+ ngOnInit(): void {
+ this.table
+ .setConfig({
+ cacheKey: this.page + '_' + this.type,
+ })
+ .setColumn([
+ { key: 'procVars', title: '名称', visible: true },
+ { key: 'status', title: '流程状态', visible: true },
+ { key: 'urgency', title: '紧急程度', visible: true },
+ { key: 'procDefName', title: '流程类型', visible: true },
+ { key: 'assigneeName', title: '审批人', visible: true },
+ { key: 'createTime', title: '提交时间', visible: true },
+ // { key: 'createTime', title: '作废时间', visible: true },
+ // { key: 'createTime', title: '完成时间', visible: true },
+ ])
+ .setRowOperate([
+ { title: '查看', onClick: this.onDetail.bind(this) },
+ {
+ title: '作废',
+ onClick: this.cancleFlow.bind(this),
+ visible: (v) => {
+ return this.page === 'apply'
+ },
+ },
+ ])
+ }
+
+ fetchData(p: {}, q: AnyObject) {
+ if (this.page === 'apply') {
+ return this.api.getMyApplyAssetFlow({ ...p, ...q, type: this.type }).pipe(
+ tap((res) => {
+ this.onLoad.emit(res.body.total)
+ }),
+ )
+ } else if (this.page === 'finished') {
+ return this.api.getMyFinishedAssetFlow({ ...p, ...q, type: this.type }).pipe(
+ tap((res) => {
+ this.onLoad.emit(res.body.total)
+ }),
+ )
+ } else {
+ return this.api.getMyTodoAssetFlow({ ...p, ...q, type: this.type }).pipe(
+ tap((res) => {
+ this.onLoad.emit(res.body.total)
+ }),
+ )
+ }
+ }
+
+ onDetail(model: NzSafeAny) {
+ console.log('model', model, comsMap[model.category])
+ this.modal.create({
+ nzTitle: '查看',
+ nzContent: comsMap[model.category],
+ nzWrapClassName: 'modal-lg',
+ nzWidth: '80vw',
+ nzFooter: null,
+ nzData: {
+ value: model,
+ preview: true,
+ },
+ })
+ }
+
+ cancleFlow(d: NzSafeAny) {
+ this.modal.confirm({
+ nzTitle: '作废',
+ nzContent: '是否要作废该申请?',
+ nzOnOk: async () => {
+ const res = await lastValueFrom(
+ this.api.cancelFlow({
+ instanceId: d.procInsId,
+ taskId: d.taskId,
+ }),
+ )
+ this.msg.success('作废成功')
+ this.table.ref.reload()
+ },
+ })
+ }
+}
diff --git a/web-admin-app/src/app/components/plan-task/handle-task-asset-item/handle-task-asset-item.component.html b/web-admin-app/src/app/components/plan-task/handle-task-asset-item/handle-task-asset-item.component.html
index 487f443..c453511 100644
--- a/web-admin-app/src/app/components/plan-task/handle-task-asset-item/handle-task-asset-item.component.html
+++ b/web-admin-app/src/app/components/plan-task/handle-task-asset-item/handle-task-asset-item.component.html
@@ -38,15 +38,28 @@
-
-
-
- 自动发起报修流程
-
-
-
-
-
+ @if (type != 'stocktaking' && formGroup.get('defectStatus')?.value === 2) {
+
+
+ 自动发起报修流程
+
+
+
+
+
+ }
+ @if (type === 'maintenance') {
+
+
+ 保养成本
+
+
+
+
+
+
+
+ }
{{ data.title }}总结
@@ -128,6 +141,64 @@
}
+ @if (type === 'maintenance') {
+ 备件损耗
+
+
+ }
+
diff --git a/web-admin-app/src/app/components/plan-task/handle-task-asset-item/handle-task-asset-item.component.ts b/web-admin-app/src/app/components/plan-task/handle-task-asset-item/handle-task-asset-item.component.ts
index d2b15b1..9539a81 100644
--- a/web-admin-app/src/app/components/plan-task/handle-task-asset-item/handle-task-asset-item.component.ts
+++ b/web-admin-app/src/app/components/plan-task/handle-task-asset-item/handle-task-asset-item.component.ts
@@ -12,10 +12,11 @@ import { ASSET_SOURCE_MAP, ASSET_STATUS, MAINTENANCE_STATUS, MAINTENANCE_TYPE, M
// 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 { NZ_MODAL_DATA, NzModalService } from 'ng-zorro-antd/modal'
import { UploadComponent } from 'app/shared/components/upload/upload.component'
import { AssetCategorySelectComponent } from 'app/components/asset-category-select/asset-category-select.component'
import { PlanTaskType } from 'app/types'
+import { AssetSelectBeijianComponent } from 'app/components/asset-select-beijian/asset-select-beijian.component'
// import { AssetOperationRecordsComponent } from '../asset-operation-records/asset-operation-records.component'
// import { AssetRepairRecordsComponent } from '../asset-repair-records/asset-repair-records.component'
// import { UploadComponent } from '../../shared/components/upload/upload.component'
@@ -39,6 +40,7 @@ export const defectStatusText: Record = {
// MaintenanceSelectComponent,
// AssetOperationRecordsComponent,
// AssetRepairRecordsComponent,
+ AssetSelectBeijianComponent,
UploadComponent,
],
templateUrl: './handle-task-asset-item.component.html',
@@ -86,8 +88,10 @@ export class HandleTaskAssetItemComponent {
img: this.fb.control(null, []),
attachment: this.fb.control(null, []),
notes: this.fb.control(null, []),
-
+ autoRepair: this.fb.control(false, []),
+ cost: this.fb.control(0, []),
_extInfo: this.fb.array([]),
+ sparePartsList: this.fb.control([], []),
})
this.patchValues()
@@ -100,6 +104,9 @@ export class HandleTaskAssetItemComponent {
get extInfo(): FormArray {
return this.formGroup.get('_extInfo') as FormArray
}
+ // get sparePartsList(): FormArray {
+ // return this.formGroup.get('sparePartsList') as FormArray
+ // }
onExtraChange(v: any) {
let extraFields: NzSafeAny[] = []
@@ -110,9 +117,36 @@ export class HandleTaskAssetItemComponent {
} catch (error) {}
this.setExtraFields(extraFields)
+ // this.setBeijian(extraFields)
}
ext = null
+ setBeijian(beijian: NzSafeAny[]) {
+ // this.sparePartsList.clear()
+ // beijian.forEach((i) => {
+ // this.sparePartsList.push(
+ // this.fb.group({
+ // assetId: this.fb.control(i.assetId),
+ // categoryId: this.fb.control(i.categoryId),
+ // categoryName: this.fb.control(i.categoryName),
+ // count: this.fb.control(i.count),
+ // model: this.fb.control(i.model),
+ // name: this.fb.control(i.name),
+ // remark: this.fb.control(i.remark),
+ // }),
+ // )
+ // })
+ }
+
+ modal = inject(NzModalService)
+ addSpareParts() {
+ this.modal.create({
+ nzTitle: '选择备件',
+ })
+ }
+ removeSpareParts(idx: number) {
+ // this.sparePartsList.removeAt(idx)
+ }
setExtraFields(fields: NzSafeAny[]) {
this.extInfo.clear()
this.extraFields = fields
@@ -136,6 +170,7 @@ export class HandleTaskAssetItemComponent {
fields: this.fb.control(i.type === 'RADIO' ? i.value?.fields : []),
}),
)
+
return i
})
}
diff --git a/web-admin-app/src/app/components/plan-task/handle-task/handle-task.component.html b/web-admin-app/src/app/components/plan-task/handle-task/handle-task.component.html
index 27f2388..96eff2c 100644
--- a/web-admin-app/src/app/components/plan-task/handle-task/handle-task.component.html
+++ b/web-admin-app/src/app/components/plan-task/handle-task/handle-task.component.html
@@ -172,7 +172,7 @@
- @if (item.defectStatus == 0) {
+ @if (item.defectStatus == 0 && !data.preview) {
{
const vals = e.getValues()
if (vals) {
- const res = await lastValueFrom(
- this.api.handleTaskAssetItem(
- {
- ...this.data.value,
- defects: this.data.value.defects.map((i: NzSafeAny) => {
- if (i.assetId === asset.assetId) {
- return {
- ...asset,
- _formValue: vals._extInfo,
- ...vals,
- }
- }
- return i
- }),
- },
- this.data.value.id,
- ),
- )
+ const val = {
+ ...this.data.value,
+ defects: this.data.value.defects.map((i: NzSafeAny) => {
+ if (i.assetId === asset.assetId) {
+ return {
+ ...asset,
+ _formValue: vals._extInfo,
+ ...vals,
+ }
+ }
+ return i
+ }),
+ }
+ console.log('val', val)
+
+ const res = await lastValueFrom(this.api.handleTaskAssetItem(val, this.data.value.id))
+ this.data.value = JSON.parse(JSON.stringify(val))
this.msg.success(res.desc)
// this.table.ref.reload()
return true
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
index 4702cfd..b7984c8 100644
--- 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
@@ -45,7 +45,12 @@
任务时长
-
+
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
index 09a92b4..92aaa4f 100644
--- 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
@@ -81,7 +81,7 @@ export class TaskFormComponent {
businessId: this.fb.control(null, []),
attachment: this.fb.control(null, []),
- duration: this.fb.control(null, []),
+ duration: this.fb.control(null, [FormValidators.required('请输入')]),
order: this.fb.control(false, []),
limit: this.fb.control(false, []),
img: this.fb.control(null, []),
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
index 40572cb..e87839e 100644
--- 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
@@ -17,6 +17,7 @@ import { StatusTagComponent } from 'app/components/status-tag/status-tag.compone
import { PlanFormComponent } from '../plan-form/plan-form.component'
import { TaskFormComponent } from '../task-form/task-form.component'
import { HandleTaskComponent } from '../handle-task/handle-task.component'
+import { Utils } from 'app/utils'
@Component({
selector: 'app-task-list',
@@ -99,13 +100,12 @@ export class TaskListComponent {
title: '审批',
onClick: this.onHandle.bind(this, false),
visible(v) {
- return true
return v.status === 'APPROVAL'
},
},
{
title: '报表',
- onClick: this.deleteItem.bind(this),
+ onClick: this.onReport.bind(this),
visible(v) {
return v.status === 'COMPLETED'
},
@@ -171,6 +171,7 @@ export class TaskListComponent {
}
this.table.ref.reload()
+ this.modalRef?.close()
return true
},
})
@@ -245,8 +246,22 @@ export class TaskListComponent {
// },
})
}
+
+ modalRef?: NzModalRef
+
+ onReport(i: NzSafeAny) {
+ this.msg.loading('下载中...')
+ this.api.downloadTaskReport(i.id).subscribe((res) => {
+ Utils.downLoadFile(
+ res,
+ 'application/vnd.openxmlformats-officedocument.wordprocessingml.document;charset=utf-8',
+ )
+ this.msg.remove()
+ this.msg.success('下载成功')
+ })
+ }
onHandle(chuzhi: boolean, data: NzSafeAny) {
- console.log('chuzhi', chuzhi, data)
+ // console.log('chuzhi', chuzhi, data)
let nzTitle = chuzhi ? '处置任务' : '任务审批'
const footer: NzSafeAny[] = chuzhi
? [
@@ -268,7 +283,7 @@ export class TaskListComponent {
)
this.msg.success(res.desc)
this.table.ref.reload()
- ref.close()
+ this.modalRef?.close()
}
},
},
@@ -293,7 +308,7 @@ export class TaskListComponent {
)
this.msg.success(res.desc)
this.table.ref.reload()
- ref.close()
+ this.modalRef?.close()
}
},
},
@@ -317,7 +332,7 @@ export class TaskListComponent {
},
},
]
- const ref = this.modal.create({
+ this.modalRef = this.modal.create({
nzTitle,
nzContent: HandleTaskComponent,
nzWidth: '80vw',
@@ -326,11 +341,12 @@ export class TaskListComponent {
value: data,
chuzhi,
type: this.type,
+ preview: !chuzhi,
},
nzFooter: footer.concat({
label: '取消',
onClick: () => {
- ref.close()
+ this.modalRef?.close()
},
}),
})
diff --git a/web-admin-app/src/app/pages/data-vis/data-vis.component.html b/web-admin-app/src/app/pages/data-vis/data-vis.component.html
new file mode 100644
index 0000000..5913909
--- /dev/null
+++ b/web-admin-app/src/app/pages/data-vis/data-vis.component.html
@@ -0,0 +1,113 @@
+
+
+
+ {{ time | date: 'yyyy-MM-dd HH:mm:ss' }}
+
+ EAM数据可视化
+
+ {{ data?.slogan }}
+
+
+
+
+
+
+ @for (item of data.assetCostStatistics; track $index) {
+
+ {{ item.content }}
+
+
+ {{ item.name }}
+
+
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ @for (item of data.flowCountStatistics; track $index) {
+
+ {{ item.content }}
+
+
+ {{ item.name }}
+
+
+ }
+
+
+
+
+
+
+
+
+
+
+
+ 消息名称
+ 消息内容
+
+
+
+ @for (item of data.messages; track $index) {
+
+ {{ item.name }}
+ {{ item.content }}
+
+ }
+
+
+
+
+
+
+
+
diff --git a/web-admin-app/src/app/pages/data-vis/data-vis.component.less b/web-admin-app/src/app/pages/data-vis/data-vis.component.less
new file mode 100644
index 0000000..5621eeb
--- /dev/null
+++ b/web-admin-app/src/app/pages/data-vis/data-vis.component.less
@@ -0,0 +1,761 @@
+::ng-deep {
+ body {
+ line-height: 1.15;
+ font-size: 0.5rem;
+ margin: 0;
+ padding: 0;
+ background-repeat: no-repeat;
+ background-position: 0 0 / cover;
+ background-color: #101129;
+ }
+
+ html {
+ font-size: 21.1375px !important;
+ }
+
+ * {
+ margin: 0;
+ padding: 0;
+ font-weight: normal;
+ }
+
+ ul {
+ list-style: none;
+ }
+
+ a {
+ text-decoration: none;
+ }
+}
+
+.vis-hd-left {
+ position: absolute;
+ left: 40px;
+ top: 40px;
+ color: #fff;
+ font-size: 20px;
+}
+
+.vis-hd-right {
+ position: absolute;
+ right: 40px;
+ top: 40px;
+ color: #fff;
+ font-size: 20px;
+}
+
+.vis-title {
+ font-size: 28px;
+ position: absolute;
+ top: 40px;
+ left: 50%;
+ transform: translateX(-50%);
+ color: #fff;
+}
+
+.viewport {
+ /* 限定大小 */
+ min-width: 1024px;
+ max-width: 1920px;
+ min-height: 780px;
+ margin: 0 auto;
+ background: url(/assets/data-vis/images/logo.png) no-repeat 0 0 / contain;
+ display: flex;
+ padding: 3.667rem 0.833rem 0;
+ position: relative;
+}
+
+.column {
+ flex: 3;
+ position: relative;
+}
+
+.column:nth-child(2) {
+ flex: 4;
+ margin: 1.333rem 0.833rem 0;
+}
+
+.panel {
+ /* 边框 */
+ box-sizing: border-box;
+ border: 2px solid red;
+ border-image: url(/assets/data-vis/images/border.png) 51 38 21 132;
+ border-width: 2.125rem 1.583rem 0.875rem 5.5rem;
+ position: relative;
+
+ &:not(:first-child) {
+ margin-top: 0.833rem;
+ }
+}
+
+.panel .inner {
+ /* 装内容 */
+ /* height: 60px; */
+ position: absolute;
+ top: -2.125rem;
+ right: -1.583rem;
+ bottom: -0.875rem;
+ left: -5.5rem;
+ padding: 1rem 1.5rem;
+
+}
+
+.panel h3 {
+ font-size: 0.833rem;
+ color: #fff;
+}
+
+/* 概览区域 */
+.overview {
+ height: 4.583rem;
+}
+
+.overview .inner {
+ display: flex;
+ justify-content: space-between;
+}
+
+.overview h4 {
+ font-size: 1.167rem;
+ padding-left: 0.2rem;
+ color: #fff;
+ margin-bottom: 0.333rem
+}
+
+.overview span {
+ font-size: 0.667rem;
+ color: #4c9bfd;
+}
+
+/* 监控 */
+.monitor {
+ height: 14rem;
+}
+
+.monitor .inner {
+ padding: 1rem 0;
+ display: flex;
+ flex-direction: column;
+}
+
+.monitor .tabs {
+ padding: 0 1.5rem;
+ margin-bottom: 0.75rem;
+}
+
+.monitor .tabs a {
+ color: #1950c4;
+ font-size: 0.75rem;
+ padding: 0 1.125rem;
+}
+
+// .monitor .tabs a:first-child {
+// border-right: 0.083rem solid #00f2f1;
+// padding-left: 0;
+// }
+
+.monitor .tabs a.active {
+ color: #fff;
+}
+
+.monitor .content {
+ flex: 1;
+ display: none;
+ position: relative;
+}
+
+.monitor .head {
+ background: rgba(255, 255, 255, 0.1);
+ font-size: 0.583rem;
+ padding: 0.5rem 1.5rem;
+ color: #68d8fe;
+ display: flex;
+ justify-content: space-between;
+ line-height: 1.05;
+}
+
+.monitor .col:nth-child(1) {
+ width: 3.2rem;
+}
+
+.monitor .col:nth-child(2) {
+ width: 8.4rem;
+ /* 不换行 一行省略*/
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.monitor .col:nth-child(3) {
+ width: 3.2rem;
+}
+
+.monitor .marquee-view {
+ position: absolute;
+ top: 1.6rem;
+ bottom: 0;
+ width: 100%;
+ overflow: hidden;
+}
+
+.monitor .row {
+ line-height: 1.05;
+ padding: 0.5rem 1.5rem;
+ color: #61a8ff;
+ font-size: 0.5rem;
+ position: relative;
+ display: flex;
+ justify-content: space-between;
+}
+
+.monitor .row:hover {
+ color: #68d8ff;
+ background: rgba(255, 255, 255, 0.1);
+}
+
+.monitor .row:hover .icon-dot {
+ opacity: 1;
+}
+
+.monitor .icon-dot {
+ position: absolute;
+ left: 0.64rem;
+ opacity: 0;
+}
+
+.monitor .marquee-view {
+ position: absolute;
+ top: 1.6rem;
+ bottom: 0;
+ width: 100%;
+ overflow: hidden;
+}
+
+.monitor .row {
+ line-height: 1.05;
+ padding: 0.5rem 1.5rem;
+ color: #61a8ff;
+ font-size: 0.5rem;
+ position: relative;
+ display: flex;
+ justify-content: space-between;
+}
+
+.monitor .row:hover {
+ color: #68d8ff;
+ background: rgba(255, 255, 255, 0.1);
+}
+
+.monitor .row:hover .icon-dot {
+ opacity: 1;
+}
+
+.monitor .icon-dot {
+ position: absolute;
+ left: 0.64rem;
+ opacity: 0;
+}
+
+/* ------------------------------------------------------------动画 */
+@keyframes row {
+ 0% {}
+
+ 100% {
+ transform: translateY(-50%);
+ }
+}
+
+/* 调用动画 */
+.monitor .marquee {
+ /* //infinite永久调用动画 */
+ animation: row 10s linear infinite;
+}
+
+/*鼠标划入 停止动画 */
+.monitor .marquee:hover {
+ animation-play-state: paused;
+}
+
+/* 点位 */
+.point {
+ height: 20rem;
+}
+
+.point .chart {
+ display: flex;
+ margin-top: 1rem;
+ justify-content: space-between;
+}
+
+.point .pie {
+ width: 13rem;
+ height: 10rem;
+ margin-left: -0.4rem;
+}
+
+.point .data {
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+ width: 7rem;
+ padding: 1.5rem 1.25rem;
+ box-sizing: border-box;
+ background-image: url(/assets/data-vis/images/rect.png);
+ background-size: cover;
+}
+
+.point h4 {
+ margin-bottom: 0.5rem;
+ font-size: 1.167rem;
+ color: #fff;
+}
+
+.point span {
+ display: block;
+ color: #4c9bfd;
+ font-size: 0.667rem;
+}
+
+/* 地图 */
+.map {
+ height: 24.1rem;
+ margin-bottom: 0.833rem;
+ display: flex;
+ flex-direction: column;
+}
+
+.map h3 {
+ line-height: 1;
+ padding: 0.667rem 0;
+ margin: 0;
+ font-size: 0.833rem;
+ color: #fff;
+}
+
+.map .icon-cube {
+ color: #68d8fe;
+}
+
+.map .chart {
+ flex: 1;
+ background-color: rgba(255, 255, 255, 0.05);
+}
+
+.map .geo {
+ width: 100%;
+ height: 100%;
+}
+
+/* 用户模块 */
+.users {
+ height: 14.167rem;
+ display: flex;
+}
+
+.users .inner {
+ display: flex;
+ flex-direction: column;
+}
+
+.users .chart {
+ flex: 1;
+ display: flex;
+ margin-top: 1rem;
+}
+
+.users .bar {
+ width: 24.5rem;
+ height: 10rem;
+}
+
+.users .data {
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+ width: 7rem;
+ padding: 1.5rem 1.25rem;
+ box-sizing: border-box;
+ background-image: url(/assets/data-vis/images/rect.png);
+ background-size: cover;
+}
+
+.users h4 {
+ margin-bottom: 0.5rem;
+ font-size: 1.167rem;
+ color: #fff;
+}
+
+.users span {
+ display: block;
+ color: #4c9bfd;
+ font-size: 0.667rem;
+}
+
+/* 订单 */
+.order {
+ height: 6.167rem;
+}
+
+.order .filter {
+ display: flex;
+}
+
+.order .filter a {
+ display: block;
+ height: 0.75rem;
+ line-height: 1;
+ padding: 0 0.75rem;
+ color: #1950c4;
+ font-size: 0.75rem;
+ border-right: 0.083rem solid #00f2f1;
+}
+
+.order .filter a:first-child {
+ padding-left: 0;
+}
+
+.order .filter a:last-child {
+ border-right: none;
+}
+
+.order .filter a.active {
+ color: #fff;
+ font-size: 0.833rem;
+}
+
+.order .data {
+ display: flex;
+ margin-top: 0.833rem;
+}
+
+.order .item {
+ width: 50%;
+}
+
+.order h4 {
+ font-size: 1.167rem;
+ color: #fff;
+ margin-bottom: 0.417rem;
+}
+
+.order span {
+ display: block;
+ color: #4c9bfd;
+ font-size: 0.667rem;
+}
+
+/* 销售区域 */
+.sales {
+ height: 18.333rem;
+}
+
+.sales .caption {
+ display: flex;
+ line-height: 1;
+}
+
+.sales h3 {
+ height: 0.75rem;
+ padding-right: 0.75rem;
+
+}
+
+.sales a {
+ padding: 0.167rem;
+ font-size: 0.667rem;
+ margin: -0.125rem 0 0 0.875rem;
+ border-radius: 0.125rem;
+ color: #0bace6;
+}
+
+.sales a.active {
+ background-color: #4c9bfd;
+ color: #fff;
+}
+
+.sales .inner {
+ display: flex;
+ flex-direction: column;
+}
+
+.sales .chart {
+ flex: 1;
+ padding-top: 0.6rem;
+ position: relative;
+}
+
+.sales .label {
+ position: absolute;
+ left: 1.75rem;
+ top: 0.75rem;
+ color: #4996f5;
+ font-size: 0.583rem;
+}
+
+.sales .line {
+ width: 100%;
+ height: 100%;
+}
+
+/* 渠道区块 */
+.wrap {
+ display: flex;
+}
+
+.channel,
+.quarter {
+ flex: 1;
+ height: 13.5rem;
+}
+
+.channel {
+ margin-right: 0.833rem;
+}
+
+.channel .data {
+ overflow: hidden;
+}
+
+.channel .item {
+ margin-top: 0.85rem;
+}
+
+.channel .item:first-child {
+ float: left;
+}
+
+.channel .item:last-child {
+ float: right;
+}
+
+.channel h4 {
+ color: #fff;
+ font-size: 1.333rem;
+ margin-bottom: 0.2rem;
+}
+
+.channel small {
+ font-size: 50%;
+}
+
+.channel span {
+ display: block;
+ color: #4c9bfd;
+ font-size: 0.583rem;
+}
+
+/* 季度区块 */
+.quarter .inner {
+ display: flex;
+ flex-direction: column;
+ margin: 0 -0.25rem;
+}
+
+.quarter .chart {
+ flex: 1;
+ padding-top: 0.75rem;
+}
+
+.quarter .box {
+ position: relative;
+}
+
+.quarter .label {
+ transform: translate(-50%, -30%);
+ color: #fff;
+ font-size: 1.25rem;
+ position: absolute;
+ left: 50%;
+ top: 50%;
+}
+
+.quarter .label small {
+ font-size: 50%;
+}
+
+.quarter .gauge {
+ height: 3.5rem;
+}
+
+.quarter .data {
+ display: flex;
+ justify-content: space-between;
+}
+
+.quarter .item {
+ width: 50%;
+}
+
+.quarter h4 {
+ color: #fff;
+ font-size: 1rem;
+ margin-bottom: 0.4rem;
+}
+
+.quarter span {
+ display: block;
+ width: 100%;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ color: #4c9bfd;
+ font-size: 0.583rem;
+}
+
+.point .inner {
+ display: flex;
+ flex-direction: column;
+
+ .chart {
+ flex: 1;
+ }
+}
+
+/* 排行榜 */
+.top {
+ height: 11.8rem;
+}
+
+.top .inner {
+ display: flex;
+}
+
+.top .all {
+ display: flex;
+ flex-direction: column;
+ width: 7rem;
+ color: #4c9bfd;
+ font-size: 0.6rem;
+ vertical-align: middle;
+}
+
+.top .all ul {
+ padding-left: 0.5rem;
+ margin-top: 0.5rem;
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ justify-content: space-around;
+}
+
+.top .all li {
+ overflow: hidden;
+}
+
+.top .all [class^="icon-"] {
+ font-size: 1.5rem;
+ vertical-align: middle;
+ margin-right: 0.5rem;
+}
+
+.top .province {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ color: #fff;
+}
+
+.top .province i {
+ padding: 0 0.5rem;
+ margin-top: 0.208rem;
+ float: right;
+ font-style: normal;
+ font-size: 0.583rem;
+ color: #0bace6;
+}
+
+.top .province s {
+ display: inline-block;
+ transform: scale(0.8);
+ text-decoration: none;
+}
+
+.top .province .icon-up {
+ color: #dc3c33;
+}
+
+.top .province .icon-down {
+ color: #36be90;
+}
+
+.top .province .data {
+ flex: 1;
+ display: flex;
+ margin-top: 0.6rem;
+}
+
+.top .province ul {
+ flex: 1;
+ line-height: 1;
+ margin-bottom: 0.25rem;
+}
+
+.top .province ul li {
+ display: flex;
+ justify-content: space-between;
+}
+
+.top .province ul span {
+ display: block;
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+}
+
+.top .province ul.sup {
+ font-size: 0.583rem;
+}
+
+.top .province ul.sup li {
+ color: #4995f4;
+ padding: 0.5rem;
+}
+
+.top .province ul.sup li.active {
+ color: #a3c6f2;
+ background-color: rgba(10, 67, 188, 0.2);
+}
+
+.top .province ul.sub {
+ display: flex;
+ flex-direction: column;
+ justify-content: space-around;
+ font-size: 0.5rem;
+ background-color: rgba(10, 67, 188, 0.2);
+}
+
+.top .province ul.sub li {
+ color: #52ffff;
+ padding: 0.417rem 0.6rem;
+}
+
+.clock {
+ position: absolute;
+ top: -1.5rem;
+ right: 1.667rem;
+ font-size: 0.833rem;
+ color: #0bace6;
+}
+
+.clock i {
+ margin-right: 5px;
+ font-size: 0.833rem;
+}
+
+@media screen and (max-width: 1600px) {
+ .top span {
+ transform: scale(0.9);
+ }
+
+ .top .province ul.sup li {
+ padding: 0.4rem 0.5rem;
+ }
+
+ .top .province ul.sub li {
+ padding: 0.23rem 0.5rem;
+ }
+
+ .quarter span {
+ transform: scale(0.9);
+ }
+}
\ No newline at end of file
diff --git a/web-admin-app/src/app/pages/data-vis/data-vis.component.ts b/web-admin-app/src/app/pages/data-vis/data-vis.component.ts
new file mode 100644
index 0000000..52cb682
--- /dev/null
+++ b/web-admin-app/src/app/pages/data-vis/data-vis.component.ts
@@ -0,0 +1,271 @@
+import { Component, ElementRef, ViewChild } from '@angular/core'
+import { ApiService } from 'app/services'
+import { SharedModule } from 'app/shared/shared.module'
+import { NzSafeAny } from 'ng-zorro-antd/core/types'
+import { interval } from 'rxjs'
+import { init, EChartsType } from 'echarts'
+
+@Component({
+ selector: 'app-data-vis',
+ standalone: true,
+ imports: [SharedModule],
+ templateUrl: './data-vis.component.html',
+ styleUrl: './data-vis.component.less',
+})
+export class DataVisComponent {
+ constructor(private api: ApiService) {}
+
+ @ViewChild('cateTpl') cateTpl?: ElementRef
+ @ViewChild('statusTpl') statusTpl?: ElementRef
+ @ViewChild('changeTpl') changeTpl?: ElementRef
+ @ViewChild('posTpl') posTpl?: ElementRef
+ @ViewChild('flowTpl') flowTpl?: ElementRef
+
+ cateRef?: EChartsType
+ statusRef?: EChartsType
+ changeRef?: EChartsType
+ posRef?: EChartsType
+ flowRef?: EChartsType
+
+ data: NzSafeAny
+
+ time = new Date()
+ ngOnInit(): void {
+ this.api.bigScreen().subscribe((res) => {
+ this.data = res.body
+ setTimeout(() => {
+ this.renderCate()
+ this.renderStatus()
+ this.renderChange()
+ this.renderPos()
+ this.renderFlow()
+ }, 10)
+ })
+
+ interval(1000).subscribe(() => {
+ this.time = new Date()
+ })
+ }
+
+ renderFlow() {
+ if (!this.flowTpl?.nativeElement) {
+ return
+ }
+ if (!this.flowRef) {
+ this.flowRef = init(this.flowTpl.nativeElement)
+ }
+ const name: string[] = []
+ const val: number[] = []
+ this.data.assetPositionChart.forEach((i: any) => {
+ name.push(i.name)
+ val.push(i.total)
+ })
+ this.flowRef.setOption({
+ legend: {
+ bottom: 'bottom',
+ left: 'center',
+ type: 'scroll',
+ textStyle: {
+ color: '#ffffff',
+ },
+ },
+
+ series: [
+ {
+ type: 'pie',
+ radius: [10, 100],
+ label: {
+ formatter: '{b}-{c}',
+ // position: 'inside',
+ },
+ itemStyle: {
+ borderRadius: 8,
+ },
+ data: this.data.flowTypeChart.map((i: any) => {
+ return {
+ value: i.total,
+ name: i.name,
+ }
+ }),
+ },
+ ],
+ })
+ }
+ renderPos() {
+ if (!this.posTpl?.nativeElement) {
+ return
+ }
+ if (!this.posRef) {
+ this.posRef = init(this.posTpl.nativeElement)
+ }
+ const name: string[] = []
+ const val: number[] = []
+ this.data.assetPositionChart.forEach((i: any) => {
+ name.push(i.name)
+ val.push(i.total)
+ })
+ this.posRef.setOption({
+ grid: {
+ top: '5%',
+ left: '10%',
+ right: '5%',
+ bottom: '10%',
+ },
+ xAxis: {
+ type: 'category',
+ boundaryGap: false,
+ data: name,
+ splitLine: {
+ show: false,
+ },
+ axisLabel: {
+ show: true,
+ color: '#ffffff',
+ },
+ },
+ yAxis: {
+ type: 'value',
+ axisLabel: {
+ show: true,
+ color: '#ffffff',
+ },
+ },
+ series: [
+ {
+ data: val,
+ type: 'bar',
+ areaStyle: {},
+ smooth: true,
+ },
+ ],
+ })
+ }
+ renderChange() {
+ if (!this.changeTpl?.nativeElement) {
+ return
+ }
+ if (!this.changeRef) {
+ this.changeRef = init(this.changeTpl.nativeElement)
+ }
+ const name: string[] = []
+ const val: number[] = []
+ this.data.assetChangeChart.forEach((i: any) => {
+ name.push(i.name)
+ val.push(i.total)
+ })
+ this.changeRef.setOption({
+ grid: {
+ top: '5%',
+ left: '10%',
+ right: '5%',
+ bottom: '6%',
+ },
+ xAxis: {
+ type: 'category',
+ boundaryGap: false,
+ data: name,
+ splitLine: {
+ show: false,
+ },
+ axisLabel: {
+ show: true,
+ color: '#ffffff',
+ },
+ },
+ yAxis: {
+ type: 'value',
+ axisLabel: {
+ show: true,
+ color: '#ffffff',
+ },
+ },
+ series: [
+ {
+ data: val,
+ type: 'line',
+ areaStyle: {},
+ smooth: true,
+ },
+ ],
+ })
+ }
+ renderStatus() {
+ if (!this.statusTpl?.nativeElement) {
+ return
+ }
+ if (!this.statusRef) {
+ this.statusRef = init(this.statusTpl.nativeElement)
+ }
+
+ this.statusRef.setOption({
+ legend: {
+ bottom: 'bottom',
+ left: 'center',
+ type: 'scroll',
+ textStyle: {
+ color: '#ffffff',
+ },
+ },
+
+ series: [
+ {
+ type: 'pie',
+ radius: [10, 100],
+
+ roseType: 'area',
+ itemStyle: {
+ borderRadius: 8,
+ },
+ data: this.data.assetStatusChart.map((i: any) => {
+ return {
+ value: i.total,
+ name: i.name,
+ }
+ }),
+ },
+ ],
+ })
+ }
+ renderCate() {
+ if (!this.cateTpl?.nativeElement) {
+ return
+ }
+ if (!this.cateRef) {
+ this.cateRef = init(this.cateTpl.nativeElement)
+ }
+ const name: string[] = []
+ const val: number[] = []
+ this.data.assetCategoryChart.forEach((i: any) => {
+ name.push(i.name)
+ val.push(i.total)
+ })
+ this.cateRef.setOption({
+ grid: {
+ top: 0,
+ left: '10%',
+ right: '0%',
+ bottom: '0%',
+ },
+ xAxis: {
+ type: 'value',
+ splitLine: {
+ show: false,
+ },
+ },
+ yAxis: {
+ type: 'category',
+ data: name,
+ axisLabel: {
+ show: true,
+ color: '#ffffff',
+ },
+ },
+ series: [
+ {
+ type: 'bar',
+ data: val,
+ },
+ ],
+ })
+ }
+}
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
index fcc0186..7d14eb4 100644
--- 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
@@ -23,7 +23,11 @@
-
@@ -69,3 +70,13 @@
+
+
+
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
index c2ddccd..eed7db8 100644
--- 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
@@ -1,11 +1,12 @@
-import { Component, inject, TemplateRef, ViewChild } from '@angular/core'
+import { Component, ElementRef, 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 { UploadComponent } from 'app/shared/components/upload/upload.component'
import { SharedModule } from 'app/shared/shared.module'
-import { FormValidators } from 'app/utils'
+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'
@@ -14,13 +15,13 @@ import { lastValueFrom, map } from 'rxjs'
@Component({
selector: 'app-basic-flow-form',
standalone: true,
- imports: [SharedModule, StatusTagComponent],
+ imports: [SharedModule, StatusTagComponent, UploadComponent],
templateUrl: './basic-flow-form.component.html',
styleUrl: './basic-flow-form.component.less',
})
export class BasicFlowFormComponent {
constructor(
- private api: ApiService,
+ public api: ApiService,
private modal: NzModalService,
private msg: NzMessageService,
) {}
@@ -38,12 +39,28 @@ export class BasicFlowFormComponent {
table = new TableOption(this.fetchData.bind(this))
+ importData(nzContent: TemplateRef<{}>) {
+ this.modal.create({
+ nzTitle: '导入',
+ nzContent,
+ nzFooter: null,
+ })
+ }
+ exportData() {
+ this.msg.loading('正在下载...', { nzDuration: 0 })
+ this.api.exportFlowForm(Array.from(this.table.ref.selected)).subscribe((res) => {
+ Utils.downLoadFile(res, 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8')
+ this.msg.remove()
+ this.msg.success('下载成功')
+ })
+ }
+
ngOnInit(): void {
this.table
- // .setConfig({
- // selectable: true,
- // rowKey: 'id',
- // })
+ .setConfig({
+ selectable: true,
+ rowKey: 'formTempId',
+ })
.setColumn([
{ key: 'formKey', title: '表单编号', visible: true },
{ key: 'formName', title: '表单名称', visible: true },
@@ -64,7 +81,7 @@ export class BasicFlowFormComponent {
router = inject(Router)
onEdit(v: NzSafeAny) {
- this.router.navigate(['/fixed-asset/basic/flow-form/manage/', v.formKey])
+ this.router.navigate(['/fixed-asset/basic/flow-form/manage/', v.formTempId])
}
onDelete(data: NzSafeAny) {
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 2be54b3..da65d47 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
@@ -307,7 +307,7 @@
>
供应商
-
维保商
-
- -->
+
+
- 维修类型
+ 维保类型
{
+ this.onRecords(v)
+ },
+ },
])
}
@@ -102,4 +111,14 @@ export class MaintainOnOffComponent {
batchOnOff(type: number) {
this.onOff(Array.from(this.table.ref.selected), type)
}
+
+ onRecords(v: NzSafeAny) {
+ this.modal.create({
+ nzTitle: '开关机记录',
+ nzContent: OnOffRecordsComponent,
+ nzData: v,
+
+ nzFooter: null,
+ })
+ }
}
diff --git a/web-admin-app/src/app/pages/fixed-asset/maintain/on-off-records/on-off-records.component.html b/web-admin-app/src/app/pages/fixed-asset/maintain/on-off-records/on-off-records.component.html
new file mode 100644
index 0000000..46dbdb8
--- /dev/null
+++ b/web-admin-app/src/app/pages/fixed-asset/maintain/on-off-records/on-off-records.component.html
@@ -0,0 +1,12 @@
+
+
+ @for (item of records; track $index) {
+
+ {{ item.operationType }}
+
+ }
+
+
diff --git a/web-admin-app/src/app/pages/fixed-asset/maintain/on-off-records/on-off-records.component.less b/web-admin-app/src/app/pages/fixed-asset/maintain/on-off-records/on-off-records.component.less
new file mode 100644
index 0000000..e69de29
diff --git a/web-admin-app/src/app/pages/fixed-asset/maintain/on-off-records/on-off-records.component.ts b/web-admin-app/src/app/pages/fixed-asset/maintain/on-off-records/on-off-records.component.ts
new file mode 100644
index 0000000..96464d8
--- /dev/null
+++ b/web-admin-app/src/app/pages/fixed-asset/maintain/on-off-records/on-off-records.component.ts
@@ -0,0 +1,27 @@
+import { Component, inject, OnInit } from '@angular/core'
+import { ApiService } from 'app/services'
+import { SharedModule } from 'app/shared/shared.module'
+import { NzSafeAny } from 'ng-zorro-antd/core/types'
+import { NZ_MODAL_DATA } from 'ng-zorro-antd/modal'
+
+@Component({
+ selector: 'app-on-off-records',
+ standalone: true,
+ imports: [SharedModule],
+ templateUrl: './on-off-records.component.html',
+ styleUrl: './on-off-records.component.less',
+})
+export class OnOffRecordsComponent implements OnInit {
+ constructor(private api: ApiService) {}
+
+ data = inject(NZ_MODAL_DATA)
+
+ records: NzSafeAny[] = []
+ ngOnInit(): void {
+ if (this.data) {
+ this.api.onOffRecord(this.data.assetId).subscribe((res) => {
+ this.records = res.body
+ })
+ }
+ }
+}
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
index e24357a..7f7ef0d 100644
--- 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
@@ -244,6 +244,27 @@
+
+ 模版文件类型
+
+
+
+
+
+
+
+ @if (templateType === '2') {
+
+ 扩展资产表单
+
+
+ @for (item of flowForms; track $index) {
+
+ }
+
+
+
+ }
模版文件
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
index bcde03d..9b17cb3 100644
--- 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
@@ -48,6 +48,12 @@ export class RegistrationComponent {
copyNum = 1
+ templateType = '1'
+
+ extendFormId?: string
+
+ flowForms: NzSafeAny[] = []
+
ngOnInit(): void {
this.table
.setConfig({
@@ -75,6 +81,10 @@ export class RegistrationComponent {
{ title: '二维码', onClick: this.qrcode.bind(this) },
{ title: '删除', onClick: this.deleteItem.bind(this) },
])
+
+ this.api.getFlowFormList().subscribe((res) => {
+ this.flowForms = res.body
+ })
}
fetchData(p: {}, q: AnyObject) {
@@ -163,8 +173,12 @@ export class RegistrationComponent {
}
downloadTemplate() {
+ if (this.templateType === '2' && !this.extendFormId) {
+ this.msg.error('请选择表单')
+ return
+ }
this.msg.loading('模板下载中...')
- this.api.downloadAssetTemplate().subscribe((res) => {
+ this.api.downloadAssetTemplate(this.extendFormId).subscribe((res) => {
Utils.downLoadFile(res, 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8')
this.msg.remove()
this.msg.success('模板下载成功')
diff --git a/web-admin-app/src/app/pages/flow/flow-my-apply/flow-my-apply.component.html b/web-admin-app/src/app/pages/flow/flow-my-apply/flow-my-apply.component.html
index c2380bf..3f47fd0 100644
--- a/web-admin-app/src/app/pages/flow/flow-my-apply/flow-my-apply.component.html
+++ b/web-admin-app/src/app/pages/flow/flow-my-apply/flow-my-apply.component.html
@@ -1,34 +1,12 @@
-
-
-
-
-
-
-
-
- @switch (key) {
- @case ('_assignee') {
- {{ data.userName }}
- }
- @case ('procVars') {
- {{ data?.title ?? data?.name ?? '-' }}
- }
- @case ('status') {
-
- {{ FLOW_STATUS.get(data) }}
-
- }
- @case ('urgency') {
-
- {{ row.procVars.urgency === 2 ? '紧急' : '普通' }}
-
- }
- @default {
- {{ data }}
- }
- }
-
-
+
diff --git a/web-admin-app/src/app/pages/flow/flow-my-apply/flow-my-apply.component.ts b/web-admin-app/src/app/pages/flow/flow-my-apply/flow-my-apply.component.ts
index 262d00c..133b08b 100644
--- a/web-admin-app/src/app/pages/flow/flow-my-apply/flow-my-apply.component.ts
+++ b/web-admin-app/src/app/pages/flow/flow-my-apply/flow-my-apply.component.ts
@@ -13,11 +13,12 @@ import { FormValidators } from 'app/utils'
import { AssetEmployeeApplyComponent } from 'app/components'
import { comsMap } from '../flow-main/flow-main.component'
import { FLOW_STATUS, flowIntStatus } from 'app/constants'
+import { FlowListByTypeComponent } from 'app/components/flow-list-by-type/flow-list-by-type.component'
@Component({
selector: 'app-flow-my-apply',
standalone: true,
- imports: [SharedModule],
+ imports: [SharedModule, FlowListByTypeComponent],
templateUrl: './flow-my-apply.component.html',
styleUrl: './flow-my-apply.component.less',
})
@@ -35,67 +36,13 @@ export class FlowMyApplyComponent {
userId: new FormControl ([], [FormValidators.required('请选择')]),
})
- table = new TableOption(this.fetchData.bind(this))
+ assetTotal = 0
- queryForm = new FormGroup({
- name: new FormControl(''),
- })
-
- FLOW_STATUS = flowIntStatus
- ngOnInit(): void {
- this.table
- // .setConfig({
- // selectable: true,
- // rowKey: 'id',
- // })
- .setColumn([
- { key: 'procVars', title: '名称', visible: true },
- { key: 'status', title: '流程状态', visible: true },
- { key: 'urgency', title: '紧急程度', visible: true },
- { key: 'procDefName', title: '流程类型', visible: true },
- { key: 'assigneeName', title: '审批人', visible: true },
- { key: 'createTime', title: '提交时间', visible: true },
- // { key: 'createTime', title: '作废时间', visible: true },
- // { key: 'createTime', title: '完成时间', visible: true },
- ])
- .setRowOperate([
- { title: '查看', onClick: this.onDetail.bind(this) },
- { title: '作废', onClick: this.cancleFlow.bind(this) },
- ])
- }
+ deviceTotal = 0
- fetchData(p: {}, q: AnyObject) {
- return this.api.getMyApplyAssetFlow({ ...p, ...q })
+ onLoad(total: number, type: 'assetTotal' | 'deviceTotal') {
+ this[type] = total
}
- onDetail(model: NzSafeAny) {
- this.modal.create({
- nzTitle: '查看任务',
- nzContent: comsMap[model.category],
- nzWrapClassName: 'modal-lg',
- nzWidth: '80vw',
- nzFooter: null,
- nzData: {
- value: model,
- preview: true,
- },
- })
- }
-
- cancleFlow(d: NzSafeAny) {
- this.modal.confirm({
- nzTitle: '作废',
- nzContent: '是否要作废该申请?',
- nzOnOk: async () => {
- const res = await lastValueFrom(
- this.api.cancelFlow({
- instanceId: d.procInsId,
- taskId: d.taskId,
- }),
- )
- this.msg.success('作废成功')
- this.table.ref.reload()
- },
- })
- }
+ ngOnInit(): void {}
}
diff --git a/web-admin-app/src/app/pages/flow/flow-my-finished/flow-my-finished.component.html b/web-admin-app/src/app/pages/flow/flow-my-finished/flow-my-finished.component.html
index c2380bf..85aa338 100644
--- a/web-admin-app/src/app/pages/flow/flow-my-finished/flow-my-finished.component.html
+++ b/web-admin-app/src/app/pages/flow/flow-my-finished/flow-my-finished.component.html
@@ -1,34 +1,12 @@
-
-
-
-
-
-
-
-
- @switch (key) {
- @case ('_assignee') {
- {{ data.userName }}
- }
- @case ('procVars') {
- {{ data?.title ?? data?.name ?? '-' }}
- }
- @case ('status') {
-
- {{ FLOW_STATUS.get(data) }}
-
- }
- @case ('urgency') {
-
- {{ row.procVars.urgency === 2 ? '紧急' : '普通' }}
-
- }
- @default {
- {{ data }}
- }
- }
-
-
+
diff --git a/web-admin-app/src/app/pages/flow/flow-my-finished/flow-my-finished.component.ts b/web-admin-app/src/app/pages/flow/flow-my-finished/flow-my-finished.component.ts
index 6be7ba3..b4ec651 100644
--- a/web-admin-app/src/app/pages/flow/flow-my-finished/flow-my-finished.component.ts
+++ b/web-admin-app/src/app/pages/flow/flow-my-finished/flow-my-finished.component.ts
@@ -12,11 +12,12 @@ import { NzMessageService } from 'ng-zorro-antd/message'
import { FormValidators } from 'app/utils'
import { comsMap } from '../flow-main/flow-main.component'
import { FLOW_STATUS, flowIntStatus } from 'app/constants'
+import { FlowListByTypeComponent } from 'app/components/flow-list-by-type/flow-list-by-type.component'
@Component({
selector: 'app-flow-my-finished',
standalone: true,
- imports: [SharedModule],
+ imports: [SharedModule, FlowListByTypeComponent],
templateUrl: './flow-my-finished.component.html',
styleUrl: './flow-my-finished.component.less',
})
@@ -34,6 +35,14 @@ export class FlowMyFinishedComponent {
userId: new FormControl ([], [FormValidators.required('请选择')]),
})
+ assetTotal = 0
+
+ deviceTotal = 0
+
+ onLoad(total: number, type: 'assetTotal' | 'deviceTotal') {
+ this[type] = total
+ }
+
table = new TableOption(this.fetchData.bind(this))
queryForm = new FormGroup({
@@ -43,23 +52,23 @@ export class FlowMyFinishedComponent {
FLOW_STATUS = flowIntStatus
ngOnInit(): void {
- this.table
- // .setConfig({
- // selectable: true,
- // rowKey: 'id',
- // })
- .setColumn([
- { key: 'procVars', title: '名称', visible: true },
- // { key: 'status', title: '审批状态', visible: true },
- { key: 'status', title: '流程状态', visible: true },
- { key: 'urgency', title: '紧急程度', visible: true },
- { key: 'procDefName', title: '流程类型', visible: true },
- { key: 'assigneeName', title: '审批人', visible: true },
- { key: 'createTime', title: '提交时间', visible: true },
- // { key: 'createTime', title: '作废时间', visible: true },
- // { key: 'createTime', title: '完成时间', visible: true },
- ])
- .setRowOperate([{ title: '查看', onClick: this.onDetail.bind(this) }])
+ // this.table
+ // // .setConfig({
+ // // selectable: true,
+ // // rowKey: 'id',
+ // // })
+ // .setColumn([
+ // { key: 'procVars', title: '名称', visible: true },
+ // // { key: 'status', title: '审批状态', visible: true },
+ // { key: 'status', title: '流程状态', visible: true },
+ // { key: 'urgency', title: '紧急程度', visible: true },
+ // { key: 'procDefName', title: '流程类型', visible: true },
+ // { key: 'assigneeName', title: '审批人', visible: true },
+ // { key: 'createTime', title: '提交时间', visible: true },
+ // // { key: 'createTime', title: '作废时间', visible: true },
+ // // { key: 'createTime', title: '完成时间', visible: true },
+ // ])
+ // .setRowOperate([{ title: '查看', onClick: this.onDetail.bind(this) }])
}
fetchData(p: {}, q: AnyObject) {
diff --git a/web-admin-app/src/app/pages/flow/flow-my-todo/flow-my-todo.component.html b/web-admin-app/src/app/pages/flow/flow-my-todo/flow-my-todo.component.html
index 69a4e8b..bb64685 100644
--- a/web-admin-app/src/app/pages/flow/flow-my-todo/flow-my-todo.component.html
+++ b/web-admin-app/src/app/pages/flow/flow-my-todo/flow-my-todo.component.html
@@ -1,4 +1,4 @@
-
+
+
+
+
+
diff --git a/web-admin-app/src/app/pages/flow/flow-my-todo/flow-my-todo.component.ts b/web-admin-app/src/app/pages/flow/flow-my-todo/flow-my-todo.component.ts
index a51af71..9ff6f76 100644
--- a/web-admin-app/src/app/pages/flow/flow-my-todo/flow-my-todo.component.ts
+++ b/web-admin-app/src/app/pages/flow/flow-my-todo/flow-my-todo.component.ts
@@ -12,11 +12,12 @@ import { NzMessageService } from 'ng-zorro-antd/message'
import { FormValidators } from 'app/utils'
import { comsMap } from '../flow-main/flow-main.component'
import { FLOW_STATUS, flowIntStatus } from 'app/constants'
+import { FlowListByTypeComponent } from 'app/components/flow-list-by-type/flow-list-by-type.component'
@Component({
selector: 'app-flow-my-todo',
standalone: true,
- imports: [SharedModule],
+ imports: [SharedModule, FlowListByTypeComponent],
templateUrl: './flow-my-todo.component.html',
styleUrl: './flow-my-todo.component.less',
})
@@ -38,6 +39,14 @@ export class FlowMyTodoComponent {
comment = ''
+ assetTotal = 0
+
+ deviceTotal = 0
+
+ onLoad(total: number, type: 'assetTotal' | 'deviceTotal') {
+ this[type] = total
+ }
+
table = new TableOption(this.fetchData.bind(this))
queryForm = new FormGroup({
diff --git a/web-admin-app/src/app/pages/flow/flow-report/flow-report.component.html b/web-admin-app/src/app/pages/flow/flow-report/flow-report.component.html
index c178d98..49c2fdf 100644
--- a/web-admin-app/src/app/pages/flow/flow-report/flow-report.component.html
+++ b/web-admin-app/src/app/pages/flow/flow-report/flow-report.component.html
@@ -1 +1,135 @@
-flow-report works!
+
+
+
+
+ 任务类型
+
+
+
+
+
+
+
+
+
+
+
+
+ 类型
+
+
+
+
+
+
+
+
+
+
+
+
+ 自定义时段
+
+
+
+
+
+
+
+
+ 编辑
+ 复制
+ 打印
+ 导出
+
+
+
+
+
+
+
+
+
+ 工作报表
+
+
+ 日期:{{ data.startDate | date: 'yyyy-MM-dd' }} ~ {{ data.endDate | date: 'yyyy-MM-dd' }}
+
+
+
+
+ {{ reportTypeText.get(reportType) }}工作概述
+
+
+
+
+
+
+ -
+
{{ data.taskCount ?? 0 }}
+ 累计处理任务数
+
+ -
+
{{ data.taskCount ?? 0 }}
+ 已完成任务数
+
+ -
+
{{ data.taskCount ?? 0 }}
+ 未完成任务数
+
+
+
+
+
+ @for (item of data.taskList; track $index) {
+
+ }
+
+
+
+
+
+
+
+
+
diff --git a/web-admin-app/src/app/pages/flow/flow-report/flow-report.component.less b/web-admin-app/src/app/pages/flow/flow-report/flow-report.component.less
index e69de29..c7fc982 100644
--- a/web-admin-app/src/app/pages/flow/flow-report/flow-report.component.less
+++ b/web-admin-app/src/app/pages/flow/flow-report/flow-report.component.less
@@ -0,0 +1,127 @@
+.report {
+
+
+ padding: 24px;
+ background-color: #fff;
+
+ h1 {
+ font-size: 22px;
+ }
+
+ h2 {
+ font-size: 18x;
+ }
+
+ .report-title {
+ position: relative;
+
+ }
+
+ .echart {
+ height: 205px;
+
+ }
+
+ .pie {
+ width: 200px;
+ }
+
+ .line {
+ flex: 1;
+ }
+
+ .report-title-left {
+ font-size: 24px;
+ text-align: center;
+ }
+
+ .report-title-right {
+ position: absolute;
+ bottom: 5px;
+ right: 0;
+ }
+
+ .report-footer {
+ text-align: right;
+
+ &>div {
+ margin-top: 12px;
+ }
+ }
+
+ .report-content-row {
+ min-height: 220px;
+
+ textarea {
+ width: 100%;
+ min-height: 150px;
+ border: 1px solid #ccc;
+
+ &:focus,
+ &:active,
+ &:hover {
+ outline: none;
+ border: 1px solid #ccc;
+ }
+ }
+ }
+
+ .report-content-row-content {
+ display: flex;
+
+ .report-content-row-left {
+ display: flex;
+ flex-basis: 60%;
+ flex-shrink: 0;
+ }
+
+ .report-content-row-right {
+ padding-left: 24px;
+ flex: 1;
+ }
+ }
+
+ .counter {
+ display: flex;
+ justify-content: center;
+
+
+
+
+ li {
+ margin: 0 12px;
+ padding: 24px 0;
+ flex: 1;
+ text-align: center;
+ border: 1px dashed #027db4;
+
+ &.error {
+ border-color: #d9001b;
+
+ p {
+ color: #d9001b;
+ }
+ }
+
+ &.success {
+ border-color: #70b603;
+
+ p {
+ color: #70b603;
+ }
+ }
+
+ p {
+ margin-bottom: 6px;
+ color: #027db4;
+
+ &:first-child {
+
+ font-size: 20px;
+ font-weight: bold;
+ }
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/web-admin-app/src/app/pages/flow/flow-report/flow-report.component.ts b/web-admin-app/src/app/pages/flow/flow-report/flow-report.component.ts
index 3ab3eec..96fa60f 100644
--- a/web-admin-app/src/app/pages/flow/flow-report/flow-report.component.ts
+++ b/web-admin-app/src/app/pages/flow/flow-report/flow-report.component.ts
@@ -1,12 +1,217 @@
-import { Component } from '@angular/core';
+import { Component, ElementRef, QueryList, ViewChildren } from '@angular/core'
+import { FormControl, FormGroup } from '@angular/forms'
+import { ApiService } from 'app/services'
+import { SharedModule } from 'app/shared/shared.module'
+import { NzSafeAny } from 'ng-zorro-antd/core/types'
+import {
+ startOfDay,
+ endOfDay,
+ startOfWeek,
+ endOfWeek,
+ startOfMonth,
+ endOfMonth,
+ startOfYear,
+ endOfYear,
+ format,
+} from 'date-fns'
+import { finalize } from 'rxjs'
+
+import { init, EChartsType } from 'echarts'
+
+function getDateRange(n: number): { startDate: string; endDate: string } {
+ const today = new Date()
+
+ let startDate: Date
+ let endDate: Date
+
+ switch (n) {
+ case 0: // Today
+ startDate = startOfDay(today)
+ endDate = endOfDay(today)
+ break
+ case 1: // This Week
+ startDate = startOfWeek(today, { weekStartsOn: 1 })
+ endDate = endOfWeek(today, { weekStartsOn: 1 })
+ break
+ case 2: // This Month
+ startDate = startOfMonth(today)
+ endDate = endOfMonth(today)
+ break
+ case 3: // This Year
+ startDate = startOfYear(today)
+ endDate = endOfYear(today)
+ break
+ default:
+ throw new Error('Invalid parameter. Please provide a number between 0 and 3.')
+ }
+
+ return {
+ startDate: format(startDate, 'yyyy-MM-dd'),
+ endDate: format(endDate, 'yyyy-MM-dd'),
+ }
+}
@Component({
- selector: 'app-flow-report',
- standalone: true,
- imports: [],
- templateUrl: './flow-report.component.html',
- styleUrl: './flow-report.component.less'
+ selector: 'app-flow-report',
+ standalone: true,
+ imports: [SharedModule],
+ templateUrl: './flow-report.component.html',
+ styleUrl: './flow-report.component.less',
})
export class FlowReportComponent {
+ constructor(private api: ApiService) {}
+
+ formKeys: NzSafeAny[] = []
+
+ reportType: number = 0
+
+ range: Date[] = []
+
+ data: NzSafeAny
+
+ loading = false
+
+ today = format(new Date(), 'yyyy年MM月dd日')
+
+ reportTypeText = new Map([
+ [0, '今日'],
+ [1, '本周'],
+ [2, '本月'],
+ [3, '本年'],
+ ])
+
+ gaishu = `
+ 1、本周
+ 2、继续对所有锅炉和电梯设备进行定期巡检,确保设备安全稳定运行。
+ 3、根据本周巡检结果,对设备维护计划进行必要的调整,以提高设备运行效率和安全性。`
+
+ plan = `
+ 1、安排专业人员对{锅炉001}进行返修,确保设备尽快恢复正常运行。
+ 2、继续对所有锅炉和电梯设备进行定期巡检,确保设备安全稳定运行。
+ 3、根据本周巡检结果,对设备维护计划进行必要的调整,以提高设备运行效率和安全性。
+ `
+
+ zongjie = `
+ 本周的巡检和检修工作总体顺利,除了锅炉001需要返修外,其他设备均运行正常。
+ 我们将继续密切关注设备状态,并及时处理任何潜在问题,以确保公司运营的顺畅和安全。
+ 请各部门继续配合我们的工作,如有任何问题或建议,请及时与我们联系。
+
+ `
+
+ @ViewChildren('itemElement') itemElements!: QueryList
+
+ ngOnInit() {
+ this.onTypeChange(this.reportType)
+ }
+
+ ngAfterViewInit() {}
+
+ onTypeChange(n: number) {
+ const { startDate, endDate } = getDateRange(n)
+ this.range = [new Date(startDate), new Date(endDate)]
+ this.onChange()
+ }
+ onChange() {
+ let startDate = ''
+ let endDate = ''
+ this.loading = true
+ if (this.range.length === 2) {
+ startDate = format(this.range[0], 'yyyy-MM-dd')
+ endDate = format(this.range[1], 'yyyy-MM-dd')
+ }
+ this.api
+ .getReportData({
+ formKeys: this.formKeys,
+ reportType: this.reportType,
+ startDate,
+ endDate,
+ })
+ .pipe(
+ finalize(() => {
+ this.loading = false
+ }),
+ )
+ .subscribe((res) => {
+ this.data = res.body
+ setTimeout(() => {
+ console.log('this.data', this.itemElements)
+ this.itemElements.forEach((itemElement, index) => {
+ console.log(`Element ${index}: `, itemElement.nativeElement)
+ this.renderPie(itemElement.nativeElement, [])
+ this.renderLine(itemElement.nativeElement, [])
+ })
+ }, 0)
+ })
+ }
+
+ renderLine(el: HTMLElement, data: NzSafeAny[]) {
+ el = el.querySelector('.line') as HTMLDivElement
+ if (el) {
+ const lineRef = init(el)
+ const name: string[] = []
+ const value: number[] = []
+ data?.forEach((i: NzSafeAny) => {
+ name.push(i.name)
+ value.push(i.value)
+ })
+ lineRef.setOption({
+ xAxis: {
+ type: 'category',
+ data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
+ },
+ yAxis: {
+ type: 'value',
+ },
+ series: [
+ {
+ data: [820, 932, 901, 934, 1290, 1330, 1320],
+ type: 'line',
+ smooth: true,
+ },
+ ],
+ })
+ }
+ }
+ renderPie(el: HTMLElement, data: NzSafeAny[]) {
+ el = el.querySelector('.pie') as HTMLDivElement
+ if (el) {
+ const pieRef = init(el)
+ let data: NzSafeAny[] = []
+ const odata: NzSafeAny[] = data ?? []
+ const total = odata.reduce((a: number, b: any) => a + Math.abs(b.value), 0)
+
+ data = odata.map((i: NzSafeAny) => {
+ const value = Math.abs(i.value)
+ const percent = ((value / total) * 100).toFixed(2)
+
+ return {
+ ...i,
+ percent,
+ value,
+ }
+ })
+ pieRef.setOption({
+ title: {
+ text: '',
+ },
+ series: [
+ {
+ name: 'Access From',
+ type: 'pie',
+ radius: ['40%', '70%'],
+ avoidLabelOverlap: false,
+ label: {
+ show: false,
+ position: 'center',
+ },
+ data: [
+ { value: 1048, name: 'Search Engine' },
+ { value: 735, name: 'Direct' },
+ ],
+ },
+ ],
+ })
+ }
+ }
}
diff --git a/web-admin-app/src/app/pages/msg/flow-msg/flow-msg.component.ts b/web-admin-app/src/app/pages/msg/flow-msg/flow-msg.component.ts
index d2d9c12..17ec2da 100644
--- a/web-admin-app/src/app/pages/msg/flow-msg/flow-msg.component.ts
+++ b/web-admin-app/src/app/pages/msg/flow-msg/flow-msg.component.ts
@@ -43,11 +43,11 @@ export class FlowMsgComponent {
// rowKey: 'id',
// })
.setColumn([
- { key: 'logId', title: '序号', visible: true },
+ // { key: 'logId', title: '序号', visible: true },
{ key: 'createTime', title: '时间', visible: true },
- { key: 'logType', title: '类型', visible: true },
- { key: 'logContent', title: '内容', visible: true },
- { key: 'logContent', title: '待我处理', visible: true },
+ // { key: 'logType', title: '类型', visible: true },
+ { key: 'content', title: '内容', visible: true },
+ // { key: 'logContent', title: '待我处理', visible: true },
])
}
diff --git a/web-admin-app/src/app/services/api.service.ts b/web-admin-app/src/app/services/api.service.ts
index 05fee66..485a47c 100644
--- a/web-admin-app/src/app/services/api.service.ts
+++ b/web-admin-app/src/app/services/api.service.ts
@@ -55,6 +55,13 @@ export class ApiService {
uploadLicenseInfo(formData: FormData) {
return this.http.post('/api/license/update', formData)
}
+ importFlowFormByExcel(formData: FormData) {
+ return this.http.post('/api/v2/sysFormTemp/importByExcel', formData)
+ }
+
+ uploadFormTpl(formData: FormData) {
+ return this.http.post(`/api/v2/sysFormTemp/upload`, formData)
+ }
login(data: {}) {
return this.http.post('/api/oauth/login', data).pipe(
@@ -194,8 +201,9 @@ export class ApiService {
responseType: 'blob' as 'json',
})
}
- downloadAssetTemplate() {
+ downloadAssetTemplate(categoryId?: string) {
return this.http.post(`/api/eamAsset/importTemplate`, null, {
+ params: categoryId ? { categoryId } : {},
observe: 'response',
responseType: 'blob' as 'json',
})
@@ -617,6 +625,12 @@ export class ApiService {
responseType: 'blob' as 'json',
})
}
+ downloadTpl() {
+ return this.http.post(`/api/v2/sysFormTemp/formTemplate`, null, {
+ observe: 'response',
+ responseType: 'blob' as 'json',
+ })
+ }
addFlowForm(data: NzSafeAny) {
return this.http.post(`/api/v2/sysFormTemp/add`, data)
@@ -624,6 +638,9 @@ export class ApiService {
updateFlowForm(data: NzSafeAny) {
return this.http.post(`/api/v2/sysFormTemp/update`, data)
}
+ confirmFlowForm(data: NzSafeAny) {
+ return this.http.post(` /api/v2/sysFormTemp/confirm`, data)
+ }
deleteFlowForm(idList: NzSafeAny) {
return this.http.post(`/api/v2/sysFormTemp/delete`, idList)
@@ -698,7 +715,7 @@ export class ApiService {
return this.http.post('/api/v2/alarm/list', data)
}
getFlowMsg(data: {}) {
- return this.http.post('/api/flowable/task/todoListMSG ', data)
+ return this.http.post('/api/flowable/task/todoListMSG', data)
}
getCalendarData(data: {}) {
return this.http.post('/api/flFormItem/calendar', data)
@@ -709,4 +726,41 @@ export class ApiService {
flowFormUpdate(d: {}) {
return this.http.post('/api/flForm/update', d)
}
+ deviceLog(d: {}) {
+ return this.http.post('/api/eamAssetLog/list/device', d)
+ }
+ assetFlowRecord(d: {}) {
+ return this.http.post('/api/flowable/task/flowRecord', d)
+ }
+ operationalStatistics(d: {}) {
+ return this.http.get('/api/eamAsset/operationalStatistics', {
+ params: d,
+ })
+ }
+ downloadTaskReport(id: string) {
+ return this.http.post(`/api/v2/flowable/device/export/${id}`, null, {
+ observe: 'response',
+ responseType: 'blob' as 'json',
+ })
+ }
+ exportFlowForm(idList: string[]) {
+ return this.http.post(`/api/v2/sysFormTemp/exportExcel`, idList, {
+ observe: 'response',
+ responseType: 'blob' as 'json',
+ })
+ }
+ onOffRecord(id: string) {
+ return this.http.post(`/api/v2/device/record`, null, {
+ params: { id },
+ })
+ }
+ getReportData(data: {}) {
+ return this.http.post(`/api/flFormItem/workReport`, data)
+ }
+ saveReport(content: string) {
+ return this.http.post(`api/flFormItem/h5str2word`, null, { params: { content } })
+ }
+ bigScreen() {
+ return this.http.post(`/api/home/bigScreen`, null)
+ }
}
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 6840138..0a4526d 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
@@ -94,7 +94,7 @@
-
+
diff --git a/web-admin-app/src/app/shared/components/server-paginated-table/server-paginated-table.component.html b/web-admin-app/src/app/shared/components/server-paginated-table/server-paginated-table.component.html
index 24379a0..b10f935 100644
--- a/web-admin-app/src/app/shared/components/server-paginated-table/server-paginated-table.component.html
+++ b/web-admin-app/src/app/shared/components/server-paginated-table/server-paginated-table.component.html
@@ -90,7 +90,7 @@
}
}
@if (options.operate.length > 0) {
- 操作 |
+ 操作 |
}
@if (options.columns.length > 3) {
@@ -142,26 +142,24 @@
@if (options.operate.length > 0) {
|
-
-
-
-
-
- @for (operate of options.operate; track operate.title) {
- @if (operate?.visible(data)) {
- -
- {{ operate.title }}
-
- }
+
+
+
+
+
+ @for (operate of options.operate; track operate.title) {
+ @if (operate?.visible(data)) {
+
+ {{ operate.title }}
+
}
-
-
+ }
+
|
}
@if (options.columns.length > 3) {
diff --git a/web-admin-app/src/app/utils/index.ts b/web-admin-app/src/app/utils/index.ts
index 156beb2..ce4acc7 100644
--- a/web-admin-app/src/app/utils/index.ts
+++ b/web-admin-app/src/app/utils/index.ts
@@ -98,6 +98,7 @@ export class Utils {
}
static downLoadFile(response: HttpResponse |