65 changed files with 407 additions and 2479 deletions
@ -1,12 +0,0 @@ |
|||||
<form nz-form [formGroup]="formGroup"> |
|
||||
<nz-form-item> |
|
||||
<nz-form-label> 部门名称 </nz-form-label> |
|
||||
<nz-form-control [nzErrorTip]="formErrorTipsTpl"> |
|
||||
<input nz-input placeholder="请输入部门名称" formControlName="name" /> |
|
||||
</nz-form-control> |
|
||||
</nz-form-item> |
|
||||
</form> |
|
||||
|
|
||||
<ng-template #formErrorTipsTpl let-control> |
|
||||
<form-error-tips [control]="control"></form-error-tips> |
|
||||
</ng-template> |
|
@ -1,38 +0,0 @@ |
|||||
import { Component, OnInit, inject } from '@angular/core' |
|
||||
import { FormControl, FormGroup } from '@angular/forms' |
|
||||
import { SharedModule } from 'app/shared/shared.module' |
|
||||
import { FormValidators } from 'app/utils' |
|
||||
import { NZ_MODAL_DATA } from 'ng-zorro-antd/modal' |
|
||||
|
|
||||
@Component({ |
|
||||
selector: 'app-contact-group-form', |
|
||||
standalone: true, |
|
||||
imports: [SharedModule], |
|
||||
templateUrl: './contact-group-form.component.html', |
|
||||
styleUrl: './contact-group-form.component.less', |
|
||||
}) |
|
||||
export class ContactGroupFormComponent implements OnInit { |
|
||||
constructor() {} |
|
||||
|
|
||||
data = inject(NZ_MODAL_DATA) |
|
||||
|
|
||||
formGroup = new FormGroup({ |
|
||||
id: new FormControl(), |
|
||||
name: new FormControl('', [FormValidators.required('请输入部门名称'), FormValidators.maxLength(30)]), |
|
||||
parentId: new FormControl(), |
|
||||
}) |
|
||||
|
|
||||
ngOnInit(): void { |
|
||||
if (this.data) { |
|
||||
this.formGroup.patchValue(this.data) |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public getValues() { |
|
||||
let values = null |
|
||||
if (FormValidators.validateFormGroup(this.formGroup)) { |
|
||||
values = this.formGroup.value |
|
||||
} |
|
||||
return values |
|
||||
} |
|
||||
} |
|
@ -1,31 +0,0 @@ |
|||||
<div class="data-tree"> |
|
||||
<nz-tree |
|
||||
nzBlockNode |
|
||||
[nzSelectedKeys]="contact.selecedKeys" |
|
||||
[nzExpandedKeys]="contact.expandedKeys" |
|
||||
[nzData]="nodes" |
|
||||
(nzClick)="activeNode($event)" |
|
||||
(nzExpandChange)="handleExpandedKeysChange($event)" |
|
||||
[nzTreeTemplate]="nzTreeTemplate" |
|
||||
> |
|
||||
</nz-tree> |
|
||||
</div> |
|
||||
|
|
||||
<ng-template #nzTreeTemplate let-node let-origin="origin"> |
|
||||
<div class="flex items-center justify-between overflow-hidden"> |
|
||||
<span class="flex-1 overflow-hidden text-ellipsis">{{ node.title }}</span> |
|
||||
|
|
||||
@if (origin.id !== '1') { |
|
||||
<button nz-button nzType="text" nz-dropdown [nzDropdownMenu]="menu" (click)="$event.stopPropagation()"> |
|
||||
<i nz-icon nzType="more"></i> |
|
||||
</button> |
|
||||
} |
|
||||
<nz-dropdown-menu #menu="nzDropdownMenu"> |
|
||||
<ul nz-menu> |
|
||||
<!-- <li nz-menu-item (click)="createGroup(node)">新增下级部门</li> --> |
|
||||
<li nz-menu-item (click)="editGroup(node)">编辑</li> |
|
||||
<li nz-menu-item (click)="deleteGroup(node)">删除</li> |
|
||||
</ul> |
|
||||
</nz-dropdown-menu> |
|
||||
</div> |
|
||||
</ng-template> |
|
@ -1,83 +0,0 @@ |
|||||
import { Component, EventEmitter, Input, Output, OnChanges, OnInit, SimpleChanges } from '@angular/core' |
|
||||
|
|
||||
import { NzContextMenuService, NzDropdownMenuComponent } from 'ng-zorro-antd/dropdown' |
|
||||
import { NzFormatEmitEvent, NzTreeNode, NzTreeNodeOptions } from 'ng-zorro-antd/tree' |
|
||||
import { SharedModule } from 'app/shared/shared.module' |
|
||||
import { Persist } from 'app/utils' |
|
||||
import { ContactService } from '../contact.service' |
|
||||
|
|
||||
@Component({ |
|
||||
selector: 'app-contact-group', |
|
||||
standalone: true, |
|
||||
imports: [SharedModule], |
|
||||
providers: [ContactService], |
|
||||
templateUrl: './contact-group.component.html', |
|
||||
styleUrl: './contact-group.component.less', |
|
||||
}) |
|
||||
export class ContactGroupComponent implements OnInit, OnChanges { |
|
||||
constructor( |
|
||||
private nzContextMenuService: NzContextMenuService, |
|
||||
public contact: ContactService, |
|
||||
) {} |
|
||||
|
|
||||
@Input() nodes: NzTreeNodeOptions[] = [] |
|
||||
|
|
||||
@Input() active!: Persist |
|
||||
|
|
||||
@Output() onSelect = new EventEmitter() |
|
||||
|
|
||||
@Output() onCreate = new EventEmitter() |
|
||||
|
|
||||
@Output() onEdit = new EventEmitter() |
|
||||
|
|
||||
@Output() onDelete = new EventEmitter() |
|
||||
|
|
||||
ngOnInit(): void {} |
|
||||
|
|
||||
ngOnChanges(changes: SimpleChanges) {} |
|
||||
|
|
||||
openFolder(data: NzTreeNode | NzFormatEmitEvent): void { |
|
||||
if (data instanceof NzTreeNode) { |
|
||||
data.isExpanded = !data.isExpanded |
|
||||
} else { |
|
||||
const node = data.node |
|
||||
if (node) { |
|
||||
node.isExpanded = !node.isExpanded |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
activeNode(data: NzFormatEmitEvent): void { |
|
||||
this.contact.contactGroup.update((state) => { |
|
||||
return { |
|
||||
...state, |
|
||||
selecedKeys: [data.node!.key], |
|
||||
} |
|
||||
}) |
|
||||
this.onSelect.emit() |
|
||||
} |
|
||||
|
|
||||
handleExpandedKeysChange(expanded: NzFormatEmitEvent) { |
|
||||
this.contact.contactGroup.update((state) => { |
|
||||
return { |
|
||||
...state, |
|
||||
expandedKeys: expanded?.keys ?? [], |
|
||||
} |
|
||||
}) |
|
||||
} |
|
||||
|
|
||||
contextMenu($event: MouseEvent, menu: NzDropdownMenuComponent): void { |
|
||||
this.nzContextMenuService.create($event, menu) |
|
||||
} |
|
||||
|
|
||||
createGroup(node: NzTreeNode): void { |
|
||||
this.onCreate.emit(node.origin) |
|
||||
} |
|
||||
|
|
||||
editGroup(node: NzTreeNode): void { |
|
||||
this.onEdit.emit(node.origin) |
|
||||
} |
|
||||
deleteGroup(node: NzTreeNode): void { |
|
||||
this.onDelete.emit(node.origin.key) |
|
||||
} |
|
||||
} |
|
@ -1,97 +0,0 @@ |
|||||
<nz-card [nzBordered]="false" [nzBodyStyle]="{ padding: 0, height }"> |
|
||||
<div class="flex contacts h-full"> |
|
||||
<div class="group w-56 h-full flex flex-col"> |
|
||||
<div> |
|
||||
<h3 class="px-4 pt-4 flex items-center justify-between"> |
|
||||
<span>部门</span> |
|
||||
<button nz-button nzType="text" (click)="showGroupForm()"> |
|
||||
<i nz-icon nzType="plus"></i> |
|
||||
</button> |
|
||||
</h3> |
|
||||
</div> |
|
||||
|
|
||||
<div class="flex-1 overflow-y-auto"> |
|
||||
<app-contact-group |
|
||||
[nodes]="groups" |
|
||||
(onSelect)="handleGroupSelect()" |
|
||||
(onCreate)="showGroupForm($event)" |
|
||||
(onEdit)="showGroupForm($event, true)" |
|
||||
(onDelete)="deleteUserGroup($event)" |
|
||||
> |
|
||||
</app-contact-group> |
|
||||
</div> |
|
||||
</div> |
|
||||
<div class="flex-1 p-4 overflow-auto"> |
|
||||
<app-server-paginated-table |
|
||||
[formGroup]="queryForm" |
|
||||
[renderColumn]="renderColumnTpl" |
|
||||
[options]="tableOption" |
|
||||
> |
|
||||
<div *appTableForm nz-row [nzGutter]="[24, 24]"> |
|
||||
<div nz-col nzSpan="8"> |
|
||||
<nz-form-item> |
|
||||
<nz-form-label nzFlex="80px">用户名</nz-form-label> |
|
||||
<nz-form-control nzFlex="1"> |
|
||||
<input nz-input placeholder="请输入用户名" formControlName="userName" /> |
|
||||
</nz-form-control> |
|
||||
</nz-form-item> |
|
||||
</div> |
|
||||
<div nz-col nzSpan="8"> |
|
||||
<nz-form-item> |
|
||||
<nz-form-label nzFlex="80px">姓名</nz-form-label> |
|
||||
<nz-form-control nzFlex="1"> |
|
||||
<input nz-input placeholder="请输入姓名" formControlName="name" /> |
|
||||
</nz-form-control> |
|
||||
</nz-form-item> |
|
||||
</div> |
|
||||
<div nz-col nzSpan="8"> |
|
||||
<nz-form-item> |
|
||||
<nz-form-label nzFlex="80px">状态</nz-form-label> |
|
||||
<nz-form-control nzFlex="1"> |
|
||||
<nz-select nzPlaceHolder="请选择状态" formControlName="enable" nzAllowClear> |
|
||||
<nz-option [nzValue]="true" nzLabel="启用"></nz-option> |
|
||||
<nz-option [nzValue]="false" nzLabel="禁用"></nz-option> |
|
||||
</nz-select> |
|
||||
</nz-form-control> |
|
||||
</nz-form-item> |
|
||||
</div> |
|
||||
<div nz-col nzSpan="8"> |
|
||||
<nz-form-item> |
|
||||
<nz-form-label nzFlex="80px">创建时间</nz-form-label> |
|
||||
<nz-form-control nzFlex="1"> |
|
||||
<!-- <nz-range-picker formControlName="createTime"></nz-range-picker> --> |
|
||||
<app-range-picker [showTime]="true" formControlName="createTime"></app-range-picker> |
|
||||
</nz-form-control> |
|
||||
</nz-form-item> |
|
||||
</div> |
|
||||
</div> |
|
||||
<div *appTableAction> |
|
||||
<nz-space> |
|
||||
<button nz-button nzType="primary" (click)="handleCreateUser()">添加用户</button> |
|
||||
</nz-space> |
|
||||
</div> |
|
||||
<ng-template #renderColumnTpl let-data let-key="key"> |
|
||||
@switch (key) { |
|
||||
@case ('enable') { |
|
||||
@if (data) { |
|
||||
<nz-badge nzStatus="success" nzText="启用"></nz-badge> |
|
||||
} @else { |
|
||||
<nz-badge nzStatus="error" nzText="禁用"></nz-badge> |
|
||||
} |
|
||||
} |
|
||||
@case ('roleName') { |
|
||||
@if (data) { |
|
||||
<nz-tag>{{ data }}</nz-tag> |
|
||||
} @else { |
|
||||
- |
|
||||
} |
|
||||
} |
|
||||
@default { |
|
||||
{{ data }} |
|
||||
} |
|
||||
} |
|
||||
</ng-template> |
|
||||
</app-server-paginated-table> |
|
||||
</div> |
|
||||
</div> |
|
||||
</nz-card> |
|
@ -1,3 +0,0 @@ |
|||||
.group { |
|
||||
border-right: 1px solid var(--border-color); |
|
||||
} |
|
@ -1,223 +0,0 @@ |
|||||
import { Component, HostListener, OnInit, OnDestroy } from '@angular/core' |
|
||||
import { lastValueFrom } from 'rxjs' |
|
||||
import { NzTreeNodeOptions } from 'ng-zorro-antd/tree' |
|
||||
import { NzModalService } from 'ng-zorro-antd/modal' |
|
||||
import { FormControl, FormGroup } from '@angular/forms' |
|
||||
import { NzMessageService } from 'ng-zorro-antd/message' |
|
||||
import { format } from 'date-fns' |
|
||||
import { ApiService, UserGroupTreeItem } from 'app/services' |
|
||||
import { SharedModule } from 'app/shared/shared.module' |
|
||||
import { ContactGroupComponent } from '../contact-group/contact-group.component' |
|
||||
import { ContactGroupFormComponent } from '../contact-group-form/contact-group-form.component' |
|
||||
import { AnyObject, TableOption } from 'app/components/server-paginated-table' |
|
||||
import { UserFormComponent } from 'app/components/user-form/user-form.component' |
|
||||
import { RoleListDTO, UserDTO } from 'app/services/api.dto' |
|
||||
import { ContactService } from '../contact.service' |
|
||||
|
|
||||
@Component({ |
|
||||
selector: 'app-contact-list', |
|
||||
standalone: true, |
|
||||
imports: [SharedModule, ContactGroupComponent, ContactGroupFormComponent], |
|
||||
templateUrl: './contact-list.component.html', |
|
||||
styleUrl: './contact-list.component.less', |
|
||||
providers: [ContactService], |
|
||||
}) |
|
||||
export class ContactListComponent implements OnInit, OnDestroy { |
|
||||
constructor( |
|
||||
private api: ApiService, |
|
||||
private modal: NzModalService, |
|
||||
private msg: NzMessageService, |
|
||||
private contact: ContactService, |
|
||||
) {} |
|
||||
|
|
||||
height = 'auto' |
|
||||
|
|
||||
groups: NzTreeNodeOptions[] = [] |
|
||||
|
|
||||
tableOption = new TableOption(this.fetchData.bind(this), { |
|
||||
manual: true, |
|
||||
}) |
|
||||
|
|
||||
queryForm = new FormGroup({ |
|
||||
userName: new FormControl(), |
|
||||
enable: new FormControl(), |
|
||||
name: new FormControl(), |
|
||||
createTime: new FormControl(), |
|
||||
}) |
|
||||
|
|
||||
roleList: RoleListDTO[] = [] |
|
||||
|
|
||||
ngOnInit(): void { |
|
||||
this.initTableOption() |
|
||||
this.onResize() |
|
||||
this.getUserGroupTree() |
|
||||
this.getRoleList() |
|
||||
} |
|
||||
|
|
||||
ngOnDestroy(): void {} |
|
||||
|
|
||||
initTableOption() { |
|
||||
this.tableOption |
|
||||
.setColumn([ |
|
||||
{ key: 'username', title: '用户名' }, |
|
||||
{ key: 'name', title: '姓名' }, |
|
||||
{ key: 'enable', title: '状态' }, |
|
||||
{ key: 'roleName', title: '角色' }, |
|
||||
{ key: 'remark', title: '说明' }, |
|
||||
{ key: 'createTime', title: '创建时间' }, |
|
||||
]) |
|
||||
.setRowOperate([ |
|
||||
{ title: '启用', onClick: this.updateStatus.bind(this), visible: (v) => v.id !== '1' && !v.enable }, |
|
||||
{ title: '禁用', onClick: this.updateStatus.bind(this), visible: (v) => v.id !== '1' && v.enable }, |
|
||||
{ |
|
||||
title: '重置密码', |
|
||||
onClick: this.resetPassword.bind(this), |
|
||||
premissions: [], |
|
||||
visible: (v) => v.id !== '1', |
|
||||
}, |
|
||||
{ |
|
||||
title: '编辑', |
|
||||
onClick: this.handleCreateUser.bind(this), |
|
||||
premissions: [], |
|
||||
visible: (v) => v.id !== '1', |
|
||||
}, |
|
||||
{ |
|
||||
title: '删除', |
|
||||
onClick: this.deleteUser.bind(this), |
|
||||
premissions: [], |
|
||||
visible: (v) => v.id !== '1', |
|
||||
}, |
|
||||
]) |
|
||||
} |
|
||||
|
|
||||
@HostListener('window:resize') |
|
||||
onResize() { |
|
||||
this.height = innerHeight - 100 + 'px' |
|
||||
} |
|
||||
|
|
||||
fetchData(p: {}, q: AnyObject) { |
|
||||
let query = Object.create(null) |
|
||||
const activeGroup = this.contact.contactGroup.value |
|
||||
if (Array.isArray(q['createTime'])) { |
|
||||
const createTimeStart = q['createTime']?.[0] |
|
||||
const createTimeEnd = q['createTime']?.[1] |
|
||||
|
|
||||
q['createTimeStart'] = createTimeStart ? format(new Date(createTimeStart), 'yyyy-MM-dd HH:mm:ss') : '' |
|
||||
q['createTimeEnd'] = createTimeEnd ? format(new Date(createTimeEnd), 'yyyy-MM-dd HH:mm:ss') : '' |
|
||||
} |
|
||||
query = { ...q, groupId: activeGroup?.selecedKeys[0] } |
|
||||
return this.api.getUserPage(p, query) |
|
||||
} |
|
||||
|
|
||||
handleGroupSelect() { |
|
||||
this.tableOption.ref?.search() |
|
||||
} |
|
||||
|
|
||||
updateStatus(v: UserDTO) { |
|
||||
this.modal.confirm({ |
|
||||
nzTitle: '警告', |
|
||||
nzContent: `是否要${v.enable ? '禁用' : '启用'}该用户?`, |
|
||||
nzOnOk: async () => { |
|
||||
await lastValueFrom(this.api.updateUserStatus(v.id)) |
|
||||
this.msg.success('操作成功') |
|
||||
this.tableOption.ref.reload() |
|
||||
}, |
|
||||
}) |
|
||||
} |
|
||||
|
|
||||
getUserGroupTree() { |
|
||||
this.api.getUserGroupTree().subscribe((res) => { |
|
||||
this.groups = res |
|
||||
this.contact.initState(res) |
|
||||
if (res.length > 0) { |
|
||||
this.tableOption.ref?.reload() |
|
||||
} |
|
||||
}) |
|
||||
} |
|
||||
|
|
||||
getRoleList() { |
|
||||
this.api.getAllRole().subscribe((res) => { |
|
||||
this.roleList = res.data |
|
||||
}) |
|
||||
} |
|
||||
|
|
||||
showGroupForm(group?: UserGroupTreeItem, edit = false) { |
|
||||
this.modal.create({ |
|
||||
nzTitle: edit ? '编辑部门' : '新增部门', |
|
||||
nzContent: ContactGroupFormComponent, |
|
||||
nzData: edit ? group : { parentId: group?.id }, |
|
||||
nzOnOk: async (e) => { |
|
||||
const vals = e.getValues() |
|
||||
if (vals) { |
|
||||
await lastValueFrom(this.api.saveUserGroup(vals as UserGroupTreeItem)) |
|
||||
this.msg.success('保存成功') |
|
||||
this.getUserGroupTree() |
|
||||
return true |
|
||||
} |
|
||||
return false |
|
||||
}, |
|
||||
}) |
|
||||
} |
|
||||
|
|
||||
deleteUserGroup(id: string) { |
|
||||
this.modal.confirm({ |
|
||||
nzTitle: '警告', |
|
||||
nzContent: '是否要删除该分组?', |
|
||||
nzOkDanger: true, |
|
||||
nzOnOk: async () => { |
|
||||
await lastValueFrom(this.api.deleteUserGroup(id)) |
|
||||
this.msg.success('删除成功') |
|
||||
this.getUserGroupTree() |
|
||||
}, |
|
||||
}) |
|
||||
} |
|
||||
|
|
||||
deleteUser(v: UserDTO) { |
|
||||
this.modal.confirm({ |
|
||||
nzTitle: '警告', |
|
||||
nzContent: '是否要删除该用户?', |
|
||||
nzOkDanger: true, |
|
||||
nzOnOk: async () => { |
|
||||
await lastValueFrom(this.api.deleteUser(v.id)) |
|
||||
this.msg.success('删除成功') |
|
||||
this.getUserGroupTree() |
|
||||
}, |
|
||||
}) |
|
||||
} |
|
||||
|
|
||||
resetPassword(v: UserDTO) { |
|
||||
this.modal.confirm({ |
|
||||
nzTitle: '警告', |
|
||||
nzContent: '是否要将该用户的密码重置为jwkj?', |
|
||||
nzOnOk: async () => { |
|
||||
await lastValueFrom(this.api.changeUserPassword(v.id, 'jwkj')) |
|
||||
this.msg.success('重置成功') |
|
||||
}, |
|
||||
}) |
|
||||
} |
|
||||
|
|
||||
handleCreateUser(user?: UserDTO) { |
|
||||
this.modal.create({ |
|
||||
nzTitle: user ? '编辑用户' : '添加用户', |
|
||||
nzContent: UserFormComponent, |
|
||||
nzWidth: 720, |
|
||||
nzData: { |
|
||||
roleList: this.roleList, |
|
||||
value: user, |
|
||||
}, |
|
||||
nzOnOk: async (e) => { |
|
||||
const vals = e.getValues() |
|
||||
if (vals) { |
|
||||
const activeGroup = this.contact.contactGroup.value |
|
||||
await lastValueFrom( |
|
||||
this.api.saveUser({ ...(user ?? {}), ...vals, groupId: activeGroup.selecedKeys[0] }), |
|
||||
) |
|
||||
this.tableOption.ref?.reload() |
|
||||
this.msg.success('保存成功') |
|
||||
return true |
|
||||
} |
|
||||
return false |
|
||||
}, |
|
||||
}) |
|
||||
} |
|
||||
} |
|
@ -1,59 +0,0 @@ |
|||||
import { Injectable, OnDestroy } from '@angular/core' |
|
||||
import { Persist, Utils } from 'app/utils' |
|
||||
import { NzTreeNodeOptions } from 'ng-zorro-antd/tree' |
|
||||
|
|
||||
@Injectable() |
|
||||
export class ContactService implements OnDestroy { |
|
||||
constructor() {} |
|
||||
|
|
||||
ngOnDestroy(): void { |
|
||||
this.contactGroup.clear() |
|
||||
} |
|
||||
|
|
||||
contactGroup = new Persist<{ selecedKeys: string[]; expandedKeys: string[] }>(sessionStorage, 'contactGroup', { |
|
||||
selecedKeys: [], |
|
||||
expandedKeys: [], |
|
||||
}) |
|
||||
|
|
||||
public get selecedKeys(): string[] { |
|
||||
return this.contactGroup.value.selecedKeys |
|
||||
} |
|
||||
|
|
||||
public get expandedKeys(): string[] { |
|
||||
return this.contactGroup.value.expandedKeys |
|
||||
} |
|
||||
|
|
||||
initState(treeData: NzTreeNodeOptions[]) { |
|
||||
if (treeData.length === 0) { |
|
||||
return |
|
||||
} |
|
||||
let selecedKeys = this.selecedKeys |
|
||||
let expandedKeys = this.expandedKeys |
|
||||
const flatData: NzTreeNodeOptions[] = Utils.treeToFlatList(treeData) |
|
||||
if (!flatData.some((s) => selecedKeys.includes(s.key))) { |
|
||||
selecedKeys = [] |
|
||||
} |
|
||||
if (selecedKeys.length === 0) { |
|
||||
selecedKeys = [treeData[0].key] as string[] |
|
||||
} else { |
|
||||
expandedKeys = this.setExpandedKeysBySelecedKeys(treeData, selecedKeys) |
|
||||
} |
|
||||
this.contactGroup.update(() => { |
|
||||
return { |
|
||||
expandedKeys: [...new Set(expandedKeys)], |
|
||||
selecedKeys, |
|
||||
} |
|
||||
}) |
|
||||
} |
|
||||
|
|
||||
setExpandedKeysBySelecedKeys(flatData: NzTreeNodeOptions[], selecedKeys: string[]) { |
|
||||
const res: string[] = [] |
|
||||
|
|
||||
let parentId = flatData.find((f) => selecedKeys.includes(f.key))?.['parentId'] |
|
||||
while (parentId) { |
|
||||
res.push(parentId) |
|
||||
parentId = flatData.find((f) => f.key === parentId)?.['parentId'] |
|
||||
} |
|
||||
return this.expandedKeys.concat(res) |
|
||||
} |
|
||||
} |
|
@ -1,83 +0,0 @@ |
|||||
<nz-card [nzBordered]="false"> |
|
||||
<form nz-form class="w-[800px]" [formGroup]="formGroup" (ngSubmit)="onSubmit()"> |
|
||||
<nz-form-item> |
|
||||
<nz-form-label nzRequired nzSpan="4"> 角色名称 </nz-form-label> |
|
||||
<nz-form-control> |
|
||||
<input nz-input placeholder="请输入角色名称" formControlName="roleName" /> |
|
||||
</nz-form-control> |
|
||||
</nz-form-item> |
|
||||
|
|
||||
<nz-form-item> |
|
||||
<nz-form-label nzRequired nzSpan="4"> 权限 </nz-form-label> |
|
||||
<nz-form-control> |
|
||||
<nz-spin [nzSpinning]="permissionsLoading"> |
|
||||
<div class="bordered min-h-[20px]"> |
|
||||
<ul class="permissions"> |
|
||||
@for (p of permissions; track $index) { |
|
||||
<li> |
|
||||
<div |
|
||||
nz-checkbox |
|
||||
[nzChecked]="checked.has(p.id)" |
|
||||
(nzCheckedChange)="onPermissionChange($event, p.id)" |
|
||||
[nzValue]="p.id" |
|
||||
> |
|
||||
{{ p.name }} |
|
||||
</div> |
|
||||
</li> |
|
||||
} |
|
||||
</ul> |
|
||||
<!-- <nz-collapse nzGhost> |
|
||||
@for (item of permissions; track $index) { |
|
||||
<nz-collapse-panel [nzHeader]="item.name" [nzExtra]="nzExtraTpl"> |
|
||||
<ng-template #nzExtraTpl> |
|
||||
<label |
|
||||
nz-checkbox |
|
||||
[nzIndeterminate]="checkedAll.get(item.id)?.nzIndeterminate" |
|
||||
[nzChecked]="checkedAll.get(item.id)?.nzChecked" |
|
||||
(click)="$event.stopPropagation()" |
|
||||
(nzCheckedChange)="checkAllChange($event, item)" |
|
||||
> |
|
||||
全选 |
|
||||
</label> |
|
||||
</ng-template> |
|
||||
<div nz-row [nzGutter]="[12, 12]"> |
|
||||
@for (p of item.children; track $index) { |
|
||||
<div nz-col nzSpan="8"> |
|
||||
<label |
|
||||
nz-checkbox |
|
||||
[nzChecked]="checked.has(p.id)" |
|
||||
[nzValue]="p.id" |
|
||||
(nzCheckedChange)="onPermissionChange($event, p.id, item)" |
|
||||
> |
|
||||
{{ p.name }} |
|
||||
</label> |
|
||||
</div> |
|
||||
} @empty { |
|
||||
<div nz-col nzSpan="24"> |
|
||||
<nz-empty></nz-empty> |
|
||||
</div> |
|
||||
} |
|
||||
</div> |
|
||||
</nz-collapse-panel> |
|
||||
} |
|
||||
</nz-collapse> --> |
|
||||
</div> |
|
||||
</nz-spin> |
|
||||
</nz-form-control> |
|
||||
</nz-form-item> |
|
||||
<nz-form-item> |
|
||||
<nz-form-label nzSpan="4"> 说明 </nz-form-label> |
|
||||
<nz-form-control> |
|
||||
<textarea nz-input formControlName="remark" placeholder="请输入说明"></textarea> |
|
||||
</nz-form-control> |
|
||||
</nz-form-item> |
|
||||
<nz-form-item> |
|
||||
<nz-form-control nzOffset="4"> |
|
||||
<nz-space> |
|
||||
<button nz-button nzType="primary" *nzSpaceItem>保存</button> |
|
||||
<button nz-button *nzSpaceItem [routerLink]="['/', 'role']">取消</button> |
|
||||
</nz-space> |
|
||||
</nz-form-control> |
|
||||
</nz-form-item> |
|
||||
</form> |
|
||||
</nz-card> |
|
@ -1,11 +0,0 @@ |
|||||
.permissions { |
|
||||
li { |
|
||||
display: flex; |
|
||||
padding: 8px 24px; |
|
||||
|
|
||||
&:not(:last-child) { |
|
||||
|
|
||||
border-bottom: 1px solid var(--border-color); |
|
||||
} |
|
||||
} |
|
||||
} |
|
@ -1,146 +0,0 @@ |
|||||
import { finalize } from 'rxjs' |
|
||||
import { Component, OnInit } from '@angular/core' |
|
||||
import { FormControl, FormGroup } from '@angular/forms' |
|
||||
import { ActivatedRoute, Router } from '@angular/router' |
|
||||
import { ApiService } from 'app/services' |
|
||||
import { PermissionDTO } from 'app/services/api.dto' |
|
||||
import { SharedModule } from 'app/shared/shared.module' |
|
||||
import { FormValidators } from 'app/utils' |
|
||||
import { NzMessageService } from 'ng-zorro-antd/message' |
|
||||
|
|
||||
@Component({ |
|
||||
selector: 'app-role-form', |
|
||||
standalone: true, |
|
||||
imports: [SharedModule], |
|
||||
templateUrl: './role-form.component.html', |
|
||||
styleUrl: './role-form.component.less', |
|
||||
}) |
|
||||
export class RoleFormComponent implements OnInit { |
|
||||
constructor( |
|
||||
private api: ApiService, |
|
||||
private msg: NzMessageService, |
|
||||
private route: ActivatedRoute, |
|
||||
private router: Router, |
|
||||
// private modal: NzModalService,
|
|
||||
) {} |
|
||||
|
|
||||
id: string | null = null |
|
||||
|
|
||||
permissions: PermissionDTO[] = [] |
|
||||
|
|
||||
formGroup = new FormGroup({ |
|
||||
roleName: new FormControl('', [FormValidators.required('请输入角色名称'), FormValidators.maxLength(30)]), |
|
||||
remark: new FormControl('', [FormValidators.maxLength(30)]), |
|
||||
}) |
|
||||
|
|
||||
checkedAll = new Map<string, { nzIndeterminate: boolean; nzChecked: boolean }>() |
|
||||
|
|
||||
checked = new Set<string>() |
|
||||
|
|
||||
permissionsLoading = false |
|
||||
|
|
||||
ngOnInit(): void { |
|
||||
this.getPermissions() |
|
||||
const id = this.route.snapshot.paramMap.get('id') |
|
||||
if (id && id !== 'create') { |
|
||||
this.id = id |
|
||||
this.getRoleInfo() |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
getPermissions() { |
|
||||
this.permissionsLoading = true |
|
||||
this.api |
|
||||
.getAllPermission() |
|
||||
.pipe( |
|
||||
finalize(() => { |
|
||||
this.permissionsLoading = false |
|
||||
}), |
|
||||
) |
|
||||
.subscribe((res) => { |
|
||||
this.permissions = res.data |
|
||||
this.updateCheckedAll() |
|
||||
}) |
|
||||
} |
|
||||
|
|
||||
getRoleInfo() { |
|
||||
this.api.getRoleById(this.id!).subscribe((res) => { |
|
||||
this.formGroup.patchValue(res.data) |
|
||||
this.checked = new Set(res.data.authorityId) |
|
||||
this.updateCheckedAll() |
|
||||
}) |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 权限之间的联动 |
|
||||
*/ |
|
||||
roleLinkage = new Map<string, string[]>([ |
|
||||
// ['2', ['2', '9', '15']],
|
|
||||
// ['9', ['2', '9', '15']],
|
|
||||
// ['15', ['2', '9', '15']],
|
|
||||
// ['20', ['20', '25']],
|
|
||||
// ['25', ['20', '25']],
|
|
||||
]) |
|
||||
|
|
||||
onPermissionChange(checked: boolean, id: string) { |
|
||||
const checkedIds = this.roleLinkage.get(id) ?? [id] |
|
||||
checkedIds.forEach((i) => { |
|
||||
if (checked) { |
|
||||
this.checked.add(i) |
|
||||
} else { |
|
||||
this.checked.delete(i) |
|
||||
} |
|
||||
}) |
|
||||
this.updateCheckedAll() |
|
||||
} |
|
||||
|
|
||||
checkAllChange(checked: boolean, p: PermissionDTO) { |
|
||||
p.children?.forEach((permission) => { |
|
||||
if (checked) { |
|
||||
this.checked.add(permission.id) |
|
||||
} else { |
|
||||
this.checked.delete(permission.id) |
|
||||
} |
|
||||
}) |
|
||||
this.updateCheckedAll() |
|
||||
} |
|
||||
|
|
||||
updateCheckedAll() { |
|
||||
this.permissions.forEach((g) => { |
|
||||
let nzChecked = true |
|
||||
let nzIndeterminate = false |
|
||||
g.children?.forEach((permission) => { |
|
||||
if (this.checked.has(permission.id)) { |
|
||||
nzIndeterminate = true |
|
||||
} else { |
|
||||
nzChecked = false |
|
||||
} |
|
||||
}) |
|
||||
this.checkedAll.set(g.id, { |
|
||||
nzChecked, |
|
||||
nzIndeterminate: nzChecked ? false : nzIndeterminate, |
|
||||
}) |
|
||||
}) |
|
||||
} |
|
||||
|
|
||||
onSubmit() { |
|
||||
if (FormValidators.validateFormGroup(this.formGroup)) { |
|
||||
if (this.checked.size === 0) { |
|
||||
this.msg.error('请选择权限') |
|
||||
return |
|
||||
} |
|
||||
const { value } = this.formGroup |
|
||||
this.api |
|
||||
.saveRole({ |
|
||||
id: this.id, |
|
||||
roleName: value.roleName!, |
|
||||
remark: value.remark as string, |
|
||||
authorityId: Array.from(this.checked), |
|
||||
}) |
|
||||
.subscribe(() => { |
|
||||
this.msg.success('保存成功') |
|
||||
this.router.navigate(['/role/list']) |
|
||||
}) |
|
||||
} |
|
||||
} |
|
||||
} |
|
@ -1,27 +0,0 @@ |
|||||
<nz-card [nzBordered]="false"> |
|
||||
<app-server-paginated-table [options]="tableOption" [formGroup]="queryForm"> |
|
||||
<div *appTableAction class="flex items-center justify-between"> |
|
||||
<div class="flex-1"> |
|
||||
<nz-space> |
|
||||
<button |
|
||||
nz-button |
|
||||
nzType="primary" |
|
||||
type="button" |
|
||||
[routerLink]="['/', 'role', 'form', 'create']" |
|
||||
*nzSpaceItem |
|
||||
> |
|
||||
添加角色 |
|
||||
</button> |
|
||||
</nz-space> |
|
||||
</div> |
|
||||
<!-- <div> |
|
||||
<nz-input-group nzSearch [nzSuffix]="suffixIconSearch"> |
|
||||
<input type="text" nz-input placeholder="请输入角色名称" formControlName="roleName" /> |
|
||||
</nz-input-group> |
|
||||
<ng-template #suffixIconSearch> |
|
||||
<span nz-icon nzType="search"></span> |
|
||||
</ng-template> |
|
||||
</div> --> |
|
||||
</div> |
|
||||
</app-server-paginated-table> |
|
||||
</nz-card> |
|
@ -1,72 +0,0 @@ |
|||||
import { lastValueFrom } from 'rxjs' |
|
||||
import { Component, OnInit } from '@angular/core' |
|
||||
import { FormControl, FormGroup } from '@angular/forms' |
|
||||
import { Router } from '@angular/router' |
|
||||
import { TableOption } from 'app/components/server-paginated-table' |
|
||||
import { ApiService } from 'app/services' |
|
||||
import { RoleListDTO } from 'app/services/api.dto' |
|
||||
import { SharedModule } from 'app/shared/shared.module' |
|
||||
import { NzModalService } from 'ng-zorro-antd/modal' |
|
||||
import { NzMessageService } from 'ng-zorro-antd/message' |
|
||||
|
|
||||
@Component({ |
|
||||
selector: 'app-role-list', |
|
||||
standalone: true, |
|
||||
imports: [SharedModule], |
|
||||
templateUrl: './role-list.component.html', |
|
||||
styleUrl: './role-list.component.less', |
|
||||
}) |
|
||||
export class RoleListComponent implements OnInit { |
|
||||
constructor( |
|
||||
private api: ApiService, |
|
||||
private modal: NzModalService, |
|
||||
private router: Router, |
|
||||
private msg: NzMessageService, |
|
||||
) {} |
|
||||
|
|
||||
tableOption = new TableOption(this.fetchData.bind(this)) |
|
||||
|
|
||||
queryForm = new FormGroup({ |
|
||||
roleName: new FormControl(), |
|
||||
}) |
|
||||
|
|
||||
permissions = [] |
|
||||
|
|
||||
ngOnInit(): void { |
|
||||
this.initTable() |
|
||||
} |
|
||||
|
|
||||
initTable() { |
|
||||
this.tableOption |
|
||||
.setColumn([ |
|
||||
{ key: 'roleName', title: '角色名称' }, |
|
||||
{ key: 'remark', title: '说明' }, |
|
||||
{ key: 'createTime', title: '创建时间' }, |
|
||||
]) |
|
||||
.setRowOperate([ |
|
||||
{ title: '编辑', onClick: this.edit.bind(this), visible: (v) => v.id !== '1' }, |
|
||||
{ title: '删除', onClick: this.deleteItem.bind(this), visible: (v) => v.id !== '1' }, |
|
||||
]) |
|
||||
} |
|
||||
|
|
||||
fetchData(p: {}, q: {}) { |
|
||||
return this.api.getRolePage(p, q) |
|
||||
} |
|
||||
|
|
||||
edit(role: RoleListDTO) { |
|
||||
this.router.navigate(['/', 'role', 'form', role.id]) |
|
||||
} |
|
||||
|
|
||||
deleteItem(role: RoleListDTO) { |
|
||||
this.modal.confirm({ |
|
||||
nzTitle: '警告', |
|
||||
nzContent: '是否要删除该角色?', |
|
||||
nzOkDanger: true, |
|
||||
nzOnOk: async () => { |
|
||||
await lastValueFrom(this.api.deleteRole(role.id)) |
|
||||
this.msg.success('删除成功') |
|
||||
this.tableOption.ref?.reload() |
|
||||
}, |
|
||||
}) |
|
||||
} |
|
||||
} |
|
@ -1,63 +0,0 @@ |
|||||
<div nz-row nzGutter="12"> |
|
||||
<div nz-col nzSpan="6"> |
|
||||
<nz-card [nzBordered]="false"> |
|
||||
<div> |
|
||||
<nz-statistic [nzValue]="counter.totalClient" [nzTitle]="'今日预约'"></nz-statistic> |
|
||||
</div> |
|
||||
</nz-card> |
|
||||
</div> |
|
||||
<div nz-col nzSpan="18"> |
|
||||
<nz-card [nzBordered]="false"> |
|
||||
<div nz-row nzGutter="24"> |
|
||||
<div nz-col nzSpan="8"> |
|
||||
<nz-statistic [nzValue]="counter.totalClient" [nzTitle]="'会员'"></nz-statistic> |
|
||||
</div> |
|
||||
<div nz-col nzSpan="8"> |
|
||||
<nz-statistic [nzValue]="counter.totalProduct" [nzTitle]="'会员卡'"></nz-statistic> |
|
||||
</div> |
|
||||
<div nz-col nzSpan="8"> |
|
||||
<nz-statistic [nzValue]="counter.totalLicense" [nzTitle]="'教练'"></nz-statistic> |
|
||||
</div> |
|
||||
</div> |
|
||||
</nz-card> |
|
||||
</div> |
|
||||
</div> |
|
||||
|
|
||||
<div class="mt-4"> |
|
||||
<nz-card [nzBordered]="false" nzTitle="近30天办卡"> |
|
||||
<div class="h-80" #chart1Tpl></div> |
|
||||
</nz-card> |
|
||||
</div> |
|
||||
|
|
||||
<div class="mt-4 mb-4"> |
|
||||
<nz-card [nzBordered]="false" nzTitle="近30天到期会员"> |
|
||||
<nz-table nzTemplateMode nzSize="small" [nzBordered]="true"> |
|
||||
<thead> |
|
||||
<tr> |
|
||||
<th>实体</th> |
|
||||
<th>产品</th> |
|
||||
<!-- <th>版本</th> --> |
|
||||
<th>到期时间</th> |
|
||||
</tr> |
|
||||
</thead> |
|
||||
<tbody> |
|
||||
@for (p of expiringSoon; track $index) { |
|
||||
<tr> |
|
||||
<td>{{ p.clientName }}</td> |
|
||||
<td>{{ p.productName }}</td> |
|
||||
<!-- <td></td> --> |
|
||||
<td> |
|
||||
{{ p.endTime * 1000 | date: 'yyyy-MM-dd HH:mm:ss' }} |
|
||||
</td> |
|
||||
</tr> |
|
||||
} @empty { |
|
||||
<tr> |
|
||||
<td [colSpan]="4"> |
|
||||
<nz-empty nzNotFoundContent="没有近30天到期的授权"></nz-empty> |
|
||||
</td> |
|
||||
</tr> |
|
||||
} |
|
||||
</tbody> |
|
||||
</nz-table> |
|
||||
</nz-card> |
|
||||
</div> |
|
@ -1,195 +0,0 @@ |
|||||
import { AfterViewInit, Component, ElementRef, HostListener, OnInit, ViewChild } from '@angular/core' |
|
||||
import { init, EChartsType } from 'echarts' |
|
||||
import { SharedModule } from '../../shared/shared.module' |
|
||||
import { ApiService } from 'app/services' |
|
||||
import { ConsoleClientTopDTO, ConsoleCountDTO, ConsoleExpireDTO } from 'app/services/api.dto' |
|
||||
|
|
||||
const antvColor = [ |
|
||||
'#5B8FF9', |
|
||||
'#61DDAA', |
|
||||
'#65789B', |
|
||||
'#F6BD16', |
|
||||
'#7262FD', |
|
||||
'#78D3F8', |
|
||||
'#9661BC', |
|
||||
'#F6903D', |
|
||||
'#008685', |
|
||||
'#F08BB4', |
|
||||
] |
|
||||
|
|
||||
@Component({ |
|
||||
standalone: true, |
|
||||
imports: [SharedModule], |
|
||||
selector: 'app-dashboard', |
|
||||
templateUrl: './dashboard.component.html', |
|
||||
styleUrls: ['./dashboard.component.less'], |
|
||||
}) |
|
||||
export class DashboardComponent implements OnInit, AfterViewInit { |
|
||||
constructor(private api: ApiService) {} |
|
||||
|
|
||||
@ViewChild('chart1Tpl') chart1!: ElementRef<HTMLDivElement> |
|
||||
|
|
||||
@ViewChild('chart2Tpl') chart2!: ElementRef<HTMLDivElement> |
|
||||
|
|
||||
echartRef1?: EChartsType |
|
||||
|
|
||||
echartRef2?: EChartsType |
|
||||
|
|
||||
counter: ConsoleCountDTO = { totalClient: 0, totalLicense: 0, totalProduct: 0 } |
|
||||
|
|
||||
expiringSoon: ConsoleExpireDTO[] = [] |
|
||||
|
|
||||
clientTopTen: ConsoleClientTopDTO[] = [] |
|
||||
|
|
||||
@HostListener('window:resize') |
|
||||
onResize() { |
|
||||
// this.echartRef1?.resize();
|
|
||||
this.echartRef2?.resize() |
|
||||
} |
|
||||
|
|
||||
ngOnInit(): void { |
|
||||
// this.api.getDashboardCounter().subscribe((res) => {
|
|
||||
// this.counter = res.data
|
|
||||
// })
|
|
||||
// this.api.getDashboardExpire().subscribe((res) => {
|
|
||||
// this.expiringSoon = res.data
|
|
||||
// })
|
|
||||
// this.api.getDashboardClientTop().subscribe((res) => {
|
|
||||
// this.clientTopTen = res.data
|
|
||||
// this.initChart2()
|
|
||||
// })
|
|
||||
} |
|
||||
|
|
||||
ngAfterViewInit(): void { |
|
||||
// this.initChart1();
|
|
||||
} |
|
||||
|
|
||||
initChart1() { |
|
||||
const el = this.chart1.nativeElement |
|
||||
if (el) { |
|
||||
this.echartRef1 = init(el) |
|
||||
this.echartRef1.setOption({ |
|
||||
color: antvColor, |
|
||||
tooltip: { |
|
||||
trigger: 'axis', |
|
||||
axisPointer: { |
|
||||
type: 'cross', |
|
||||
label: { |
|
||||
backgroundColor: '#6a7985', |
|
||||
}, |
|
||||
}, |
|
||||
}, |
|
||||
legend: { |
|
||||
data: ['晶未智慧安全平台', 'NG-WAF', 'DLP', 'API'], |
|
||||
}, |
|
||||
|
|
||||
grid: { |
|
||||
left: '10px', |
|
||||
right: '10px', |
|
||||
bottom: '3%', |
|
||||
containLabel: true, |
|
||||
}, |
|
||||
xAxis: [ |
|
||||
{ |
|
||||
type: 'category', |
|
||||
boundaryGap: false, |
|
||||
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], |
|
||||
}, |
|
||||
], |
|
||||
yAxis: [ |
|
||||
{ |
|
||||
type: 'value', |
|
||||
}, |
|
||||
], |
|
||||
series: [ |
|
||||
{ |
|
||||
name: '晶未智慧安全平台', |
|
||||
type: 'line', |
|
||||
smooth: true, |
|
||||
areaStyle: { |
|
||||
opacity: 0.2, |
|
||||
}, |
|
||||
emphasis: { |
|
||||
focus: 'series', |
|
||||
}, |
|
||||
data: [620, 332, 401, 534, 190, 330, 410], |
|
||||
}, |
|
||||
{ |
|
||||
name: 'NG-WAF', |
|
||||
type: 'line', |
|
||||
smooth: true, |
|
||||
areaStyle: { |
|
||||
opacity: 0.2, |
|
||||
}, |
|
||||
emphasis: { |
|
||||
focus: 'series', |
|
||||
}, |
|
||||
data: [220, 182, 191, 234, 290, 330, 310], |
|
||||
}, |
|
||||
{ |
|
||||
name: 'API', |
|
||||
type: 'line', |
|
||||
smooth: true, |
|
||||
areaStyle: { |
|
||||
opacity: 0.2, |
|
||||
}, |
|
||||
emphasis: { |
|
||||
focus: 'series', |
|
||||
}, |
|
||||
data: [55, 612, 491, 34, 90, 200, 411], |
|
||||
}, |
|
||||
{ |
|
||||
name: 'DLP', |
|
||||
type: 'line', |
|
||||
smooth: true, |
|
||||
areaStyle: { |
|
||||
opacity: 0.2, |
|
||||
}, |
|
||||
emphasis: { |
|
||||
focus: 'series', |
|
||||
}, |
|
||||
data: [20, 162, 291, 134, 390, 300, 10], |
|
||||
}, |
|
||||
], |
|
||||
}) |
|
||||
} |
|
||||
} |
|
||||
initChart2() { |
|
||||
const el = this.chart2.nativeElement |
|
||||
if (el) { |
|
||||
this.echartRef2 = init(el) |
|
||||
this.echartRef2.setOption({ |
|
||||
color: antvColor, |
|
||||
tooltip: { |
|
||||
trigger: 'axis', |
|
||||
axisPointer: { |
|
||||
type: 'cross', |
|
||||
label: { |
|
||||
backgroundColor: '#6a7985', |
|
||||
}, |
|
||||
}, |
|
||||
}, |
|
||||
|
|
||||
grid: { |
|
||||
left: '10px', |
|
||||
right: '10px', |
|
||||
bottom: '3%', |
|
||||
containLabel: true, |
|
||||
}, |
|
||||
xAxis: { |
|
||||
type: 'category', |
|
||||
data: this.clientTopTen.map((i) => i.clientName), |
|
||||
}, |
|
||||
yAxis: { |
|
||||
type: 'value', |
|
||||
}, |
|
||||
series: [ |
|
||||
{ |
|
||||
data: this.clientTopTen.map((i) => i.count), |
|
||||
type: 'bar', |
|
||||
}, |
|
||||
], |
|
||||
}) |
|
||||
} |
|
||||
} |
|
||||
} |
|
@ -1,101 +0,0 @@ |
|||||
@if (entity) { |
|
||||
<div class="mb-4"> |
|
||||
<nz-card [nzBordered]="false" nzTitle="实体详情" [nzExtra]="nzExtraTpl"> |
|
||||
<ng-template #nzExtraTpl> |
|
||||
<nz-space> |
|
||||
<button *nzSpaceItem nz-button [routerLink]="['/', 'entity']">返回</button> |
|
||||
</nz-space> |
|
||||
</ng-template> |
|
||||
|
|
||||
<nz-descriptions [nzColumn]="3" class="ml-16"> |
|
||||
<nz-descriptions-item nzTitle="实体名称"> |
|
||||
{{ entity.name }} |
|
||||
</nz-descriptions-item> |
|
||||
<nz-descriptions-item nzTitle="联系方式"> |
|
||||
{{ entity.contact ?? '-' }} |
|
||||
</nz-descriptions-item> |
|
||||
<!-- <nz-descriptions-item nzTitle="地址"> |
|
||||
{{ entity.address ?? '-' }} |
|
||||
</nz-descriptions-item> --> |
|
||||
<nz-descriptions-item nzTitle="说明">{{ entity.remark || '-' }}</nz-descriptions-item> |
|
||||
</nz-descriptions> |
|
||||
</nz-card> |
|
||||
</div> |
|
||||
} |
|
||||
|
|
||||
<div class="mb-4"> |
|
||||
<nz-card [nzBordered]="false" nzTitle="授权记录" [nzExtra]="licenseExtraTpl"> |
|
||||
<ng-template #licenseExtraTpl> |
|
||||
<nz-space> |
|
||||
<button *nzSpaceItem nz-button nzType="primary" (click)="authorize()">新增授权</button> |
|
||||
</nz-space> |
|
||||
</ng-template> |
|
||||
<div> |
|
||||
<div class="mb-3"> |
|
||||
<nz-space nzAlign="center"> |
|
||||
<div *nzSpaceItem>状态:</div> |
|
||||
<div *nzSpaceItem> |
|
||||
<nz-select |
|
||||
nzPlaceHolder="请选择状态" |
|
||||
class="w-64" |
|
||||
[(ngModel)]="status" |
|
||||
(ngModelChange)="onStatusChange()" |
|
||||
> |
|
||||
<nz-option [nzValue]="-1" nzLabel="全部"></nz-option> |
|
||||
<nz-option [nzValue]="0" nzLabel="无效"></nz-option> |
|
||||
<nz-option [nzValue]="1" nzLabel="生效中"></nz-option> |
|
||||
</nz-select> |
|
||||
</div> |
|
||||
</nz-space> |
|
||||
</div> |
|
||||
<nz-table #table [nzData]="visibleList" [nzShowPagination]="false"> |
|
||||
<thead> |
|
||||
<tr> |
|
||||
<th>授权产品</th> |
|
||||
<th>操作人</th> |
|
||||
<th>生效时间</th> |
|
||||
<th>失效时间</th> |
|
||||
<th>状态</th> |
|
||||
<th>创建时间</th> |
|
||||
<th>操作</th> |
|
||||
</tr> |
|
||||
</thead> |
|
||||
<tbody> |
|
||||
@for (item of table.data; track $index) { |
|
||||
<tr> |
|
||||
<td> |
|
||||
{{ item.productName }} |
|
||||
</td> |
|
||||
<td> |
|
||||
{{ item.username }} |
|
||||
</td> |
|
||||
<td> |
|
||||
{{ item.startTime * 1000 | date: 'yyyy-MM-dd HH:mm:ss' }} |
|
||||
</td> |
|
||||
<td> |
|
||||
{{ item.endTime ? (item.endTime * 1000 | date: 'yyyy-MM-dd HH:mm:ss') : '永久' }} |
|
||||
</td> |
|
||||
<td> |
|
||||
@if (item.status) { |
|
||||
<nz-badge nzStatus="processing" nzText="生效中"> </nz-badge> |
|
||||
} @else { |
|
||||
<nz-badge nzStatus="default" nzText="无效"></nz-badge> |
|
||||
} |
|
||||
</td> |
|
||||
<td> |
|
||||
{{ item.createTime }} |
|
||||
</td> |
|
||||
<td> |
|
||||
<nz-space> |
|
||||
<button *nzSpaceItem nz-button nzType="link" (click)="copy(item.license)"> |
|
||||
复制授权码 |
|
||||
</button> |
|
||||
</nz-space> |
|
||||
</td> |
|
||||
</tr> |
|
||||
} |
|
||||
</tbody> |
|
||||
</nz-table> |
|
||||
</div> |
|
||||
</nz-card> |
|
||||
</div> |
|
@ -1,105 +0,0 @@ |
|||||
import { Component, OnInit } from '@angular/core' |
|
||||
import { ActivatedRoute } from '@angular/router' |
|
||||
import { ApiService } from 'app/services' |
|
||||
import { AuthorizeItemDTO, EntityDTO, EntityDetailDTO } from 'app/services/api.dto' |
|
||||
import { SharedModule } from 'app/shared/shared.module' |
|
||||
import { Clipboard } from '@angular/cdk/clipboard' |
|
||||
import { NzMessageService } from 'ng-zorro-antd/message' |
|
||||
import { NzModalService } from 'ng-zorro-antd/modal' |
|
||||
import { AuthorizeComponent } from 'app/components/authorize/authorize.component' |
|
||||
|
|
||||
@Component({ |
|
||||
selector: 'app-entity-detail', |
|
||||
standalone: true, |
|
||||
imports: [SharedModule], |
|
||||
templateUrl: './entity-detail.component.html', |
|
||||
styleUrl: './entity-detail.component.less', |
|
||||
}) |
|
||||
export class EntityDetailComponent implements OnInit { |
|
||||
constructor( |
|
||||
private api: ApiService, |
|
||||
private route: ActivatedRoute, |
|
||||
private clipboard: Clipboard, |
|
||||
private msg: NzMessageService, |
|
||||
private modal: NzModalService, |
|
||||
) {} |
|
||||
|
|
||||
entity?: EntityDetailDTO |
|
||||
|
|
||||
authorizeData: AuthorizeItemDTO[] = [] |
|
||||
|
|
||||
visibleList: AuthorizeItemDTO[] = [] |
|
||||
|
|
||||
product: { id: string; name: string }[] = [] |
|
||||
|
|
||||
id: string = '' |
|
||||
|
|
||||
status = -1 |
|
||||
|
|
||||
ngOnInit(): void { |
|
||||
const id = this.route.snapshot.paramMap.get('id') |
|
||||
if (id) { |
|
||||
this.id = id |
|
||||
this.api.getEntityDetail(id).subscribe((res) => { |
|
||||
this.entity = res.data |
|
||||
}) |
|
||||
this.getEntityAuthorizeList() |
|
||||
} |
|
||||
this.api.getAllProduct().subscribe((res) => { |
|
||||
this.product = res.data |
|
||||
}) |
|
||||
} |
|
||||
|
|
||||
getEntityAuthorizeList() { |
|
||||
this.api.getEntityAuthorizeList(this.id).subscribe((res) => { |
|
||||
this.authorizeData = res.data.map((i) => ({ |
|
||||
...i, |
|
||||
status: this.between(i.startTime, i.endTime) ? 1 : 0, |
|
||||
})) |
|
||||
this.onStatusChange() |
|
||||
}) |
|
||||
} |
|
||||
|
|
||||
onStatusChange() { |
|
||||
this.visibleList = this.authorizeData.filter((f) => (this.status === -1 ? true : f.status === this.status)) |
|
||||
} |
|
||||
|
|
||||
copy(license: string) { |
|
||||
const pending = this.clipboard.beginCopy(license) |
|
||||
let remainingAttempts = 3 |
|
||||
const attempt = () => { |
|
||||
const result = pending.copy() |
|
||||
if (!result && --remainingAttempts) { |
|
||||
setTimeout(attempt) |
|
||||
} else { |
|
||||
this.msg.success('复制成功') |
|
||||
pending.destroy() |
|
||||
} |
|
||||
} |
|
||||
attempt() |
|
||||
} |
|
||||
|
|
||||
between(start: number, end: number): boolean { |
|
||||
if (end === 0) { |
|
||||
return true |
|
||||
} |
|
||||
const now = Date.now() |
|
||||
return start * 1000 <= now && now <= end * 1000 |
|
||||
} |
|
||||
|
|
||||
authorize() { |
|
||||
const ref = this.modal.create({ |
|
||||
nzTitle: '添加授权', |
|
||||
nzContent: AuthorizeComponent, |
|
||||
nzWidth: 800, |
|
||||
nzData: { |
|
||||
product: this.product, |
|
||||
entity: this.entity, |
|
||||
}, |
|
||||
nzFooter: null, |
|
||||
}) |
|
||||
ref.afterClose.subscribe(() => { |
|
||||
this.getEntityAuthorizeList() |
|
||||
}) |
|
||||
} |
|
||||
} |
|
@ -1,83 +0,0 @@ |
|||||
<nz-card [nzBordered]="false"> |
|
||||
<app-server-paginated-table |
|
||||
#tableTpl |
|
||||
[renderColumn]="renderColumnsTpl" |
|
||||
[formGroup]="queryForm" |
|
||||
[simpleSearch]="true" |
|
||||
[options]="table" |
|
||||
> |
|
||||
<ng-template #renderColumnsTpl let-data let-key="key" let-row="row"> |
|
||||
@switch (key) { |
|
||||
@case ('name') { |
|
||||
<a [routerLink]="['/', 'entity', row.id, 'detail']">{{ data }}</a> |
|
||||
} |
|
||||
@default { |
|
||||
{{ data }} |
|
||||
} |
|
||||
} |
|
||||
</ng-template> |
|
||||
|
|
||||
<div *appTableForm nz-row [nzGutter]="[24, 24]"> |
|
||||
<div nz-col nzSpan="8"> |
|
||||
<nz-form-item> |
|
||||
<nz-form-label nzFlex="80px"> 实体名称 </nz-form-label> |
|
||||
<nz-form-control nzSpan="18"> |
|
||||
<input nz-input placeholder="请输入实体名称" formControlName="name" /> |
|
||||
</nz-form-control> |
|
||||
</nz-form-item> |
|
||||
</div> |
|
||||
<div nz-col nzSpan="12"> |
|
||||
<nz-form-item> |
|
||||
<nz-form-label nzFlex="80px"> 创建时间 </nz-form-label> |
|
||||
<nz-form-control nzSpan="18"> |
|
||||
<!-- <nz-range-picker nzShowTime formControlName="createTime"></nz-range-picker> --> |
|
||||
<app-range-picker [showTime]="true" formControlName="createTime"></app-range-picker> |
|
||||
</nz-form-control> |
|
||||
</nz-form-item> |
|
||||
</div> |
|
||||
</div> |
|
||||
<div *appTableAction class="flex"> |
|
||||
<div> |
|
||||
<nz-space> |
|
||||
<button *nzSpaceItem nzType="primary" nz-button (click)="create()">添加实体</button> |
|
||||
</nz-space> |
|
||||
</div> |
|
||||
</div> |
|
||||
|
|
||||
<!-- <div action>Custom Modal action</div> --> |
|
||||
</app-server-paginated-table> |
|
||||
</nz-card> |
|
||||
|
|
||||
<ng-template #entityFormTpl> |
|
||||
<form [formGroup]="createForm" nz-form [nzLayout]="'vertical'"> |
|
||||
<nz-form-item> |
|
||||
<nz-form-label nzRequired> 实体名称 </nz-form-label> |
|
||||
<nz-form-control [nzErrorTip]="formErrorTipsTpl"> |
|
||||
<input nz-input placeholder="请输入实体名称" formControlName="name" /> |
|
||||
</nz-form-control> |
|
||||
</nz-form-item> |
|
||||
|
|
||||
<nz-form-item> |
|
||||
<nz-form-label> 联系方式 </nz-form-label> |
|
||||
<nz-form-control [nzErrorTip]="formErrorTipsTpl"> |
|
||||
<input nz-input placeholder="请输入联系方式" formControlName="contact" /> |
|
||||
</nz-form-control> |
|
||||
</nz-form-item> |
|
||||
<!-- <nz-form-item> |
|
||||
<nz-form-label> 地址 </nz-form-label> |
|
||||
<nz-form-control [nzErrorTip]="formErrorTipsTpl"> |
|
||||
<input nz-input placeholder="请输入地址" formControlName="address" /> |
|
||||
</nz-form-control> |
|
||||
</nz-form-item> --> |
|
||||
<nz-form-item> |
|
||||
<nz-form-label> 说明 </nz-form-label> |
|
||||
<nz-form-control [nzErrorTip]="formErrorTipsTpl"> |
|
||||
<textarea nz-input placeholder="请输入说明" formControlName="remark"></textarea> |
|
||||
</nz-form-control> |
|
||||
</nz-form-item> |
|
||||
</form> |
|
||||
</ng-template> |
|
||||
|
|
||||
<ng-template #formErrorTipsTpl let-control> |
|
||||
<form-error-tips [control]="control"></form-error-tips> |
|
||||
</ng-template> |
|
@ -1,132 +0,0 @@ |
|||||
import { Component, ElementRef, OnInit, TemplateRef, ViewChild } from '@angular/core' |
|
||||
import { FormControl, FormGroup } from '@angular/forms' |
|
||||
import { NzModalService } from 'ng-zorro-antd/modal' |
|
||||
import { ApiService } from 'app/services' |
|
||||
import { AnyObject, ServerPaginatedTableComponent, TableOption } from 'app/components/server-paginated-table' |
|
||||
import { SharedModule } from 'app/shared/shared.module' |
|
||||
import { FormValidators } from 'app/utils' |
|
||||
import { lastValueFrom } from 'rxjs' |
|
||||
import { EntityDTO, ProductDTO } from 'app/services/api.dto' |
|
||||
import { NzMessageService } from 'ng-zorro-antd/message' |
|
||||
import { format } from 'date-fns' |
|
||||
import { AuthorizeComponent } from 'app/components/authorize/authorize.component' |
|
||||
|
|
||||
@Component({ |
|
||||
standalone: true, |
|
||||
imports: [SharedModule], |
|
||||
selector: 'app-entity-list', |
|
||||
templateUrl: './entity-list.component.html', |
|
||||
styleUrls: ['./entity-list.component.less'], |
|
||||
}) |
|
||||
export class EntityListComponent implements OnInit { |
|
||||
constructor( |
|
||||
private api: ApiService, |
|
||||
private modal: NzModalService, |
|
||||
private msg: NzMessageService, |
|
||||
) {} |
|
||||
|
|
||||
@ViewChild('entityFormTpl') entityFormTpl!: TemplateRef<{}> |
|
||||
|
|
||||
table = new TableOption(this.fetchData.bind(this), [{ key: 'name', title: '实体名称' }], [], { |
|
||||
cacheUrls: ['/dashboard'], |
|
||||
}) |
|
||||
|
|
||||
queryForm = new FormGroup({ |
|
||||
name: new FormControl(''), |
|
||||
createTime: new FormControl(), |
|
||||
}) |
|
||||
|
|
||||
createForm = new FormGroup({ |
|
||||
name: new FormControl('', [FormValidators.required('请输入实体名称'), FormValidators.maxLength(30)]), |
|
||||
// secretKey: new FormControl('', [FormValidators.required('请输入序列号')]),
|
|
||||
contact: new FormControl('', FormValidators.maxLength(30)), |
|
||||
// address: new FormControl('', FormValidators.maxLength(200)),
|
|
||||
remark: new FormControl('', FormValidators.maxLength(200)), |
|
||||
}) |
|
||||
|
|
||||
product: { id: string; name: string }[] = [] |
|
||||
|
|
||||
ngOnInit(): void { |
|
||||
this.table |
|
||||
.setColumn([ |
|
||||
{ key: 'name', title: '实体名称' }, |
|
||||
{ key: 'contact', title: '联系方式' }, |
|
||||
// { key: 'address', title: '地址' },
|
|
||||
{ key: 'remark', title: '说明' }, |
|
||||
{ key: 'createTime', title: '创建时间' }, |
|
||||
]) |
|
||||
.setRowOperate([ |
|
||||
{ title: '添加授权', premissions: [], onClick: this.authorize.bind(this) }, |
|
||||
{ title: '编辑', onClick: this.create.bind(this) }, |
|
||||
{ title: '删除', onClick: this.deleteItem.bind(this) }, |
|
||||
]) |
|
||||
this.api.getAllProduct().subscribe((res) => { |
|
||||
this.product = res.data |
|
||||
}) |
|
||||
} |
|
||||
|
|
||||
fetchData(p: {}, q: AnyObject) { |
|
||||
if (Array.isArray(q['createTime'])) { |
|
||||
const createTimeStart = q['createTime']?.[0] |
|
||||
const createTimeEnd = q['createTime']?.[1] |
|
||||
|
|
||||
q['createTimeStart'] = createTimeStart ? format(new Date(createTimeStart), 'yyyy-MM-dd HH:mm:ss') : '' |
|
||||
q['createTimeEnd'] = createTimeEnd ? format(new Date(createTimeEnd), 'yyyy-MM-dd HH:mm:ss') : '' |
|
||||
} |
|
||||
return this.api.getEntityPage(p, q) |
|
||||
} |
|
||||
|
|
||||
onSearch() {} |
|
||||
|
|
||||
authorize(v: EntityDTO) { |
|
||||
this.modal.create({ |
|
||||
nzTitle: '添加授权', |
|
||||
nzContent: AuthorizeComponent, |
|
||||
nzWidth: 800, |
|
||||
nzData: { |
|
||||
product: this.product, |
|
||||
entity: v, |
|
||||
}, |
|
||||
nzFooter: null, |
|
||||
}) |
|
||||
} |
|
||||
|
|
||||
create(entity?: EntityDTO) { |
|
||||
if (entity) { |
|
||||
this.createForm.patchValue(entity) |
|
||||
this.createForm.get('secretKey')?.disable() |
|
||||
} else { |
|
||||
this.createForm.get('secretKey')?.enable() |
|
||||
} |
|
||||
this.modal.create({ |
|
||||
nzTitle: entity ? '编辑实体' : '添加实体', |
|
||||
nzContent: this.entityFormTpl, |
|
||||
nzOnOk: async () => { |
|
||||
if (FormValidators.validateFormGroup(this.createForm)) { |
|
||||
await lastValueFrom(this.api.saveEntity({ ...(entity ?? {}), ...this.createForm.value })) |
|
||||
this.msg.success('保存成功') |
|
||||
this.table.ref?.reload() |
|
||||
this.createForm.reset() |
|
||||
return true |
|
||||
} |
|
||||
return false |
|
||||
}, |
|
||||
nzOnCancel: () => { |
|
||||
this.createForm.reset() |
|
||||
}, |
|
||||
}) |
|
||||
} |
|
||||
|
|
||||
deleteItem(entity: EntityDTO) { |
|
||||
this.modal.confirm({ |
|
||||
nzTitle: '警告', |
|
||||
nzContent: '是否要删除该实体?', |
|
||||
nzOkDanger: true, |
|
||||
nzOnOk: async () => { |
|
||||
await lastValueFrom(this.api.deleteEntity(entity.id)) |
|
||||
this.msg.success('删除成功') |
|
||||
this.table.ref?.reload() |
|
||||
}, |
|
||||
}) |
|
||||
} |
|
||||
} |
|
@ -1,5 +0,0 @@ |
|||||
<nz-card [nzBordered]="false" class="h-screen"> |
|
||||
<div class="flex items-center justify-center"> |
|
||||
<nz-result nzStatus="403"></nz-result> |
|
||||
</div> |
|
||||
</nz-card> |
|
@ -1,11 +0,0 @@ |
|||||
import { Component } from '@angular/core' |
|
||||
import { SharedModule } from 'app/shared/shared.module' |
|
||||
|
|
||||
@Component({ |
|
||||
selector: 'app-forbidden', |
|
||||
standalone: true, |
|
||||
imports: [SharedModule], |
|
||||
templateUrl: './forbidden.component.html', |
|
||||
styleUrl: './forbidden.component.less', |
|
||||
}) |
|
||||
export class ForbiddenComponent {} |
|
@ -1,82 +0,0 @@ |
|||||
<nz-card [nzBordered]="false"> |
|
||||
<app-server-paginated-table |
|
||||
#tableTpl |
|
||||
[options]="tableOption" |
|
||||
[formGroup]="queryForm" |
|
||||
[simpleSearch]="false" |
|
||||
[renderColumn]="renderColumnsTpl" |
|
||||
> |
|
||||
<ng-template #renderColumnsTpl let-data let-key="key" let-row="row"> |
|
||||
@switch (key) { |
|
||||
@case ('content') { |
|
||||
<span> |
|
||||
@switch (row.operation) { |
|
||||
@case ('insert') { |
|
||||
<nz-tag nzColor="success">新增</nz-tag> |
|
||||
} |
|
||||
@case ('update') { |
|
||||
<nz-tag nzColor="blue">编辑</nz-tag> |
|
||||
} |
|
||||
@case ('delete') { |
|
||||
<nz-tag nzColor="error">删除</nz-tag> |
|
||||
} |
|
||||
@case ('login') { |
|
||||
<nz-tag nzColor="gold">登录</nz-tag> |
|
||||
} |
|
||||
} |
|
||||
</span> |
|
||||
<span> {{ data }} </span> |
|
||||
} |
|
||||
|
|
||||
@default { |
|
||||
{{ data }} |
|
||||
} |
|
||||
} |
|
||||
</ng-template> |
|
||||
<div *appTableForm nz-row [nzGutter]="[24, 24]"> |
|
||||
<div nz-col nzSpan="8"> |
|
||||
<nz-form-item> |
|
||||
<nz-form-label nzSpan="6"> 操作人 </nz-form-label> |
|
||||
<nz-form-control nzSpan="18"> |
|
||||
<input nz-input placeholder="请输入操作人" formControlName="username" /> |
|
||||
</nz-form-control> |
|
||||
</nz-form-item> |
|
||||
</div> |
|
||||
|
|
||||
<div nz-col nzSpan="8"> |
|
||||
<nz-form-item> |
|
||||
<nz-form-label nzSpan="6"> 操作类型 </nz-form-label> |
|
||||
<nz-form-control nzSpan="18"> |
|
||||
<nz-select nzPlaceHolder="请选择操作类型" formControlName="operation" nzAllowClear> |
|
||||
<nz-option [nzValue]="'insert'" [nzLabel]="'新增'"></nz-option> |
|
||||
<nz-option [nzValue]="'update'" [nzLabel]="'编辑'"></nz-option> |
|
||||
<nz-option [nzValue]="'delete'" [nzLabel]="'删除'"></nz-option> |
|
||||
<nz-option [nzValue]="'login'" [nzLabel]="'登录'"></nz-option> |
|
||||
</nz-select> |
|
||||
</nz-form-control> |
|
||||
</nz-form-item> |
|
||||
</div> |
|
||||
|
|
||||
<div nz-col nzSpan="8"> |
|
||||
<nz-form-item> |
|
||||
<nz-form-label nzSpan="6"> 操作内容 </nz-form-label> |
|
||||
<nz-form-control nzSpan="18"> |
|
||||
<input nz-input placeholder="请输入操作内容" formControlName="content" /> |
|
||||
</nz-form-control> |
|
||||
</nz-form-item> |
|
||||
</div> |
|
||||
|
|
||||
<div nz-col nzSpan="8"> |
|
||||
<nz-form-item> |
|
||||
<nz-form-label nzSpan="6"> 创建时间 </nz-form-label> |
|
||||
<nz-form-control nzSpan="18"> |
|
||||
<!-- <nz-range-picker class="w-full" formControlName="createTime"></nz-range-picker> --> |
|
||||
<app-range-picker [showTime]="true" formControlName="createTime"></app-range-picker> |
|
||||
</nz-form-control> |
|
||||
</nz-form-item> |
|
||||
</div> |
|
||||
</div> |
|
||||
</app-server-paginated-table> |
|
||||
</nz-card> |
|
||||
|
|
||||
<ng-template #createTpl> </ng-template> |
|
@ -1,87 +0,0 @@ |
|||||
import { AfterViewInit, Component, ElementRef, OnInit, TemplateRef, ViewChild } from '@angular/core' |
|
||||
import { FormControl, FormGroup } from '@angular/forms' |
|
||||
import { ApiService } from 'app/services/api.service' |
|
||||
import { |
|
||||
AnyObject, |
|
||||
ServerPaginatedTableComponent, |
|
||||
ServerPaginatedTableService, |
|
||||
TableOption, |
|
||||
} from 'app/components/server-paginated-table' |
|
||||
import { SharedModule } from 'app/shared/shared.module' |
|
||||
import { NzModalService } from 'ng-zorro-antd/modal' |
|
||||
import { format } from 'date-fns' |
|
||||
|
|
||||
@Component({ |
|
||||
standalone: true, |
|
||||
imports: [SharedModule], |
|
||||
selector: 'app-log', |
|
||||
templateUrl: './log.component.html', |
|
||||
styleUrls: ['./log.component.less'], |
|
||||
}) |
|
||||
export class LogComponent implements OnInit, AfterViewInit { |
|
||||
constructor( |
|
||||
private api: ApiService, |
|
||||
private modal: NzModalService, |
|
||||
private table: ServerPaginatedTableService, |
|
||||
) {} |
|
||||
|
|
||||
@ViewChild('shadowLineTpl') shadowLineRef!: ElementRef<HTMLCanvasElement> |
|
||||
|
|
||||
tableOption = new TableOption(this.fetchData.bind(this)) |
|
||||
|
|
||||
queryForm = new FormGroup({ |
|
||||
operation: new FormControl(), |
|
||||
username: new FormControl(), |
|
||||
content: new FormControl(), |
|
||||
|
|
||||
createTime: new FormControl(), |
|
||||
}) |
|
||||
|
|
||||
ngOnInit(): void { |
|
||||
// this.table.run();
|
|
||||
this.tableOption.setConfig({ |
|
||||
cacheUrls: ['/dashboard'], |
|
||||
}) |
|
||||
this.tableOption.setColumn([ |
|
||||
{ |
|
||||
key: 'username', |
|
||||
title: '操作人', |
|
||||
}, |
|
||||
{ |
|
||||
key: 'content', |
|
||||
title: '操作内容', |
|
||||
}, |
|
||||
|
|
||||
{ |
|
||||
key: 'createTime', |
|
||||
title: '创建时间', |
|
||||
}, |
|
||||
]) |
|
||||
} |
|
||||
|
|
||||
ngAfterViewInit(): void {} |
|
||||
|
|
||||
fetchData(p: {}, q: AnyObject) { |
|
||||
if (Array.isArray(q['createTime'])) { |
|
||||
const createTimeStart = q['createTime']?.[0] |
|
||||
const createTimeEnd = q['createTime']?.[1] |
|
||||
|
|
||||
q['createTimeStart'] = createTimeStart ? format(new Date(createTimeStart), 'yyyy-MM-dd HH:mm:ss') : '' |
|
||||
q['createTimeEnd'] = createTimeEnd ? format(new Date(createTimeEnd), 'yyyy-MM-dd HH:mm:ss') : '' |
|
||||
} |
|
||||
return this.api.getSysLog(p, q) |
|
||||
} |
|
||||
|
|
||||
create(nzContent: TemplateRef<{}>) { |
|
||||
this.modal.create({ |
|
||||
nzTitle: '添加授权', |
|
||||
nzContent, |
|
||||
nzWidth: 720, |
|
||||
nzOnOk: async () => { |
|
||||
this.tableOption.ref?.reload() |
|
||||
}, |
|
||||
}) |
|
||||
} |
|
||||
|
|
||||
onSearch() {} |
|
||||
} |
|
@ -1,54 +0,0 @@ |
|||||
<div class="flex items-center justify-center fixed inset-0 z-10 login-page"> |
|
||||
<div class="bg fixed inset-0"></div> |
|
||||
<div class="w-[450px] relative z-10 login-form p-8 bg-white rounded-md shadow-2xl"> |
|
||||
<div class="px-4"> |
|
||||
<div class="text-center"> |
|
||||
<h1>Back to sea</h1> |
|
||||
<p class="text-lg mb-6">登录</p> |
|
||||
</div> |
|
||||
<form nz-form [formGroup]="loginForm" class="mt-12"> |
|
||||
<nz-form-item> |
|
||||
<nz-form-control [nzErrorTip]="formErrorTipsTpl"> |
|
||||
<nz-input-group [nzPrefix]="prefixTemplateUser" nzSize="large"> |
|
||||
<input nz-input nzSize="large" placeholder="用户名" formControlName="username" /> |
|
||||
</nz-input-group> |
|
||||
<ng-template #prefixTemplateUser> |
|
||||
<span nz-icon nzType="user"></span> |
|
||||
<nz-divider nzType="vertical"></nz-divider> |
|
||||
</ng-template> |
|
||||
</nz-form-control> |
|
||||
</nz-form-item> |
|
||||
<nz-form-item> |
|
||||
<nz-form-control [nzErrorTip]="formErrorTipsTpl"> |
|
||||
<nz-input-group [nzPrefix]="prefixTemplatePassword" nzSize="large"> |
|
||||
<input nz-input type="password" placeholder="密码" formControlName="password" /> |
|
||||
</nz-input-group> |
|
||||
<ng-template #prefixTemplatePassword> |
|
||||
<span nz-icon nzType="lock"></span> |
|
||||
<nz-divider nzType="vertical"></nz-divider> |
|
||||
</ng-template> |
|
||||
</nz-form-control> |
|
||||
</nz-form-item> |
|
||||
<nz-form-item> |
|
||||
<nz-form-control> |
|
||||
<button |
|
||||
nz-button |
|
||||
nzType="primary" |
|
||||
nzBlock |
|
||||
class="btn" |
|
||||
nzSize="large" |
|
||||
(click)="onLogin()" |
|
||||
[nzLoading]="loading" |
|
||||
> |
|
||||
登录 |
|
||||
</button> |
|
||||
</nz-form-control> |
|
||||
</nz-form-item> |
|
||||
</form> |
|
||||
</div> |
|
||||
</div> |
|
||||
</div> |
|
||||
|
|
||||
<ng-template #formErrorTipsTpl let-control> |
|
||||
<form-error-tips [control]="control"></form-error-tips> |
|
||||
</ng-template> |
|
@ -1,20 +0,0 @@ |
|||||
.login-page { |
|
||||
|
|
||||
|
|
||||
.bg { |
|
||||
background-image: url(/assets/images/login-bg.jpg); |
|
||||
background-repeat: no-repeat; |
|
||||
background-size: cover; |
|
||||
filter: blur(1px); |
|
||||
} |
|
||||
|
|
||||
|
|
||||
|
|
||||
.login-form { |
|
||||
|
|
||||
background-color: #fff; |
|
||||
background-color: rgba(255, 255, 255, .7); |
|
||||
-webkit-backdrop-filter: blur(10px); |
|
||||
backdrop-filter: blur(10px); |
|
||||
} |
|
||||
} |
|
@ -1,54 +0,0 @@ |
|||||
import { Component } from '@angular/core' |
|
||||
import { FormControl, FormGroup } from '@angular/forms' |
|
||||
import { SharedModule } from '../../shared/shared.module' |
|
||||
import { FormValidators } from 'app/utils' |
|
||||
import { ApiService, LocalHttpInterceptorService } from 'app/services' |
|
||||
import { NzMessageService } from 'ng-zorro-antd/message' |
|
||||
import { Router } from '@angular/router' |
|
||||
import { finalize } from 'rxjs' |
|
||||
|
|
||||
@Component({ |
|
||||
standalone: true, |
|
||||
imports: [SharedModule], |
|
||||
selector: 'app-login', |
|
||||
templateUrl: './login.component.html', |
|
||||
styleUrls: ['./login.component.less'], |
|
||||
}) |
|
||||
export class LoginComponent { |
|
||||
constructor( |
|
||||
private api: ApiService, |
|
||||
private msg: NzMessageService, |
|
||||
private local: LocalHttpInterceptorService, |
|
||||
private router: Router, |
|
||||
) {} |
|
||||
|
|
||||
loading = false |
|
||||
|
|
||||
loginForm = new FormGroup({ |
|
||||
username: new FormControl('', [FormValidators.required('请输入用户名')]), |
|
||||
password: new FormControl('', [FormValidators.required('请输入密码')]), |
|
||||
}) |
|
||||
|
|
||||
onLogin() { |
|
||||
if (FormValidators.validateFormGroup(this.loginForm)) { |
|
||||
this.loading = true |
|
||||
this.router.navigate(['/']) |
|
||||
return |
|
||||
this.api |
|
||||
.login(this.loginForm.value) |
|
||||
.pipe( |
|
||||
finalize(() => { |
|
||||
this.loading = false |
|
||||
}), |
|
||||
) |
|
||||
.subscribe((res) => { |
|
||||
this.msg.success('登录成功') |
|
||||
this.local.setAccess({ |
|
||||
access_token: res.data, |
|
||||
}) |
|
||||
localStorage.setItem('add', res.data) |
|
||||
this.router.navigate(['/']) |
|
||||
}) |
|
||||
} |
|
||||
} |
|
||||
} |
|
@ -1,5 +0,0 @@ |
|||||
<nz-card [nzBordered]="false" class="h-screen"> |
|
||||
<div class="flex items-center justify-center"> |
|
||||
<nz-result nzStatus="404" nzTitle="此页面未找到。"></nz-result> |
|
||||
</div> |
|
||||
</nz-card> |
|
@ -1,11 +0,0 @@ |
|||||
import { Component } from '@angular/core' |
|
||||
import { SharedModule } from 'app/shared/shared.module' |
|
||||
|
|
||||
@Component({ |
|
||||
selector: 'app-notfound', |
|
||||
standalone: true, |
|
||||
imports: [SharedModule], |
|
||||
templateUrl: './notfound.component.html', |
|
||||
styleUrl: './notfound.component.less', |
|
||||
}) |
|
||||
export class NotfoundComponent {} |
|
@ -1,43 +0,0 @@ |
|||||
<div> |
|
||||
<nz-card [nzBordered]="false" nzTitle="产品详情" [nzExtra]="nzExtraTpl"> |
|
||||
<ng-template #nzExtraTpl> |
|
||||
<nz-space> |
|
||||
<button *nzSpaceItem nz-button [routerLink]="['/', 'product']">返回</button> |
|
||||
</nz-space> |
|
||||
</ng-template> |
|
||||
|
|
||||
@if (detail(); as info) { |
|
||||
<nz-descriptions [nzColumn]="2" class="ml-16"> |
|
||||
<nz-descriptions-item nzTitle="产品ID"> |
|
||||
{{ info.productId }} |
|
||||
</nz-descriptions-item> |
|
||||
<nz-descriptions-item nzTitle="产品名称"> |
|
||||
{{ info.name }} |
|
||||
</nz-descriptions-item> |
|
||||
|
|
||||
<nz-descriptions-item nzTitle="说明">{{ info.remark || '-' }}</nz-descriptions-item> |
|
||||
</nz-descriptions> |
|
||||
} |
|
||||
</nz-card> |
|
||||
</div> |
|
||||
<!-- <div class="mt-4"> |
|
||||
<nz-card [nzBordered]="false" nzTitle="版本管理" [nzExtra]="versionExtraTpl"> |
|
||||
<ng-template #versionExtraTpl> |
|
||||
<nz-space> |
|
||||
<button *nzSpaceItem nz-button nzType="primary" (click)="createVersion()">添加</button> |
|
||||
</nz-space> |
|
||||
</ng-template> |
|
||||
<app-server-paginated-table [options]="tableOption"></app-server-paginated-table> |
|
||||
</nz-card> |
|
||||
</div> --> |
|
||||
|
|
||||
<ng-template #versionFormTpl> |
|
||||
<form nz-form [formGroup]="formGroup"> |
|
||||
<nz-form-item> |
|
||||
<nz-form-label nzRequired>版本号</nz-form-label> |
|
||||
<nz-form-control> |
|
||||
<input nz-input formControlName="name" placeholder="请输入版本号" /> |
|
||||
</nz-form-control> |
|
||||
</nz-form-item> |
|
||||
</form> |
|
||||
</ng-template> |
|
@ -1,84 +0,0 @@ |
|||||
import { TemplateRef } from '@angular/core' |
|
||||
import { ViewChild } from '@angular/core' |
|
||||
import { Component, OnInit, signal, computed, effect } from '@angular/core' |
|
||||
import { FormControl, FormGroup } from '@angular/forms' |
|
||||
import { ActivatedRoute, Router } from '@angular/router' |
|
||||
import { TableOption } from 'app/components/server-paginated-table' |
|
||||
import { ApiService } from 'app/services' |
|
||||
import { VersionDTO } from 'app/services/api.dto' |
|
||||
import { SharedModule } from 'app/shared/shared.module' |
|
||||
import { FormValidators } from 'app/utils' |
|
||||
import { NzMessageService } from 'ng-zorro-antd/message' |
|
||||
import { NzModalService } from 'ng-zorro-antd/modal' |
|
||||
import { lastValueFrom } from 'rxjs' |
|
||||
|
|
||||
@Component({ |
|
||||
selector: 'app-product-detail', |
|
||||
standalone: true, |
|
||||
imports: [SharedModule], |
|
||||
templateUrl: './product-detail.component.html', |
|
||||
styleUrl: './product-detail.component.less', |
|
||||
}) |
|
||||
export class ProductDetailComponent implements OnInit { |
|
||||
constructor( |
|
||||
private api: ApiService, |
|
||||
private router: Router, |
|
||||
private route: ActivatedRoute, |
|
||||
private modal: NzModalService, |
|
||||
private msg: NzMessageService, |
|
||||
) {} |
|
||||
|
|
||||
@ViewChild('versionFormTpl') versionFormTpl!: TemplateRef<{}> |
|
||||
|
|
||||
tableOption = new TableOption(this.fetchData.bind(this)) |
|
||||
|
|
||||
formGroup = new FormGroup({ |
|
||||
name: new FormControl('', [FormValidators.required('请输入产品版本号')]), |
|
||||
}) |
|
||||
|
|
||||
detail = signal({ |
|
||||
productId: '', |
|
||||
name: '', |
|
||||
remark: '', |
|
||||
}) |
|
||||
|
|
||||
id!: string |
|
||||
|
|
||||
ngOnInit(): void { |
|
||||
this.id = this.route.snapshot.paramMap.get('id')! |
|
||||
this.api.getProductDetail(this.id).subscribe((res) => { |
|
||||
this.detail.set(res.data) |
|
||||
}) |
|
||||
} |
|
||||
|
|
||||
fetchData(p: {}, q: {}) { |
|
||||
return this.api.getProductVersionPage(p, { ...q, productId: this.id }) |
|
||||
} |
|
||||
|
|
||||
createVersion(version?: VersionDTO) { |
|
||||
this.modal.create({ |
|
||||
nzTitle: '添加版本', |
|
||||
nzContent: this.versionFormTpl, |
|
||||
nzOnOk: async () => { |
|
||||
if (FormValidators.validateFormGroup(this.formGroup)) { |
|
||||
await lastValueFrom(this.api.saveVersion({ ...(version ?? {}), ...this.formGroup.value })) |
|
||||
this.msg.success('保存成功') |
|
||||
this.tableOption.ref?.reload() |
|
||||
} |
|
||||
}, |
|
||||
}) |
|
||||
} |
|
||||
|
|
||||
deleteItem(v: VersionDTO) { |
|
||||
this.modal.confirm({ |
|
||||
nzTitle: '警告', |
|
||||
nzContent: '是否要删除该版本?', |
|
||||
nzOkDanger: true, |
|
||||
nzOnOk: async () => { |
|
||||
await lastValueFrom(this.api.deleteVersion(v.id, this.id)) |
|
||||
this.msg.success('删除成功') |
|
||||
this.tableOption.ref?.reload() |
|
||||
}, |
|
||||
}) |
|
||||
} |
|
||||
} |
|
@ -1,80 +0,0 @@ |
|||||
<nz-card [nzBordered]="false"> |
|
||||
<app-server-paginated-table |
|
||||
#tableTpl |
|
||||
[renderColumn]="renderColumnsTpl" |
|
||||
[formGroup]="queryForm" |
|
||||
[simpleSearch]="true" |
|
||||
[options]="table" |
|
||||
> |
|
||||
<ng-template #renderColumnsTpl let-data let-key="key" let-row="row"> |
|
||||
@switch (key) { |
|
||||
@case ('name') { |
|
||||
<a [routerLink]="['/', 'product', row.id, 'detail']"> |
|
||||
{{ data }} |
|
||||
</a> |
|
||||
} |
|
||||
@default { |
|
||||
{{ data }} |
|
||||
} |
|
||||
} |
|
||||
</ng-template> |
|
||||
|
|
||||
<div *appTableForm nz-row [nzGutter]="[24, 24]"> |
|
||||
<div nz-col nzSpan="8"> |
|
||||
<nz-form-item> |
|
||||
<nz-form-label nzFlex="80px">产品名称</nz-form-label> |
|
||||
<nz-form-control nzSpan="18"> |
|
||||
<input nz-input placeholder="请输入产品名称" formControlName="name" /> |
|
||||
</nz-form-control> |
|
||||
</nz-form-item> |
|
||||
</div> |
|
||||
<div nz-col nzSpan="12"> |
|
||||
<nz-form-item> |
|
||||
<nz-form-label nzFlex="80px">创建时间</nz-form-label> |
|
||||
<nz-form-control nzSpan="18"> |
|
||||
<!-- <nz-range-picker nzShowTime formControlName="createTime"></nz-range-picker> --> |
|
||||
<app-range-picker [showTime]="true" formControlName="createTime"></app-range-picker> |
|
||||
</nz-form-control> |
|
||||
</nz-form-item> |
|
||||
</div> |
|
||||
</div> |
|
||||
<div *appTableAction class="flex"> |
|
||||
<div> |
|
||||
<nz-space> |
|
||||
<button *nzSpaceItem nzType="primary" nz-button (click)="create()">添加产品</button> |
|
||||
</nz-space> |
|
||||
</div> |
|
||||
</div> |
|
||||
|
|
||||
<!-- <div action>Custom Modal action</div> --> |
|
||||
</app-server-paginated-table> |
|
||||
</nz-card> |
|
||||
|
|
||||
<ng-template #productFormTpl> |
|
||||
<form [formGroup]="createForm" nz-form [nzLayout]="'vertical'"> |
|
||||
<nz-form-item> |
|
||||
<nz-form-label nzRequired> 产品名称 </nz-form-label> |
|
||||
<nz-form-control [nzErrorTip]="formErrorTipsTpl"> |
|
||||
<input nz-input placeholder="请输入产品名称" formControlName="name" /> |
|
||||
</nz-form-control> |
|
||||
</nz-form-item> |
|
||||
|
|
||||
<nz-form-item> |
|
||||
<nz-form-label nzRequired> 产品ID </nz-form-label> |
|
||||
<nz-form-control [nzErrorTip]="formErrorTipsTpl"> |
|
||||
<input nz-input placeholder="请输入产品ID" formControlName="productId" /> |
|
||||
</nz-form-control> |
|
||||
</nz-form-item> |
|
||||
|
|
||||
<nz-form-item> |
|
||||
<nz-form-label> 产品说明 </nz-form-label> |
|
||||
<nz-form-control [nzErrorTip]="formErrorTipsTpl"> |
|
||||
<textarea nz-input placeholder="请输入产品说明" formControlName="remark"></textarea> |
|
||||
</nz-form-control> |
|
||||
</nz-form-item> |
|
||||
</form> |
|
||||
</ng-template> |
|
||||
|
|
||||
<ng-template #formErrorTipsTpl let-control> |
|
||||
<form-error-tips [control]="control"></form-error-tips> |
|
||||
</ng-template> |
|
@ -1,104 +0,0 @@ |
|||||
import { Component, ElementRef, OnInit, TemplateRef, ViewChild } from '@angular/core' |
|
||||
import { FormControl, FormGroup } from '@angular/forms' |
|
||||
import { NzModalService } from 'ng-zorro-antd/modal' |
|
||||
import { ApiService } from 'app/services' |
|
||||
import { AnyObject, ServerPaginatedTableComponent, TableOption } from 'app/components/server-paginated-table' |
|
||||
import { SharedModule } from 'app/shared/shared.module' |
|
||||
import { FormValidators } from 'app/utils' |
|
||||
import { lastValueFrom } from 'rxjs' |
|
||||
import { ProductDTO } from 'app/services/api.dto' |
|
||||
import { NzMessageService } from 'ng-zorro-antd/message' |
|
||||
import { format } from 'date-fns' |
|
||||
|
|
||||
@Component({ |
|
||||
selector: 'app-product-list', |
|
||||
standalone: true, |
|
||||
imports: [SharedModule], |
|
||||
templateUrl: './product-list.component.html', |
|
||||
styleUrl: './product-list.component.less', |
|
||||
}) |
|
||||
export class ProductListComponent { |
|
||||
constructor( |
|
||||
private api: ApiService, |
|
||||
private modal: NzModalService, |
|
||||
private msg: NzMessageService, |
|
||||
) {} |
|
||||
|
|
||||
@ViewChild('productFormTpl') productFormTpl!: TemplateRef<{}> |
|
||||
|
|
||||
table = new TableOption( |
|
||||
this.fetchData.bind(this), |
|
||||
[ |
|
||||
{ key: 'name', title: '产品名称' }, |
|
||||
{ key: 'productId', title: '产品ID' }, |
|
||||
{ key: 'remark', title: '产品说明', width: '500px' }, |
|
||||
{ key: 'createTime', title: '创建时间' }, |
|
||||
], |
|
||||
[], |
|
||||
) |
|
||||
|
|
||||
queryForm = new FormGroup({ |
|
||||
name: new FormControl(''), |
|
||||
createTime: new FormControl(), |
|
||||
}) |
|
||||
|
|
||||
createForm = new FormGroup({ |
|
||||
name: new FormControl('', [FormValidators.required('请输入产品名称'), FormValidators.maxLength(30)]), |
|
||||
productId: new FormControl('', [FormValidators.required('请输入产品ID'), FormValidators.maxLength(30)]), |
|
||||
remark: new FormControl('', [FormValidators.maxLength(200)]), |
|
||||
}) |
|
||||
|
|
||||
ngOnInit(): void { |
|
||||
this.table.setRowOperate([ |
|
||||
{ title: '编辑', onClick: this.create.bind(this) }, |
|
||||
{ title: '删除', onClick: this.deleteItem.bind(this) }, |
|
||||
]) |
|
||||
} |
|
||||
|
|
||||
fetchData(p: {}, q: AnyObject) { |
|
||||
if (Array.isArray(q['createTime'])) { |
|
||||
const createTimeStart = q['createTime']?.[0] |
|
||||
const createTimeEnd = q['createTime']?.[1] |
|
||||
|
|
||||
q['createTimeStart'] = createTimeStart ? format(new Date(createTimeStart), 'yyyy-MM-dd HH:mm:ss') : '' |
|
||||
q['createTimeEnd'] = createTimeEnd ? format(new Date(createTimeEnd), 'yyyy-MM-dd HH:mm:ss') : '' |
|
||||
} |
|
||||
return this.api.getProductPage(p, q) |
|
||||
} |
|
||||
|
|
||||
onSearch() {} |
|
||||
|
|
||||
create(product?: ProductDTO) { |
|
||||
if (product) { |
|
||||
this.createForm.patchValue(product) |
|
||||
} |
|
||||
this.modal.create({ |
|
||||
nzTitle: product ? '编辑产品' : '添加产品', |
|
||||
nzContent: this.productFormTpl, |
|
||||
nzOnOk: async () => { |
|
||||
if (FormValidators.validateFormGroup(this.createForm)) { |
|
||||
await lastValueFrom(this.api.saveProduct({ ...(product ?? {}), ...this.createForm.value })) |
|
||||
this.msg.success('保存成功') |
|
||||
this.table.ref?.reload() |
|
||||
this.createForm.reset() |
|
||||
} |
|
||||
}, |
|
||||
nzOnCancel: () => { |
|
||||
this.createForm.reset() |
|
||||
}, |
|
||||
}) |
|
||||
} |
|
||||
|
|
||||
deleteItem(product: ProductDTO) { |
|
||||
this.modal.confirm({ |
|
||||
nzTitle: '警告', |
|
||||
nzContent: '是否要删除该产品?', |
|
||||
nzOkDanger: true, |
|
||||
nzOnOk: async () => { |
|
||||
await lastValueFrom(this.api.deleteProduct(product.id)) |
|
||||
this.msg.success('删除成功') |
|
||||
this.table.ref?.reload() |
|
||||
}, |
|
||||
}) |
|
||||
} |
|
||||
} |
|
@ -1,28 +0,0 @@ |
|||||
<div class="w-[600px] pt-6"> |
|
||||
<form nz-form [formGroup]="formGroup" (ngSubmit)="onSubmit()"> |
|
||||
<nz-form-item> |
|
||||
<nz-form-label nzSpan="4" nzRequired> 用户名 </nz-form-label> |
|
||||
<nz-form-control nzSpan="16"> |
|
||||
<input nz-input placeholder="请输入用户名" formControlName="username" /> |
|
||||
</nz-form-control> |
|
||||
</nz-form-item> |
|
||||
<nz-form-item> |
|
||||
<nz-form-label nzSpan="4" nzRequired> 新密码 </nz-form-label> |
|
||||
<nz-form-control nzSpan="16"> |
|
||||
<input nz-input type="password" placeholder="请输入新密码" formControlName="password" /> |
|
||||
</nz-form-control> |
|
||||
</nz-form-item> |
|
||||
<nz-form-item> |
|
||||
<nz-form-label nzSpan="4" nzRequired> 确认密码 </nz-form-label> |
|
||||
<nz-form-control nzSpan="16"> |
|
||||
<input nz-input type="password" placeholder="请再次输入密码" formControlName="confirmPassword" /> |
|
||||
</nz-form-control> |
|
||||
</nz-form-item> |
|
||||
|
|
||||
<nz-form-item> |
|
||||
<nz-form-control nzOffset="4"> |
|
||||
<button nz-button nzType="primary">保存</button> |
|
||||
</nz-form-control> |
|
||||
</nz-form-item> |
|
||||
</form> |
|
||||
</div> |
|
@ -1,46 +0,0 @@ |
|||||
import { Component } from '@angular/core' |
|
||||
import { SharedModule } from '../../shared/shared.module' |
|
||||
import { FormControl, FormGroup } from '@angular/forms' |
|
||||
import { FormValidators } from 'app/utils' |
|
||||
import { ApiService, LocalHttpInterceptorService } from 'app/services' |
|
||||
import { NzMessageService } from 'ng-zorro-antd/message' |
|
||||
|
|
||||
@Component({ |
|
||||
standalone: true, |
|
||||
imports: [SharedModule], |
|
||||
selector: 'app-profile-account', |
|
||||
templateUrl: './profile-account.component.html', |
|
||||
styleUrls: ['./profile-account.component.less'], |
|
||||
}) |
|
||||
export class ProfileAccountComponent { |
|
||||
constructor( |
|
||||
private local: LocalHttpInterceptorService, |
|
||||
private api: ApiService, |
|
||||
private msg: NzMessageService, |
|
||||
) {} |
|
||||
|
|
||||
formGroup = new FormGroup({ |
|
||||
id: new FormControl(this.api.authInfo.id), |
|
||||
username: new FormControl({ value: this.api.authInfo.username, disabled: true }, [ |
|
||||
FormValidators.required('请输入用户名'), |
|
||||
]), |
|
||||
password: new FormControl('', [FormValidators.required('请输入密码')]), |
|
||||
confirmPassword: new FormControl('', [FormValidators.required('请再次输入密码')]), |
|
||||
}) |
|
||||
|
|
||||
onSubmit() { |
|
||||
if (FormValidators.validateFormGroup(this.formGroup)) { |
|
||||
if (this.formGroup.value.confirmPassword !== this.formGroup.value.password) { |
|
||||
this.msg.error('两次输入密码不一致') |
|
||||
return |
|
||||
} |
|
||||
const v = this.formGroup.getRawValue() |
|
||||
this.api.changePassword(v).subscribe(() => { |
|
||||
this.msg.success('修改成功,请重新登录').onClose.subscribe(() => { |
|
||||
this.local.removeAccess() |
|
||||
window.location.href = '/login' |
|
||||
}) |
|
||||
}) |
|
||||
} |
|
||||
} |
|
||||
} |
|
@ -1,54 +0,0 @@ |
|||||
<div class="w-[600px] pt-6"> |
|
||||
<form nz-form [formGroup]="formGroup" (ngSubmit)="onSubmit()"> |
|
||||
<nz-form-item> |
|
||||
<nz-form-label nzSpan="4" nzRequired>姓名</nz-form-label> |
|
||||
<nz-form-control nzSpan="16" [nzErrorTip]="formErrorTipsTpl"> |
|
||||
<input nz-input placeholder="请输入姓名" formControlName="name" /> |
|
||||
</nz-form-control> |
|
||||
</nz-form-item> |
|
||||
|
|
||||
<nz-form-item> |
|
||||
<nz-form-label nzSpan="4">备注</nz-form-label> |
|
||||
<nz-form-control nzSpan="16"> |
|
||||
<textarea nz-input placeholder="请输入备注" formControlName="remark"></textarea> |
|
||||
</nz-form-control> |
|
||||
</nz-form-item> |
|
||||
<!-- <nz-form-item> |
|
||||
<nz-form-label nzSpan="4">登录限制</nz-form-label> |
|
||||
<nz-form-control nzSpan="16"> |
|
||||
<nz-switch></nz-switch> |
|
||||
</nz-form-control> |
|
||||
</nz-form-item> |
|
||||
<nz-form-item> |
|
||||
<nz-form-label nzSpan="4">限制规则</nz-form-label> |
|
||||
<nz-form-control nzSpan="16"> |
|
||||
<div> |
|
||||
<nz-input-group nzAddOnBefore="登录失败达到" nzAddOnAfter="次"> |
|
||||
<input type="number" nz-input /> |
|
||||
</nz-input-group> |
|
||||
</div> |
|
||||
<div class="mt-2"> |
|
||||
<ng-template #nzAddOnAfterTpl> |
|
||||
<nz-select class="!w-20"> |
|
||||
<nz-option nzValue="m" nzLabel="分钟"></nz-option> |
|
||||
<nz-option nzValue="h" nzLabel="小时"></nz-option> |
|
||||
<nz-option nzValue="d" nzLabel="天"></nz-option> |
|
||||
</nz-select> |
|
||||
</ng-template> |
|
||||
<nz-input-group nzAddOnBefore="锁定账号" [nzAddOnAfter]="nzAddOnAfterTpl"> |
|
||||
<input type="number" nz-input /> |
|
||||
</nz-input-group> |
|
||||
</div> |
|
||||
</nz-form-control> |
|
||||
</nz-form-item> --> |
|
||||
<nz-form-item> |
|
||||
<nz-form-control nzOffset="4"> |
|
||||
<button nz-button nzType="primary">保存</button> |
|
||||
</nz-form-control> |
|
||||
</nz-form-item> |
|
||||
</form> |
|
||||
|
|
||||
<ng-template #formErrorTipsTpl let-control> |
|
||||
<form-error-tips [control]="control"></form-error-tips> |
|
||||
</ng-template> |
|
||||
</div> |
|
@ -1,52 +0,0 @@ |
|||||
import { Component, OnDestroy, OnInit } from '@angular/core' |
|
||||
import { SharedModule } from '../../shared/shared.module' |
|
||||
import { ApiService } from 'app/services' |
|
||||
import { UserFormComponent } from 'app/components/user-form/user-form.component' |
|
||||
import { FormBuilder, FormControl, FormGroup } from '@angular/forms' |
|
||||
import { FormValidators } from 'app/utils' |
|
||||
import { NzMessageService } from 'ng-zorro-antd/message' |
|
||||
import { Subscription } from 'rxjs' |
|
||||
|
|
||||
@Component({ |
|
||||
standalone: true, |
|
||||
imports: [SharedModule, UserFormComponent], |
|
||||
selector: 'app-profile-basic', |
|
||||
templateUrl: './profile-basic.component.html', |
|
||||
styleUrls: ['./profile-basic.component.less'], |
|
||||
}) |
|
||||
export class ProfileBasicComponent implements OnInit, OnDestroy { |
|
||||
constructor( |
|
||||
public api: ApiService, |
|
||||
private fb: FormBuilder, |
|
||||
private msg: NzMessageService, |
|
||||
) {} |
|
||||
|
|
||||
formGroup!: FormGroup |
|
||||
|
|
||||
ngOnInit(): void { |
|
||||
this.formGroup = this.fb.group({ |
|
||||
name: new FormControl(this.api.authInfo.name, [FormValidators.required('请输入姓名')]), |
|
||||
remark: new FormControl(this.api.authInfo.remark), |
|
||||
}) |
|
||||
} |
|
||||
|
|
||||
ngOnDestroy(): void {} |
|
||||
|
|
||||
public getValues() { |
|
||||
let values = null |
|
||||
if (FormValidators.validateFormGroup(this.formGroup)) { |
|
||||
values = this.formGroup.value |
|
||||
} |
|
||||
return values |
|
||||
} |
|
||||
|
|
||||
onSubmit() { |
|
||||
const vals = this.getValues() |
|
||||
if (vals) { |
|
||||
this.api.saveUser({ ...this.api.authInfo, ...vals }).subscribe(() => { |
|
||||
this.msg.success('保存成功') |
|
||||
this.api.getAuthInfo(true).subscribe(() => {}) |
|
||||
}) |
|
||||
} |
|
||||
} |
|
||||
} |
|
@ -1,36 +0,0 @@ |
|||||
<div> |
|
||||
<nz-card [nzBordered]="false"> |
|
||||
<nz-descriptions [nzColumn]="2" class="ml-16"> |
|
||||
<nz-descriptions-item nzTitle="用户名"> |
|
||||
{{ api.authInfo.username }} |
|
||||
</nz-descriptions-item> |
|
||||
<nz-descriptions-item nzTitle="姓名"> |
|
||||
{{ api.authInfo.name }} |
|
||||
</nz-descriptions-item> |
|
||||
<nz-descriptions-item nzTitle="角色"> |
|
||||
{{ api.authInfo.roleName }} |
|
||||
</nz-descriptions-item> |
|
||||
<nz-descriptions-item nzTitle="状态"> |
|
||||
@if (api.authInfo.enable) { |
|
||||
<nz-badge nzStatus="success" nzText="启用"></nz-badge> |
|
||||
} @else { |
|
||||
<nz-badge nzStatus="errot" nzText="禁用"></nz-badge> |
|
||||
} |
|
||||
</nz-descriptions-item> |
|
||||
<nz-descriptions-item nzTitle="备注">{{ api.authInfo.remark || '-' }}</nz-descriptions-item> |
|
||||
</nz-descriptions> |
|
||||
</nz-card> |
|
||||
</div> |
|
||||
<div class="mt-4"> |
|
||||
<nz-card [nzBordered]="false"> |
|
||||
<div class="nav-bar"> |
|
||||
<ul> |
|
||||
<li class="cursor-pointer" [routerLink]="['/profile/basic']" routerLinkActive="active">基础信息</li> |
|
||||
<li class="cursor-pointer" [routerLink]="['/profile/account']" routerLinkActive="active">账号密码</li> |
|
||||
</ul> |
|
||||
</div> |
|
||||
<div class="py-4"> |
|
||||
<router-outlet></router-outlet> |
|
||||
</div> |
|
||||
</nz-card> |
|
||||
</div> |
|
@ -1,18 +0,0 @@ |
|||||
.nav-bar { |
|
||||
ul { |
|
||||
display: flex; |
|
||||
|
|
||||
li { |
|
||||
padding: 6px 24px; |
|
||||
margin-right: 12px; |
|
||||
font-size: 14px; |
|
||||
border-radius: 20px; |
|
||||
font-weight: bold; |
|
||||
|
|
||||
&.active { |
|
||||
background-color: #f2f3f5; |
|
||||
color: var(--primary); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
@ -1,22 +0,0 @@ |
|||||
import { Component, OnDestroy, OnInit } from '@angular/core' |
|
||||
import { SharedModule } from '../../shared/shared.module' |
|
||||
import { ApiService } from 'app/services' |
|
||||
import { UserDTO } from 'app/services/api.dto' |
|
||||
import { Subscription } from 'rxjs' |
|
||||
|
|
||||
@Component({ |
|
||||
standalone: true, |
|
||||
imports: [SharedModule], |
|
||||
selector: 'app-profile', |
|
||||
templateUrl: './profile.component.html', |
|
||||
styleUrls: ['./profile.component.less'], |
|
||||
}) |
|
||||
export class ProfileComponent implements OnInit, OnDestroy { |
|
||||
constructor(public api: ApiService) {} |
|
||||
|
|
||||
ngOnInit(): void { |
|
||||
this.api.getUserInfo(this.api.authInfo.id).subscribe((res) => {}) |
|
||||
} |
|
||||
|
|
||||
ngOnDestroy(): void {} |
|
||||
} |
|
@ -0,0 +1,10 @@ |
|||||
|
.icon { |
||||
|
width: 48px; |
||||
|
height: 48px; |
||||
|
border-radius: 8px; |
||||
|
overflow: hidden; |
||||
|
background-image: linear-gradient(135deg, #77abf4, #2f7deb); |
||||
|
font-size: 32px; |
||||
|
color: #fff; |
||||
|
|
||||
|
} |
@ -1 +1,31 @@ |
|||||
<p>flow-my-apply works!</p> |
<app-page> |
||||
|
<div class="flex-1 overflow-hidden"> |
||||
|
<app-server-paginated-table [options]="table" [renderColumn]="renderColumnTpl"> |
||||
|
<ng-template #renderColumnTpl let-data let-key="key" let-row="row"> |
||||
|
@switch (key) { |
||||
|
@case ('_assignee') { |
||||
|
<nz-tag> {{ data.userName }} </nz-tag> |
||||
|
} |
||||
|
@default { |
||||
|
{{ data }} |
||||
|
} |
||||
|
} |
||||
|
</ng-template> |
||||
|
</app-server-paginated-table> |
||||
|
</div> |
||||
|
</app-page> |
||||
|
|
||||
|
<ng-template #createFormTpl> |
||||
|
<form nz-form [formGroup]="createForm"> |
||||
|
<nz-form-item> |
||||
|
<nz-form-label [nzSpan]="6" [nzRequired]="true">审批人</nz-form-label> |
||||
|
<nz-form-control [nzSpan]="12" [nzErrorTip]="errorTpl"> |
||||
|
<app-select-user-by-org formControlName="userId" /> |
||||
|
</nz-form-control> |
||||
|
</nz-form-item> |
||||
|
</form> |
||||
|
</ng-template> |
||||
|
|
||||
|
<ng-template #errorTpl let-control> |
||||
|
<form-error-tips [control]="control"></form-error-tips> |
||||
|
</ng-template> |
||||
|
@ -1,12 +1,91 @@ |
|||||
import { Component } from '@angular/core'; |
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 { lastValueFrom, map, 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' |
||||
|
|
||||
@Component({ |
@Component({ |
||||
selector: 'app-flow-my-apply', |
selector: 'app-flow-my-apply', |
||||
standalone: true, |
standalone: true, |
||||
imports: [], |
imports: [SharedModule], |
||||
templateUrl: './flow-my-apply.component.html', |
templateUrl: './flow-my-apply.component.html', |
||||
styleUrl: './flow-my-apply.component.less' |
styleUrl: './flow-my-apply.component.less', |
||||
}) |
}) |
||||
export class FlowMyApplyComponent { |
export class FlowMyApplyComponent { |
||||
|
constructor( |
||||
|
private api: ApiService, |
||||
|
private modal: NzModalService, |
||||
|
private msg: NzMessageService, |
||||
|
) {} |
||||
|
|
||||
|
@ViewChild('createFormTpl') createFormTpl!: TemplateRef<{}> |
||||
|
|
||||
|
createForm = new FormGroup({ |
||||
|
formId: new FormControl(''), |
||||
|
userId: new FormControl<NzSafeAny[]>([], [FormValidators.required('请选择')]), |
||||
|
}) |
||||
|
|
||||
|
table = new TableOption(this.fetchData.bind(this)) |
||||
|
|
||||
|
ngOnInit(): void { |
||||
|
this.table |
||||
|
// .setConfig({
|
||||
|
// selectable: true,
|
||||
|
// rowKey: 'id',
|
||||
|
// })
|
||||
|
.setColumn([ |
||||
|
{ key: 'taskName', title: '标识', visible: true }, |
||||
|
{ key: 'name', title: '名称', visible: true }, |
||||
|
{ key: 'status', title: '审批状态', visible: true }, |
||||
|
{ key: 'category', 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: '详情' }, { title: '作废' }]) |
||||
|
} |
||||
|
|
||||
|
fetchData(p: {}, q: AnyObject) { |
||||
|
return this.api.getMyApplyAssetFlow({ ...p, ...q }) |
||||
|
} |
||||
|
|
||||
|
onSetApprover(data?: NzSafeAny) { |
||||
|
if (data) { |
||||
|
console.log('data._assignee.userId', data._assignee.userId) |
||||
|
this.createForm.patchValue({ |
||||
|
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() |
||||
|
}, |
||||
|
}) |
||||
|
} |
||||
} |
} |
||||
|
@ -0,0 +1,31 @@ |
|||||
|
<app-page> |
||||
|
<div class="flex-1 overflow-hidden"> |
||||
|
<app-server-paginated-table [options]="table" [renderColumn]="renderColumnTpl"> |
||||
|
<ng-template #renderColumnTpl let-data let-key="key" let-row="row"> |
||||
|
@switch (key) { |
||||
|
@case ('_assignee') { |
||||
|
<nz-tag> {{ data.userName }} </nz-tag> |
||||
|
} |
||||
|
@default { |
||||
|
{{ data }} |
||||
|
} |
||||
|
} |
||||
|
</ng-template> |
||||
|
</app-server-paginated-table> |
||||
|
</div> |
||||
|
</app-page> |
||||
|
|
||||
|
<ng-template #createFormTpl> |
||||
|
<form nz-form [formGroup]="createForm"> |
||||
|
<nz-form-item> |
||||
|
<nz-form-label [nzSpan]="6" [nzRequired]="true">审批人</nz-form-label> |
||||
|
<nz-form-control [nzSpan]="12" [nzErrorTip]="errorTpl"> |
||||
|
<app-select-user-by-org formControlName="userId" /> |
||||
|
</nz-form-control> |
||||
|
</nz-form-item> |
||||
|
</form> |
||||
|
</ng-template> |
||||
|
|
||||
|
<ng-template #errorTpl let-control> |
||||
|
<form-error-tips [control]="control"></form-error-tips> |
||||
|
</ng-template> |
@ -0,0 +1,91 @@ |
|||||
|
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 { lastValueFrom, map, 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' |
||||
|
|
||||
|
@Component({ |
||||
|
selector: 'app-flow-my-finished', |
||||
|
standalone: true, |
||||
|
imports: [SharedModule], |
||||
|
templateUrl: './flow-my-finished.component.html', |
||||
|
styleUrl: './flow-my-finished.component.less', |
||||
|
}) |
||||
|
export class FlowMyFinishedComponent { |
||||
|
constructor( |
||||
|
private api: ApiService, |
||||
|
private modal: NzModalService, |
||||
|
private msg: NzMessageService, |
||||
|
) {} |
||||
|
|
||||
|
@ViewChild('createFormTpl') createFormTpl!: TemplateRef<{}> |
||||
|
|
||||
|
createForm = new FormGroup({ |
||||
|
formId: new FormControl(''), |
||||
|
userId: new FormControl<NzSafeAny[]>([], [FormValidators.required('请选择')]), |
||||
|
}) |
||||
|
|
||||
|
table = new TableOption(this.fetchData.bind(this)) |
||||
|
|
||||
|
ngOnInit(): void { |
||||
|
this.table |
||||
|
// .setConfig({
|
||||
|
// selectable: true,
|
||||
|
// rowKey: 'id',
|
||||
|
// })
|
||||
|
.setColumn([ |
||||
|
{ key: 'taskName', title: '标识', visible: true }, |
||||
|
{ key: 'name', title: '名称', visible: true }, |
||||
|
{ key: 'status', title: '审批状态', visible: true }, |
||||
|
{ key: 'category', 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: '详情' }, { title: '作废' }]) |
||||
|
} |
||||
|
|
||||
|
fetchData(p: {}, q: AnyObject) { |
||||
|
return this.api.getMyFinishedAssetFlow({ ...p, ...q }) |
||||
|
} |
||||
|
|
||||
|
onSetApprover(data?: NzSafeAny) { |
||||
|
if (data) { |
||||
|
console.log('data._assignee.userId', data._assignee.userId) |
||||
|
this.createForm.patchValue({ |
||||
|
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() |
||||
|
}, |
||||
|
}) |
||||
|
} |
||||
|
} |
@ -1 +1,31 @@ |
|||||
<p>flow-my-todo works!</p> |
<app-page> |
||||
|
<div class="flex-1 overflow-hidden"> |
||||
|
<app-server-paginated-table [options]="table" [renderColumn]="renderColumnTpl"> |
||||
|
<ng-template #renderColumnTpl let-data let-key="key" let-row="row"> |
||||
|
@switch (key) { |
||||
|
@case ('_assignee') { |
||||
|
<nz-tag> {{ data.userName }} </nz-tag> |
||||
|
} |
||||
|
@default { |
||||
|
{{ data }} |
||||
|
} |
||||
|
} |
||||
|
</ng-template> |
||||
|
</app-server-paginated-table> |
||||
|
</div> |
||||
|
</app-page> |
||||
|
|
||||
|
<ng-template #createFormTpl> |
||||
|
<form nz-form [formGroup]="createForm"> |
||||
|
<nz-form-item> |
||||
|
<nz-form-label [nzSpan]="6" [nzRequired]="true">审批人</nz-form-label> |
||||
|
<nz-form-control [nzSpan]="12" [nzErrorTip]="errorTpl"> |
||||
|
<app-select-user-by-org formControlName="userId" /> |
||||
|
</nz-form-control> |
||||
|
</nz-form-item> |
||||
|
</form> |
||||
|
</ng-template> |
||||
|
|
||||
|
<ng-template #errorTpl let-control> |
||||
|
<form-error-tips [control]="control"></form-error-tips> |
||||
|
</ng-template> |
||||
|
@ -1,12 +1,91 @@ |
|||||
import { Component } from '@angular/core'; |
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 { lastValueFrom, map, 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' |
||||
|
|
||||
@Component({ |
@Component({ |
||||
selector: 'app-flow-my-todo', |
selector: 'app-flow-my-todo', |
||||
standalone: true, |
standalone: true, |
||||
imports: [], |
imports: [SharedModule], |
||||
templateUrl: './flow-my-todo.component.html', |
templateUrl: './flow-my-todo.component.html', |
||||
styleUrl: './flow-my-todo.component.less' |
styleUrl: './flow-my-todo.component.less', |
||||
}) |
}) |
||||
export class FlowMyTodoComponent { |
export class FlowMyTodoComponent { |
||||
|
constructor( |
||||
|
private api: ApiService, |
||||
|
private modal: NzModalService, |
||||
|
private msg: NzMessageService, |
||||
|
) {} |
||||
|
|
||||
|
@ViewChild('createFormTpl') createFormTpl!: TemplateRef<{}> |
||||
|
|
||||
|
createForm = new FormGroup({ |
||||
|
formId: new FormControl(''), |
||||
|
userId: new FormControl<NzSafeAny[]>([], [FormValidators.required('请选择')]), |
||||
|
}) |
||||
|
|
||||
|
table = new TableOption(this.fetchData.bind(this)) |
||||
|
|
||||
|
ngOnInit(): void { |
||||
|
this.table |
||||
|
// .setConfig({
|
||||
|
// selectable: true,
|
||||
|
// rowKey: 'id',
|
||||
|
// })
|
||||
|
.setColumn([ |
||||
|
{ key: 'taskName', title: '标识', visible: true }, |
||||
|
{ key: 'name', title: '名称', visible: true }, |
||||
|
{ key: 'status', title: '审批状态', visible: true }, |
||||
|
{ key: 'category', 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: '详情' }, { title: '作废' }]) |
||||
|
} |
||||
|
|
||||
|
fetchData(p: {}, q: AnyObject) { |
||||
|
return this.api.getMyTodoAssetFlow({ ...p, ...q }) |
||||
|
} |
||||
|
|
||||
|
onSetApprover(data?: NzSafeAny) { |
||||
|
if (data) { |
||||
|
console.log('data._assignee.userId', data._assignee.userId) |
||||
|
this.createForm.patchValue({ |
||||
|
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() |
||||
|
}, |
||||
|
}) |
||||
|
} |
||||
} |
} |
||||
|
Loading…
Reference in new issue