diff --git a/src/app/routes/account/account-routing.module.ts b/src/app/routes/account/account-routing.module.ts index 8a7ce180..bfc01865 100644 --- a/src/app/routes/account/account-routing.module.ts +++ b/src/app/routes/account/account-routing.module.ts @@ -12,6 +12,7 @@ import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { AccountComponentsCenterComponent } from './components/center/center.component'; +import { AccountComponentsEditPayPasswordComponent } from './components/edit-paypassword/edit-paypassword.component' const routes: Routes = [ { path: '', redirectTo: 'center', pathMatch: 'full' }, @@ -21,7 +22,16 @@ const routes: Routes = [ data: { title: '账户中心' } - } + }, + { + path: 'edit-paypassword', + component: AccountComponentsEditPayPasswordComponent, + data: { + title: '修改支付密码', + titleI18n: 'app.my.edit.paypassword', + // guard: {ability: ['accountcenter-editpaypassword']} + }, + }, ]; @NgModule({ diff --git a/src/app/routes/account/account.module.ts b/src/app/routes/account/account.module.ts index 96606efa..8253c4dc 100644 --- a/src/app/routes/account/account.module.ts +++ b/src/app/routes/account/account.module.ts @@ -15,11 +15,13 @@ import { AccountRoutingModule } from './account-routing.module'; import { AccountComponentsCenterComponent } from './components/center/center.component'; import { AccountComponentsEditNameComponent } from './components/edit-name/edit-name.component'; import { AccountComponentsCenterEditComponent } from './components/edit-password/edit-password.component'; +import { AccountComponentsEditPayPasswordComponent } from './components/edit-paypassword/edit-paypassword.component' const COMPONENTS = [ AccountComponentsCenterComponent, AccountComponentsEditNameComponent, - AccountComponentsCenterEditComponent + AccountComponentsCenterEditComponent, + AccountComponentsEditPayPasswordComponent ]; const COMPONENTS_NOROUNT = [AccountComponentsEditNameComponent]; diff --git a/src/app/routes/account/components/center/center.component.html b/src/app/routes/account/components/center/center.component.html index d9df68c0..7181d388 100644 --- a/src/app/routes/account/components/center/center.component.html +++ b/src/app/routes/account/components/center/center.component.html @@ -12,9 +12,9 @@
{{ infoData.phone }}
已绑定 - 未绑定 + style="color: #52c41a"> 已绑定 + 未绑定
@@ -30,19 +30,44 @@
定期更换密码有助于账号安全
- 已设置 - 未设置 + 已设置 + 未设置
修改
+ + + +
+
+ + 支付密码 +
+
定期更换支付密码有助于账号安全
+
+ 已设置 + 未设置 +
+
+
+
+
设置
+
- + \ No newline at end of file diff --git a/src/app/routes/account/components/center/center.component.less b/src/app/routes/account/components/center/center.component.less index 96f8b59c..1df38e55 100644 --- a/src/app/routes/account/components/center/center.component.less +++ b/src/app/routes/account/components/center/center.component.less @@ -17,7 +17,7 @@ right: 20px; } .item-btn { - width: 28px; + width: 36px; text-align: center; } .li-label { diff --git a/src/app/routes/account/components/center/center.component.ts b/src/app/routes/account/components/center/center.component.ts index 713b106b..504529c6 100644 --- a/src/app/routes/account/components/center/center.component.ts +++ b/src/app/routes/account/components/center/center.component.ts @@ -53,6 +53,8 @@ export class AccountComponentsCenterComponent implements OnInit { }, ]; idx: any = 0; + defaultCompany: any = {}; + ifHasPayPw = false; constructor(public service: AccountService, private modal: ModalHelper, private http: _HttpClient, private router: Router, private modalService: NzModalService,) {} ngOnInit() { @@ -136,9 +138,31 @@ export class AccountComponentsCenterComponent implements OnInit { getInfo() { this.service.http.post(this.service.$api_get_current_user_info).subscribe((res) => { this.infoData = res.data; + this.getDeafaultCompany(); }); } + getDeafaultCompany() { + this.service.request(this.service.$api_getUserDefaultEnterpriseProject).subscribe(res => { + if (res === null) { + this.router.navigate(['/changeproject']); + return; + } + this.defaultCompany = res + if (res.projectId) { + this.getPayPw() + } + }) + } + + getPayPw() { + this.service.request(this.service.$api_isUserVerifyPassword, {}).subscribe(res => { + this.ifHasPayPw = res + }) + } + + + edit(tpye: string) { if (tpye === 'phone') { const modalRef = this.modalService.create({ @@ -170,6 +194,10 @@ export class AccountComponentsCenterComponent implements OnInit { } }); } + + if (tpye === 'payPassword') { + this.router.navigate(['/account/edit-paypassword']); + } // if (tpye === 'info') { // this.router.navigate(['/account/editInfo'], { // queryParams: { realName: this.infoData.realName, certificateNumber: this.infoData.certificateNumber }, diff --git a/src/app/routes/account/components/edit-paypassword/edit-paypassword.component.html b/src/app/routes/account/components/edit-paypassword/edit-paypassword.component.html new file mode 100644 index 00000000..c985b970 --- /dev/null +++ b/src/app/routes/account/components/edit-paypassword/edit-paypassword.component.html @@ -0,0 +1,171 @@ + + + + + + +
+
+
+ + + + + + + + + + + {{ index + 1 }} + + +
+ +
+
+ + + + + + +
+ +
+
+
+ +
+
+ + 设置支付密码 + + + + + + + + + + + + + + + + 请输入支付密码! + + 6位数字,不能为连续数字或者相同数字(如123456、111111) + + + + + + 重复支付密码 + + + + + + + + + + + + + + + + 请输入确认密码! + 两次输入的密码不一致! + + + + + + + + +
+
+
+
+ +
+

密码设置成功

+

请牢记您的新支付密码,3秒后自动跳转至个人中心...

+ +
+
+
+
+
+
+
+ + + + 获取验证码 + + + + {{ count > 0 ? '请等待' + count + 's' : ('app.register.get-verification-code') }} + + + diff --git a/src/app/routes/account/components/edit-paypassword/edit-paypassword.component.less b/src/app/routes/account/components/edit-paypassword/edit-paypassword.component.less new file mode 100644 index 00000000..229e8a87 --- /dev/null +++ b/src/app/routes/account/components/edit-paypassword/edit-paypassword.component.less @@ -0,0 +1,93 @@ +:host { + ::ng-deep { + page-grid { + background-color: #f0f3f7; + + div.container { + width: 80%; + margin: 0 auto; + padding: 30px 1rem 1rem; + } + } + + .ant-steps-item-process .ant-steps-item-icon { + background-color: #3370ff; + border-color: #3370ff; + } + + .ant-steps-item-finish > .ant-steps-item-container > .ant-steps-item-icon { + background: #3370ff; + } + + .ant-steps-dot .ant-steps-item-icon, + .ant-steps-dot.ant-steps-small .ant-steps-item-icon { + width: 32px; + height: 32px; + margin-left: 55px; + line-height: 32px; + border: 1px solid rgba(0, 0, 0, 0.25); + } + + // 文本 + .ant-steps-item-wait .ant-steps-item-icon > .ant-steps-icon { + color: #000; + } + + // 连接线 + .ant-steps-dot .ant-steps-item-tail, + .ant-steps-dot.ant-steps-small .ant-steps-item-tail { + top: 12px; + margin: 0 0 0 90px; + } + + .ant-steps-item-wait > .ant-steps-item-container > .ant-steps-item-tail::after { + background-color: rgba(0, 0, 0, 0.25); + } + + .ant-steps-dot .ant-steps-item-process .ant-steps-item-icon, + .ant-steps-dot.ant-steps-small .ant-steps-item-process .ant-steps-item-icon { + width: 32px; + height: 32px; + line-height: 32px; + } + + .ant-steps-item-process > .ant-steps-item-container > .ant-steps-item-tail::after { + background-color: rgba(0, 0, 0, 0.25); + } + + .ant-steps-dot .ant-steps-item-tail::after, + .ant-steps-dot.ant-steps-small .ant-steps-item-tail::after { + width: calc(100% - 62px); + height: 1.5px; + margin-left: 12px; + } + } +} + +.success-card { + text-align: center; + + .card-icon { + display: flex; + align-items: center; + justify-content: center; + width: 36px; + height: 36px; + margin: auto; + background-color: #52c41a; + border-radius: 50%; + } + + .card-title { + margin: 14px 0 0; + font-weight: bold; + font-size: 16px; + text-align: center; + } + + .card-descr { + margin: 8px 0 0; + font-size: 14px; + text-align: center; + } +} diff --git a/src/app/routes/account/components/edit-paypassword/edit-paypassword.component.spec.ts b/src/app/routes/account/components/edit-paypassword/edit-paypassword.component.spec.ts new file mode 100644 index 00000000..d3ce290b --- /dev/null +++ b/src/app/routes/account/components/edit-paypassword/edit-paypassword.component.spec.ts @@ -0,0 +1,23 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { AccountComponentsEditPayPasswordComponent } from './edit-paypassword.component'; + +describe('AccountComponentsEditPayPasswordComponent', () => { + let component: AccountComponentsEditPayPasswordComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [AccountComponentsEditPayPasswordComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(AccountComponentsEditPayPasswordComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/routes/account/components/edit-paypassword/edit-paypassword.component.ts b/src/app/routes/account/components/edit-paypassword/edit-paypassword.component.ts new file mode 100644 index 00000000..881603c4 --- /dev/null +++ b/src/app/routes/account/components/edit-paypassword/edit-paypassword.component.ts @@ -0,0 +1,237 @@ +import { AfterViewInit, Component, Inject, OnInit, Optional, ViewChild } from '@angular/core'; +import { FormBuilder, FormControl, FormGroup, ValidatorFn, Validators } from '@angular/forms'; +import { ActivatedRoute, Router } from '@angular/router'; +import { ReuseTabService } from '@delon/abc/reuse-tab'; +import { DA_SERVICE_TOKEN, ITokenService } from '@delon/auth'; +import { SFComponent, SFSchema, SFTextareaWidgetSchema, SFTextWidgetSchema, SFUISchema } from '@delon/form'; +import { SettingsService } from '@delon/theme'; +import { CaptchaComponent } from 'src/app/shared/components/captcha'; + +import { AccountService } from '../../services/account.service'; + +@Component({ + selector: 'app-account-components-edit-password', + templateUrl: './edit-paypassword.component.html', + styleUrls: ['./edit-paypassword.component.less'], +}) +export class AccountComponentsEditPayPasswordComponent implements OnInit, AfterViewInit { + @ViewChild('dun', { static: false }) + private dun!: CaptchaComponent; + + step: 0 | 1 | 2 = 0; + + step1Schema!: SFSchema; + ui!: SFUISchema; + @ViewChild('step1sf', { static: false }) + step1sf!: SFComponent; + + phone: string; + + formGroup3!: FormGroup; + confirmPasswordValidator!: ValidatorFn; + + isShowPwd = false; + isShowConfirmPwd = false; + + count = 0; + interval$: any; + + constructor( + private fb: FormBuilder, + public service: AccountService, + private route: ActivatedRoute, + private settingService: SettingsService, + private router: Router, + @Inject(ReuseTabService) + private reuseTabService: ReuseTabService, + @Optional() + @Inject(DA_SERVICE_TOKEN) + private tokenService: ITokenService, + ) { + this.phone = route.snapshot.queryParams.phone; + } + + ngAfterViewInit(): void { + this.dun.init(); + } + + ngOnInit() { + if (this.phone) { + this.initStep1SF(); + } else { + this.service.http.post(this.service.$api_get_current_user_info).subscribe((res) => { + if (res) { + this.phone = res.data?.phone; + this.initStep1SF(); + } + }); + } + + this.confirmPasswordValidator = (control) => { + if (!control.value) { + return { error: true, required: true }; + } else if (control.value !== this.formGroup3.controls.passWord.value) { + return { passWordTo: true, error: true }; + } + return {}; + }; + + this.formGroup3 = this.fb.group({ + passWord: [ + null, + [ + Validators.required, + Validators.maxLength(6), + Validators.minLength(6), + Validators.pattern('([\\d]){6,6}'), + this.blurTestPw + + ], + ], + passWordTo: [null, [this.confirmPasswordValidator, Validators.required, Validators.maxLength(6), Validators.minLength(6)]], + voucher: [null, [Validators.required]], + }); + } + + initStep1SF() { + this.step1Schema = { + properties: { + phone: { + title: '手机号', + type: 'string', + ui: { + widget: 'text', + defaultText: this.phone.toString(), + } as SFTextWidgetSchema, + }, + smsVerifyCode: { + type: 'string', + title: '验证码', + ui: { + widget: 'custom', + errors: { + required: '请输入验证码', + }, + } as SFTextareaWidgetSchema, + }, + }, + required: ['smsVerifyCode'], + }; + + this.ui = { + '*': { spanLabelFixed: 90, grid: { span: 16, gutter: 4 } }, + }; + } + + nextStep() { + if (this.step1sf.valid) { + this.service.request(this.service.$api_get_verifyPhone, this.step1sf.value).subscribe((res) => { + if (res) { + this.formGroup3.patchValue(res, { onlySelf: true }); + this.step = 1; + this.count = 0; + clearInterval(this.interval$); + } + }); + } + } + + formSubmit() { + for (const i in this.formGroup3.controls) { + if (true) { + this.formGroup3.controls[i].markAsDirty(); + this.formGroup3.controls[i].updateValueAndValidity(); + } + } + + if (this.formGroup3.valid) { + const param = Object.assign({}, this.formGroup3.value); + this.service.http.post(this.service.$api_voucherUpdatePayPassword, param).subscribe((res) => { + if (res.success === true) { + this.step++; + setTimeout(() => { + // this.settingService.setUser({}); + // // 清空路由复用信息 + // this.reuseTabService.clear(); + // // 设置用户Token信息 + // this.tokenService.clear(); + this.router.navigate(['/account/center']); + }, 3000); + } + }); + } + } + + getMsgCode() { + if (this.phone) { + this.getCode(`${this.service.$api_get_msg_code}`); + } else { + this.service.request(this.service.$api_get_current_user_info).subscribe((res) => { + this.phone = res.phone; + this.getCode(`${this.service.$api_get_msg_code}`); + }); + } + } + goBack() { + window.history.go(-1); + } + getCode(url: string, params?: any) { + this.service.http.post(url, null, params).subscribe((res) => { + // code==503046 弹出网易盾 + if (res.success && res.data.code === '1') { + this.service.msgSrv.success('发送成功'); + this.codeCountDown(); + } else if (res.data.code === '503046') { + this.dun.popUp(); + } else { + this.service.msgSrv.success(res.sendResult); + } + }); + } + /* code倒计时 */ + codeCountDown() { + this.count = 59; + this.interval$ = setInterval(() => { + this.count -= 1; + if (this.count <= 0) { + clearInterval(this.interval$); + } + }, 1000); + } + /* 网易盾验证通过 */ + captchaDone(validate: any) { + this.codeCountDown(); + } + + validateConfirmPassword(): void { + + setTimeout(() => this.formGroup3.controls.passWordTo.updateValueAndValidity()); + } + // blurTestPw(){ + // const reg = /[^\d]/g + // const val: any = this.formGroup3.controls.passWord.value + // if(val.length === 6) { + // const pattern = /([\d])\1{2,}/g + // const pattern2 = /(?:(?:0(?=1)|1(?=2)|2(?=3)|3(?=4)|4(?=5)|5(?=6)|6(?=7)|7(?=8)|8(?=9)){5}|(?:9(?=8)|8(?=7)|7(?=6)|6(?=5)|5(?=4)|4(?=3)|3(?=2)|2(?=1)|1(?=0)){5})\d/g + // if(pattern.test(val) || pattern2.test(val)){ + // return false + // } else { + // return true + // } + // } else { + // return false + // } + // } + blurTestPw = (control: FormControl): { [s: string]: boolean } => { + if (!control.value) { + return { required: true }; + } else if (control.value.length === 6) { + const pattern = /([\d])\1{2,}/g + const pattern2 = /(?:(?:0(?=1)|1(?=2)|2(?=3)|3(?=4)|4(?=5)|5(?=6)|6(?=7)|7(?=8)|8(?=9)){5}|(?:9(?=8)|8(?=7)|7(?=6)|6(?=5)|5(?=4)|4(?=3)|3(?=2)|2(?=1)|1(?=0)){5})\d/g + if(pattern.test(control.value) || pattern2.test(control.value)){ + return { confirm: true, error: true }; + } + } + return {}; + }; +} diff --git a/src/app/routes/account/services/account.service.ts b/src/app/routes/account/services/account.service.ts index 69608398..a7911ee7 100644 --- a/src/app/routes/account/services/account.service.ts +++ b/src/app/routes/account/services/account.service.ts @@ -36,6 +36,15 @@ export class AccountService extends BaseService { $api_set_voucherUpdatePhone = `/api/mdc/cuc/userBasicInfo/forgetPassword/voucherUpdatePhone`; // 凭证修改密码 $api_set_phoneUpdatePassword = `/api/mdc/cuc/userBasicInfo/phoneUpdatePassword`; + // 凭证修改设置身份密码 + $api_voucherUpdatePayPassword = '/api/mdc/cuc/userVerify/forgetPassword/voucherUpdatePassword'; + // 根据当前登录用户绑定的手机号码获取短信验证码 + public $api_get_msg_code = `/api/mdc/pbc/smsSend/getSmVerificationCodeByToken`; + // 用户下默认企业项目 + $api_getUserDefaultEnterpriseProject = '/api/mdc/cuc/enterpriseProject/getUserDefaultEnterpriseProject'; + // 当前登录用户是否设置用户验证密码 + $api_isUserVerifyPassword = '/api/mdc/cuc/userVerify/isUserVerifyPassword'; + constructor(public injector: Injector) { super(injector); } diff --git a/src/app/routes/sys-setting/components/sms-template/sms-template.component.html b/src/app/routes/sys-setting/components/sms-template/sms-template.component.html index dbe3cff1..2b413ab5 100644 --- a/src/app/routes/sys-setting/components/sms-template/sms-template.component.html +++ b/src/app/routes/sys-setting/components/sms-template/sms-template.component.html @@ -24,7 +24,7 @@ - + diff --git a/src/app/routes/sys-setting/components/sms-template/sms-template.component.ts b/src/app/routes/sys-setting/components/sms-template/sms-template.component.ts index 00a68bbe..43d1df9c 100644 --- a/src/app/routes/sys-setting/components/sms-template/sms-template.component.ts +++ b/src/app/routes/sys-setting/components/sms-template/sms-template.component.ts @@ -1,5 +1,5 @@ -import { Component, OnInit, ViewChild } from '@angular/core'; +import { AfterViewInit, ChangeDetectorRef, Component, OnInit, ViewChild } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { STColumn, STComponent, STRequestOptions } from '@delon/abc/st'; import { SFComponent, SFSchema } from '@delon/form'; @@ -18,11 +18,12 @@ export class SmsTemplateComponent implements OnInit { sf!: SFComponent; @ViewChild('sfEdit', { static: false }) sfEdit!: SFComponent; + editSchema!: SFSchema; visible = false; isVisible = false; tempData = {}; isEdit = false; - + searchSchema: SFSchema = { properties: { templateName: { @@ -43,24 +44,27 @@ export class SmsTemplateComponent implements OnInit { } }; - editSchema: SFSchema = { - properties: { - templateName: { - type: 'string', - title: '模板名称', - ui: { placeholder: '请输入模板名称' } + initSF() { + this.editSchema = { + properties: { + templateName: { + type: 'string', + title: '模板名称', + ui: { placeholder: '请输入模板名称', errors: { require: '必填项'} } + }, + templateCode: { + type: 'string', + title: '模板编码', + readOnly: this.isEdit, + ui: { placeholder: '请输入模板编码', errors: { require: '必填项'} } + }, + templateContent: { + type: 'string', + title: '模板内容', + ui: { placeholder: '请输入模板内容', errors: { require: '必填项'} } + } }, - templateCode: { - type: 'string', - title: '模板编码', - readOnly: this.isEdit, - ui: { placeholder: '请输入模板编码', } - }, - templateContent: { - type: 'string', - title: '模板内容', - ui: { placeholder: '请输入模板内容' } - } + required: ['templateName','templateCode','templateContent'] } } @@ -91,7 +95,9 @@ export class SmsTemplateComponent implements OnInit { constructor(public service: SystemService, private nzModalService: NzModalService, private route: ActivatedRoute) { } - ngOnInit(): void { } + ngOnInit(): void { + this.initSF(); + } beforeReq = (requestOptions: STRequestOptions) => { if (this.sf) { @@ -132,7 +138,7 @@ export class SmsTemplateComponent implements OnInit { handleOk(): void { const value = this.sfEdit.value; - const { id, templateCode, templateName, templateContent } = value + const { id, templateCode, templateName, templateContent } = value; const params = { id, templateCode, diff --git a/src/app/routes/tax-management/components/invoice-reporting/invoice-reporting.component.html b/src/app/routes/tax-management/components/invoice-reporting/invoice-reporting.component.html index d308c5e6..010dee32 100644 --- a/src/app/routes/tax-management/components/invoice-reporting/invoice-reporting.component.html +++ b/src/app/routes/tax-management/components/invoice-reporting/invoice-reporting.component.html @@ -53,6 +53,6 @@ {{ selectedRows.length }} 条数据 - + diff --git a/src/app/routes/tax-management/components/invoice-reporting/invoice-reporting.component.ts b/src/app/routes/tax-management/components/invoice-reporting/invoice-reporting.component.ts index 0ecf8e6f..49955f8a 100644 --- a/src/app/routes/tax-management/components/invoice-reporting/invoice-reporting.component.ts +++ b/src/app/routes/tax-management/components/invoice-reporting/invoice-reporting.component.ts @@ -217,7 +217,7 @@ export class TaxManagementInvoiceReportingComponent implements OnInit { width: '150px', type: 'link', click: item => { - window.open(`/#/ticket/invoice-list/detail/${item.invoiceno}`, '_blank', 'noopener') + window.open(`/#/ticket/invoice-list/detail/${item.vatinvHId}?type=${item.invoiceType}`, '_blank', 'noopener') } }, { title: '发票代码', index: 'invoiceno2', className: 'text-center', width: '150px', }, diff --git a/src/app/shared/components/captcha/captcha.module.ts b/src/app/shared/components/captcha/captcha.module.ts new file mode 100644 index 00000000..9ed79a1c --- /dev/null +++ b/src/app/shared/components/captcha/captcha.module.ts @@ -0,0 +1,11 @@ +import { NgModule } from '@angular/core'; + +import { CaptchaComponent } from './captcha.component'; + +const COMPONENTS = [CaptchaComponent]; + +@NgModule({ + declarations: COMPONENTS, + exports: COMPONENTS +}) +export class CaptchaModule {} diff --git a/src/app/shared/components/captcha/index.ts b/src/app/shared/components/captcha/index.ts index b2c67294..b1fe7443 100644 --- a/src/app/shared/components/captcha/index.ts +++ b/src/app/shared/components/captcha/index.ts @@ -1,2 +1,3 @@ export * from './captcha.component'; export * from './dun.helper'; +export * from './captcha.module'; diff --git a/src/app/shared/shared-third.module.ts b/src/app/shared/shared-third.module.ts index e8a2dec2..f3a7b8a7 100644 --- a/src/app/shared/shared-third.module.ts +++ b/src/app/shared/shared-third.module.ts @@ -5,6 +5,7 @@ import { apiConf } from '@conf/api.conf'; import { NgxTinymceModule } from 'ngx-tinymce'; import { environment } from '@env/environment'; + const TinyMce = NgxTinymceModule.forRoot({ baseURL: 'assets/tinymce/', config: { diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index 51dd9bca..705f6cc8 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -37,6 +37,7 @@ import { ImageListModule } from './components/imagelist'; import { DictSelectComponent } from './components/dict-select'; import { PipeModule } from './pipes'; import { AccountDetailComponent } from './components/account-detail/account-detail.component'; +import { CaptchaModule } from './components/captcha'; import { rebateTableModule } from './components/rebate-table'; const MODULES = [ @@ -53,6 +54,7 @@ const MODULES = [ ImageListModule, PipeModule, rebateTableModule, + CaptchaModule, ...PRO_SHARED_MODULES ]; // #endregion