diff --git a/src/app/pages/account/account.routes.ts b/src/app/pages/account/account.routes.ts index 86b1617..b5c3b24 100644 --- a/src/app/pages/account/account.routes.ts +++ b/src/app/pages/account/account.routes.ts @@ -1,8 +1,10 @@ import { Routes } from '@angular/router'; import {SysAccountComponent} from "./sys-account/sys-account.component"; import {SysRoleComponent} from "./sys-role/sys-role.component"; +import {UserComponent} from "./user/user.component"; export const ACCOUNT_ROUTES: Routes = [ { path: 'sys_account', component: SysAccountComponent}, - { path: 'sys_role', component: SysRoleComponent} + { path: 'sys_role', component: SysRoleComponent}, + { path: 'user_list', component: UserComponent}, ]; diff --git a/src/app/pages/account/sys-role/sys-role.component.html b/src/app/pages/account/sys-role/sys-role.component.html index 5878c10..0bedbc3 100644 --- a/src/app/pages/account/sys-role/sys-role.component.html +++ b/src/app/pages/account/sys-role/sys-role.component.html @@ -8,7 +8,7 @@ -
+
diff --git a/src/app/pages/account/sys-role/sys-role.component.less b/src/app/pages/account/sys-role/sys-role.component.less index a7f2d4e..6d5c351 100644 --- a/src/app/pages/account/sys-role/sys-role.component.less +++ b/src/app/pages/account/sys-role/sys-role.component.less @@ -7,3 +7,6 @@ button { .submit-btn { width: 150px; } +.search-area { + margin-top: 30px; +} diff --git a/src/app/pages/account/user/user.component.html b/src/app/pages/account/user/user.component.html new file mode 100644 index 0000000..c61ca0e --- /dev/null +++ b/src/app/pages/account/user/user.component.html @@ -0,0 +1,81 @@ +
+
+
+ + 用户名 + + + + +
+ +
+ + 手机号 + + + + +
+ +
+ + 状态 + + + + + + +
+
+ + +
+
+
+ + + + + 用户名 + 手机号 + 积分数量 + 状态 + 注册时间 + 操作 + + + + + {{data.name}} + {{data.phone}} + {{data.integral}} + {{data.status | dictionary: 'USER_STATUS'}} + {{data.createTime | date: 'yyyy-MM-dd HH:mm'}} + + 禁用账户 + 恢复账户 + + + + + 总计 {{ total }} 条 + diff --git a/src/app/pages/account/user/user.component.less b/src/app/pages/account/user/user.component.less new file mode 100644 index 0000000..3d2cd3b --- /dev/null +++ b/src/app/pages/account/user/user.component.less @@ -0,0 +1,6 @@ +.search-area { + margin-top: 30px; +} +button { + margin-left: 8px; +} diff --git a/src/app/pages/account/user/user.component.ts b/src/app/pages/account/user/user.component.ts new file mode 100644 index 0000000..4a05c01 --- /dev/null +++ b/src/app/pages/account/user/user.component.ts @@ -0,0 +1,173 @@ +import { Component } from '@angular/core'; +import {FormGroup, NonNullableFormBuilder, ReactiveFormsModule} from "@angular/forms"; +import {NzMessageService} from "ng-zorro-antd/message"; +import {NzModalModule, NzModalService} from "ng-zorro-antd/modal"; +import {UserService} from "../../../servies/account/user.service"; +import {DatePipe, NgForOf, NgIf} from "@angular/common"; +import {NzButtonComponent} from "ng-zorro-antd/button"; +import {NzColDirective, NzRowDirective} from "ng-zorro-antd/grid"; +import {NzDividerComponent} from "ng-zorro-antd/divider"; +import {NzFormControlComponent, NzFormDirective, NzFormItemComponent, NzFormLabelComponent} from "ng-zorro-antd/form"; +import {NzInputDirective} from "ng-zorro-antd/input"; +import { + NzTableCellDirective, + NzTableComponent, + NzTbodyComponent, + NzTheadComponent, + NzThMeasureDirective, NzTrDirective +} from "ng-zorro-antd/table"; +import {DictionaryPipe} from "../../../pipes/common/dictionary.pipe"; +import {NzOptionComponent, NzSelectComponent} from "ng-zorro-antd/select"; +import {NzDropDownADirective, NzDropDownDirective, NzDropdownMenuComponent} from "ng-zorro-antd/dropdown"; +import {NzIconDirective} from "ng-zorro-antd/icon"; +import {NzMenuDirective, NzMenuItemComponent} from "ng-zorro-antd/menu"; + +@Component({ + selector: 'app-user', + standalone: true, + imports: [ + DatePipe, + NgForOf, + NzButtonComponent, + NzColDirective, + NzDividerComponent, + NzFormControlComponent, + NzFormDirective, + NzFormItemComponent, + NzFormLabelComponent, + NzInputDirective, + NzRowDirective, + NzTableCellDirective, + NzTableComponent, + NzTbodyComponent, + NzThMeasureDirective, + NzTheadComponent, + NzTrDirective, + ReactiveFormsModule, + DictionaryPipe, + NzSelectComponent, + NzOptionComponent, + NzModalModule, + NgIf, + NzDropDownADirective, + NzDropDownDirective, + NzDropdownMenuComponent, + NzIconDirective, + NzMenuDirective, + NzMenuItemComponent, + ], + templateUrl: './user.component.html', + styleUrl: './user.component.less' +}) +export class UserComponent { +// 表单页数 + tablePageNum = 1; + // 表单数据 + tableData: any = { + total: 0, + list: [], + }; + // 搜索表单 + searchForm: FormGroup; + + // 用户状态 + userStatusArray = new DictionaryPipe().getDictionaryList("USER_STATUS"); + constructor(private fb: NonNullableFormBuilder, + private userService: UserService, + private message: NzMessageService, + private modal: NzModalService) { + // 初始化搜索框 + this.searchForm = this.fb.group({ + name: [''], + phone: [''], + status: [''], + }); + + + this.queryData(); + } + + queryData() { + this.searchForm.value.pageNum = this.tablePageNum; + this.searchForm.value.pageSize = 10; + this.searchForm.value.time = new Date().getTime(); + this.userService.queryUserList(this.searchForm.value, (data: any) => { + if (data['return_code'] == '000000') { + this.tableData = data['return_data']; + } + }); + } + + /** + * 搜索表单提交 + */ + searchFormSubmit(): void { + this.tablePageNum = 1; + this.queryData(); + } + + /** + * 搜索表单重置 + */ + searchFormReset(): void { + this.searchForm.reset(); + } + + /** + * 打开恢复账户确认框 + */ + showRestore(dataId: number) { + this.modal.confirm({ + nzTitle: '提示', + nzContent: '确定恢复账户状态?', + nzOnOk: () => this.restore(dataId) + }); + } + + /** + * 恢复 + */ + restore(dataId: number) { + const param = { + userId: dataId + } + this.userService.restore(param, (data: any) => { + if (data['return_code'] == '000000') { + // 刷新数据 + this.queryData(); + this.message.success("操作成功"); + } else { + this.message.create('error', data['return_msg']); + } + }); + } + + /** + * 打开禁用账户确认框 + */ + showDisable(dataId: number) { + this.modal.confirm({ + nzTitle: '提示', + nzContent: '确定禁用账户吗?禁用后无法登录、交易!', + nzOnOk: () => this.disable(dataId) + }); + } + + /** + * 禁用 + */ + disable(dataId: number) { + const param = { + userId: dataId + } + this.userService.disable(param, (data: any) => { + if (data['return_code'] == '000000') { + // 刷新数据 + this.queryData(); + this.message.success("操作成功"); + } else { + this.message.create('error', data['return_msg']); + } + }); + } +} diff --git a/src/app/pages/merchant/mer-add/mer-add.component.html b/src/app/pages/merchant/mer-add/mer-add.component.html index 61f052b..f76a706 100644 --- a/src/app/pages/merchant/mer-add/mer-add.component.html +++ b/src/app/pages/merchant/mer-add/mer-add.component.html @@ -1,27 +1,11 @@
- 登录账户 - - - - - - - 角色权限 - - - - - - - - - logo + 商家标志 + + 登录账户 + + + + + + + 角色权限 + + + + + + + 商户名称 - + @@ -59,7 +59,7 @@ - 负责人电话 + 联系电话 diff --git a/src/app/pages/merchant/mer-add/mer-add.component.less b/src/app/pages/merchant/mer-add/mer-add.component.less index 8ad44a1..5058b65 100644 --- a/src/app/pages/merchant/mer-add/mer-add.component.less +++ b/src/app/pages/merchant/mer-add/mer-add.component.less @@ -1,7 +1,9 @@ form { - text-align: center; width: 500px; } .logo-uploader { text-align: left; } +.submit-btn { + width: 150px; +} diff --git a/src/app/pages/merchant/mer-add/mer-add.component.ts b/src/app/pages/merchant/mer-add/mer-add.component.ts index 991a48c..352a14c 100644 --- a/src/app/pages/merchant/mer-add/mer-add.component.ts +++ b/src/app/pages/merchant/mer-add/mer-add.component.ts @@ -19,6 +19,8 @@ import {NzUploadFile, NzUploadModule} from "ng-zorro-antd/upload"; import {NzIconDirective} from "ng-zorro-antd/icon"; import {Observable, Observer} from "rxjs"; import {NzMessageService} from "ng-zorro-antd/message"; +import {RoleService} from "../../../servies/role/role.service"; +import {environment} from "../../../../environments/environment"; @Component({ selector: 'app-mer-add', @@ -47,7 +49,7 @@ import {NzMessageService} from "ng-zorro-antd/message"; styleUrl: './mer-add.component.less' }) export class MerAddComponent { - + BASE_URL = environment.baseUrl; loading = false; logoUrl?: string; @@ -57,6 +59,7 @@ export class MerAddComponent { constructor(private fb: NonNullableFormBuilder, private merService: MerService, + private roleService: RoleService, private message: NzMessageService, private modal: NzModalService) { // 初始化表单 @@ -70,10 +73,36 @@ export class MerAddComponent { customerServiceTel: [''], address: [''], }); + + // 获取角色数据 + this.roleService.queryAllRole((data: any) => { + this.roleData = data['return_data']; + }); } submitForm() { + console.log(this.logoUrl); + if (this.form.valid) { + this.merService.create(this.form.value, (data: any) => { + if (data['return_code'] == '000000') { + this.message.create('success', '操作成功'); + + // 清空表单 + this.form.reset(); + this.logoUrl = ''; + } else { + this.message.create('error', data['return_msg']); + } + }); + } else { + Object.values(this.form.controls).forEach(control => { + if (control.invalid) { + control.markAsDirty(); + control.updateValueAndValidity({ onlySelf: true }); + } + }); + } } private getBase64(img: File, callback: (img: string) => void): void { @@ -93,9 +122,10 @@ export class MerAddComponent { this.loading = false; this.logoUrl = img; }); + this.form.patchValue({ merLogo: info.file.response['return_data'][0]}); break; case 'error': - this.message.error('Network error'); + this.message.error('网络错误!'); this.loading = false; break; } @@ -105,13 +135,13 @@ export class MerAddComponent { return new Observable((observer: Observer) => { const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png'; if (!isJpgOrPng) { - this.message.error('You can only upload JPG file!'); + this.message.error('只能上传JPG文件!'); observer.complete(); return; } const isLt2M = file.size! / 1024 / 1024 < 2; if (!isLt2M) { - this.message.error('Image must smaller than 2MB!'); + this.message.error('图片必须小于2MB!'); observer.complete(); return; } diff --git a/src/app/pages/merchant/mer-list/mer-list.component.html b/src/app/pages/merchant/mer-list/mer-list.component.html index a3cf75b..352c02a 100644 --- a/src/app/pages/merchant/mer-list/mer-list.component.html +++ b/src/app/pages/merchant/mer-list/mer-list.component.html @@ -1 +1,196 @@ -

mer-list works!

+ +
+
+ + 商户号 + + + + +
+
+ + 商户名称 + + + + +
+
+ + 创建人 + + + + +
+ +
+ + +
+
+ + + + + + 商户号 + 商户名称 + 负责人 + 联系电话 + 创建人 + 创建时间 + 更新时间 + 操作 + + + + + {{data.merNo}} + {{data.merName}} + {{data.directorName}} + {{data.directorTel}} + {{data.opUserName}} + {{data.createTime | date: 'yyyy-MM-dd HH:mm'}} + {{data.updateTime | date: 'yyyy-MM-dd HH:mm'}} + + 详情 + + 修改资料 + + + 更多 + + + + + + + + + 总计 {{ total }} 条 + + + + + + + + + + {{merDetailObject.loginName}} + {{merDetailObject.roleName}} + {{merDetailObject.merNo}} + {{merDetailObject.merName}} + {{merDetailObject.directorName}} + {{merDetailObject.directorTel}} + {{merDetailObject.customerServiceTel}} + {{merDetailObject.address}} + + + + + + +
+ + + 商家标志 + + + + +
上传
+
+ +
+
+
+ + + 登录账户 + + + + + + + 角色权限 + + + + + + + + + 商户名称 + + + + + + + 负责人 + + + + + + + 联系电话 + + + + + + + 商户地址 + + + + + + + 客服电话 + + + + + +
+ +
+ +
+
+
diff --git a/src/app/pages/merchant/mer-list/mer-list.component.less b/src/app/pages/merchant/mer-list/mer-list.component.less index e69de29..37076bc 100644 --- a/src/app/pages/merchant/mer-list/mer-list.component.less +++ b/src/app/pages/merchant/mer-list/mer-list.component.less @@ -0,0 +1,9 @@ +button { + margin-left: 8px; +} +.search-area { + margin-top: 30px; +} +.submit-btn { + width: 150px; +} diff --git a/src/app/pages/merchant/mer-list/mer-list.component.ts b/src/app/pages/merchant/mer-list/mer-list.component.ts index 9d7a95f..00eeabf 100644 --- a/src/app/pages/merchant/mer-list/mer-list.component.ts +++ b/src/app/pages/merchant/mer-list/mer-list.component.ts @@ -1,12 +1,317 @@ import { Component } from '@angular/core'; +import {DatePipe, NgForOf, NgIf} from "@angular/common"; +import {DictionaryPipe} from "../../../pipes/common/dictionary.pipe"; +import {FormGroup, FormsModule, NonNullableFormBuilder, ReactiveFormsModule, Validators} from "@angular/forms"; +import {NzButtonComponent} from "ng-zorro-antd/button"; +import { + NzCellFixedDirective, + NzTableCellDirective, + NzTableComponent, NzTableModule, + NzTbodyComponent, NzTheadComponent, + NzThMeasureDirective, NzTrDirective +} from "ng-zorro-antd/table"; +import {NzColDirective, NzRowDirective} from "ng-zorro-antd/grid"; +import {NzDividerComponent} from "ng-zorro-antd/divider"; +import {NzDropDownADirective, NzDropDownDirective, NzDropdownMenuComponent} from "ng-zorro-antd/dropdown"; +import {NzFormControlComponent, NzFormDirective, NzFormItemComponent, NzFormLabelComponent} from "ng-zorro-antd/form"; +import {NzIconDirective} from "ng-zorro-antd/icon"; +import {NzInputDirective} from "ng-zorro-antd/input"; +import {NzMenuDirective, NzMenuItemComponent} from "ng-zorro-antd/menu"; +import {NzOptionComponent, NzSelectComponent} from "ng-zorro-antd/select"; +import {SysAccountService} from "../../../servies/account/sys-account.service"; +import {RoleService} from "../../../servies/role/role.service"; +import {NzMessageService} from "ng-zorro-antd/message"; +import {NzModalModule, NzModalService} from "ng-zorro-antd/modal"; +import {MerService} from "../../../servies/merchant/mer.service"; +import {NzFlexDirective} from "ng-zorro-antd/flex"; +import {NzDescriptionsModule} from "ng-zorro-antd/descriptions"; +import {NzUploadComponent, NzUploadFile} from "ng-zorro-antd/upload"; +import {environment} from "../../../../environments/environment"; +import {Observable, Observer} from "rxjs"; +import {NzAvatarComponent, NzAvatarModule} from "ng-zorro-antd/avatar"; @Component({ selector: 'app-mer-list', standalone: true, - imports: [], + imports: [ + DatePipe, + DictionaryPipe, + FormsModule, + NgForOf, + NgIf, + NzButtonComponent, + NzCellFixedDirective, + NzColDirective, + NzDividerComponent, + NzDropDownADirective, + NzDropDownDirective, + NzDropdownMenuComponent, + NzFormControlComponent, + NzFormDirective, + NzFormItemComponent, + NzFormLabelComponent, + NzIconDirective, + NzInputDirective, + NzMenuDirective, + NzMenuItemComponent, + NzOptionComponent, + NzRowDirective, + NzSelectComponent, + NzTableCellDirective, + NzTableComponent, + NzTbodyComponent, + NzThMeasureDirective, + NzTheadComponent, + NzTrDirective, + ReactiveFormsModule, + NzTableModule, + NzModalModule, + NzFlexDirective, + NzDescriptionsModule, + NzUploadComponent, + NzAvatarModule + ], templateUrl: './mer-list.component.html', styleUrl: './mer-list.component.less' }) export class MerListComponent { + BASE_URL = environment.baseUrl; + IMAGE_URL = environment.imageUrl; + // 表单页数 + tablePageNum = 1; + // 表单数据 + tableData: any = { + total: 0, + list: [], + }; + // 搜索表单 + searchForm: FormGroup; + + roleData: any = [] + merDetailVisible = false; + merDetailObject: any = {}; + + + merLogo = ''; + uploadLoading = false; + updateMerVisible = false; + updateMerForm: FormGroup; + + constructor(private fb: NonNullableFormBuilder, + private merService: MerService, + private roleService: RoleService, + private message: NzMessageService, + private modal: NzModalService) { + // 初始化搜索框 + this.searchForm = this.fb.group({ + merNo: [''], + merName: [''], + opUserName: [''], + status: [''], + }); + + this.updateMerForm = this.fb.group({ + loginName: [{ value: '', disabled: true}, [Validators.required]], + roleId: ['', [Validators.required]], + merLogo: [''], + merNo: [''], + merName: ['', [Validators.required]], + directorName: ['',[Validators.required]], + directorTel: ['',[Validators.required]], + customerServiceTel: [''], + address: [''], + }); + + // 获取角色数据 + this.roleService.queryAllRole((data: any) => { + this.roleData = data['return_data']; + }); + + this.queryData(); + } + + /** + * 获取数据 + */ + queryData() { + this.searchForm.value.pageNum = this.tablePageNum; + this.searchForm.value.pageSize = 10; + this.searchForm.value.time = new Date().getTime(); + this.merService.queryList(this.searchForm.value, (data: any) => { + if (data['return_code'] == '000000') { + this.tableData = data['return_data']; + } + }); + } + + /** + * 搜索表单提交 + */ + searchFormSubmit(): void { + this.tablePageNum = 1; + this.queryData(); + } + + /** + * 搜索表单重置 + */ + searchFormReset(): void { + this.searchForm.reset(); + } + + /** + * 展示商户详情 + * @param merNo + */ + showMerDetail(merNo: string) { + this.merService.queryMer(merNo, (data: any) => { + if (data['return_code'] == '000000') { + this.merDetailObject = data['return_data']; + } else { + this.message.error(data['return_msg']); + } + }); + this.merDetailVisible = true; + } + + /** + * 关闭商户详情 + */ + closeMerDetail() { + this.merDetailObject = {}; + this.merDetailVisible = false; + } + + /** + * 打开修改商户模态框 + * @param merData + */ + showUpdateMer(merNo: string) { + this.merService.queryMer(merNo, (data: any) => { + if (data['return_code'] == '000000') { + data['return_data']['roleId'] = String(data['return_data']['roleId']); + this.updateMerForm.patchValue(data['return_data']); + + console.log(this.updateMerForm.controls['merLogo'].value); + } else { + this.message.error(data['return_msg']); + } + }); + this.updateMerVisible = true; + } + + /** + * 提交修改商户 + */ + submitUpdateMerForm() { + if (this.updateMerForm.valid) { + this.merService.update(this.updateMerForm.value, (data: any) => { + if (data['return_code'] == '000000') { + + this.message.create('success', '操作成功'); + + // 关闭弹窗 + this.closeUpdateMer(); + // 刷新列表 + this.queryData(); + + } else { + this.message.create('error', data['return_msg']); + } + }); + } else { + Object.values(this.updateMerForm.controls).forEach(control => { + if (control.invalid) { + control.markAsDirty(); + control.updateValueAndValidity({ onlySelf: true }); + } + }); + } + } + + /** + * 关闭修改商户模态框 + */ + closeUpdateMer() { + this.updateMerForm.reset(); + this.updateMerVisible = false; + } + + /** + * 打开密码重置确认框 + */ + showResetPwd(merNo: string) { + this.modal.confirm({ + nzTitle: '提示', + nzContent: '确定重置商户账户登录密码吗?', + nzOnOk: () => this.resetPwd(merNo) + }); + } + + /** + * 密码重置 + */ + resetPwd(merNo: string) { + const param = { + merNo: merNo + } + this.merService.resetPwd(param, (data: any) => { + if (data['return_code'] == '000000') { + // 刷新数据 + this.queryData(); + this.modal.success({ + nzTitle: '提示', + nzContent: '密码重置成功,新密码:123456' + }); + } else { + this.message.create('error', data['return_msg']); + } + }); + } + + private getBase64(img: File, callback: (img: string) => void): void { + const reader = new FileReader(); + reader.addEventListener('load', () => callback(reader.result!.toString())); + reader.readAsDataURL(img); + } + + handleChange(info: { file: NzUploadFile }): void { + switch (info.file.status) { + case 'uploading': + this.uploadLoading = true; + break; + case 'done': + // Get this url from response in real world. + this.getBase64(info.file!.originFileObj!, (img: string) => { + this.uploadLoading = false; + this.merLogo = img; + }); + this.updateMerForm.patchValue({ merLogo: info.file.response['return_data'][0]}); + break; + case 'error': + this.message.error('网络错误!'); + this.uploadLoading = false; + break; + } + } + + beforeUpload = (file: NzUploadFile, _fileList: NzUploadFile[]) => { + return new Observable((observer: Observer) => { + const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png'; + if (!isJpgOrPng) { + this.message.error('只能上传JPG文件!'); + observer.complete(); + return; + } + const isLt2M = file.size! / 1024 / 1024 < 2; + if (!isLt2M) { + this.message.error('图片必须小于2MB!'); + observer.complete(); + return; + } + observer.next(isJpgOrPng && isLt2M); + observer.complete(); + }); + }; } diff --git a/src/app/servies/account/user.service.ts b/src/app/servies/account/user.service.ts new file mode 100644 index 0000000..c373ece --- /dev/null +++ b/src/app/servies/account/user.service.ts @@ -0,0 +1,45 @@ +import { Injectable } from '@angular/core'; +import {HttpClient} from "@angular/common/http"; +import {environment} from "../../../environments/environment"; +import {ObjectData} from "../../utils/objectData.service"; + +@Injectable({ + providedIn: 'root' +}) +export class UserService { + constructor(private http: HttpClient) { } + + /** + * 恢复账户 + * @param param + * @param callBack + */ + public restore(param: object, callBack:any) { + this.http.post(environment.baseUrl + 'user/restore', param).subscribe(data => { + callBack(data); + }); + } + + /** + * 禁用账户 + * @param param + * @param callBack + */ + public disable(param: object, callBack:any) { + this.http.post(environment.baseUrl + 'user/disable', param).subscribe(data => { + callBack(data); + }); + } + + /** + * 查询账户登录列表 + * @param params + * @param callBack + */ + public queryUserList(params: object, callBack:any) { + this.http.get(environment.baseUrl + 'user/queryUserList?'+ObjectData.objectByString(params)).subscribe(data => { + callBack(data); + }); + } + +} diff --git a/src/app/servies/merchant/mer.service.ts b/src/app/servies/merchant/mer.service.ts index 51d2800..326e6f2 100644 --- a/src/app/servies/merchant/mer.service.ts +++ b/src/app/servies/merchant/mer.service.ts @@ -32,13 +32,24 @@ export class MerService { }); } + /** + * 密码重置 + * @param params + * @param callBack + */ + public resetPwd(params: object, callBack:any) { + this.http.post(environment.baseUrl + 'mer/resetPwd', params).subscribe(data => { + callBack(data); + }); + } + /** * 查询商户 * @param merNo * @param callBack */ public queryMer(merNo: string, callBack:any) { - this.http.get(environment.baseUrl + 'mer/queryMer?merNo=' + merNo).subscribe(data => { + this.http.get(environment.baseUrl + 'mer/queryMer?merNo=' + merNo + '&dt=' + new Date().getTime()).subscribe(data => { callBack(data); }); }