buli
2022-03-11 379686996b011828cd7a44a96ee68408b4d267ec
Merge branch 'PIPLFunctionStage20220310'
78个文件已修改
178个文件已添加
23785 ■■■■ 已修改文件
.vim-force.com/session.properties 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/aura/AgencyAccount/AgencyAccount.cmp 32 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/aura/AgencyAccount/AgencyAccount.css 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/aura/AgencyAccount/AgencyAccountController.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/aura/AgencyAccount/AgencyAccountHelper.js 132 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/aura/NewAgencyContact/NewAgencyContact.cmp 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/aura/NewAgencyContact/NewAgencyContact.cmp-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/aura/NewAgencyContact/NewAgencyContact.css 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/aura/NewAgencyContact/NewAgencyContactController.js 217 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/aura/NewAgencyContact/NewAgencyContactHelper.js 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/aura/WeeklyReport/WeeklyReport.cmp 36 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/aura/WeeklyReport/WeeklyReport.css 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/aura/WeeklyReport/WeeklyReportController.js 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/aura/WeeklyReport/WeeklyReportHelper.js 366 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/AWSServiceTool.cls 48 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/AgencyAccountCmp.cls 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/AgencyContactHandler.cls 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/AssessmentReportController.cls 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/B_Test.cls 161 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/B_Test.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/BmeWorkController.cls 255 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/CM_SearchContact.cls 66 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/CM_SearchContactServiceController.cls 66 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/CampaignMemberController.cls 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/CampaignMemberServiceController.cls 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/ConsumFixtureSetSelectController.cls 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/ConsumReassignController.cls 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/ConsumTrialController.cls 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/ConsumTrialPDFController.cls 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/ControllerResponse.cls 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/ControllerResponse.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/DeleteBatch.cls 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/DeleteBatch.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/DeveloperUtility.cls 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/DeveloperUtility.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/FieldInfo.cls 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/FieldInfo.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/FileUploadController.cls 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/FileUploadController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/FixtureRentalPDFController.cls 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/InsReportPDFController.cls 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/InstructReportController.cls 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/LayoutDescriberHelper.cls 76 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/LeadIntentionController.cls 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/LightningUtil.cls 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/MetaDataUtility.cls 177 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/MetaDataUtility.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NFM103Controller.cls 31 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NFM203Rest.cls 119 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NFM501Controller.cls 46 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NFM501FutureController.cls 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NFM502Controller.cls 195 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NFM503InfoFileBatch.cls 184 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NFM606Controller.cls 42 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NFM607Rest.cls 52 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NFM612Rest.cls 27 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NFM620Rest.cls 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NFM623Rest.cls 49 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NFM624Rest.cls 56 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NFM702Controller.cls 65 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NFM702ControllerHandler.cls 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NFM702ControllerHandler.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NFMUtil.cls 184 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAgencyContactController.cls 124 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAgencyContactController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditASEActivityController.cls 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditASEActivityController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditAddressController.cls 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditAgencyContactController.cls 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditAgencyContactController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditBaseController.cls 260 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditBaseController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditCampaignMemberController.cls 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditCampaignMemberController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditCaseController.cls 146 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditCaseController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditContactController.cls 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditContactController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditEventController.cls 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditEventController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditInquiryFormController.cls 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditInquiryFormController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditInspectionReportController.cls 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditInspectionReportController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditLeadController.cls 123 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditQISController.cls 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditQISController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditRepairSubOrderController.cls 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditRepairSubOrderController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditReportController.cls 160 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditReportController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditTenderinformationController.cls 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditTenderinformationController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewConsumApplyController.cls 139 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewConsumApplyController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewConsumApplyEquipSetDetailController.cls 125 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewConsumApplyEquipSetDetailController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewListOfConsumablesController.cls 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewListOfConsumablesController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewRepairController.cls 148 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewRepairController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/OFSInsReportLayoutController.cls 32 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/OnCallController.cls 129 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/OnCallController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/Option.cls 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/Option.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/PIHelper.cls 216 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/PIHelper.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/QISPDFController.cls 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/RentalApplyController.cls 153 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/RentalApplyController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/SLAReportDetailsController.cls 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/SObjectHelper.cls 445 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/SObjectHelper.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/SearchContactController.cls 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/SearchContactController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/SearchLeadController.cls 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/SearchLeadController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/SearchVisitorController.cls 60 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/SimpleEventRegisterController.cls 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/SoqlHelper.cls 136 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/SoqlHelper.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/StartTradingController.cls 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/StartTradingController.cls-meta.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/StraightBackAddressController.cls 58 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/TestClass.cls 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/TestClass.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/TestController.cls 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/TestController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/UpdateContractAimAmountHandler.cls 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/ViewParticipantsController.cls 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/ViewParticipantsController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/WeeklyReportCmp.cls 130 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/XinDailyReportController.cls 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/AssessmentReport.page 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/BMEWorkPage.page 194 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/B_Test.page 304 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/B_Test.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/CM_SearchContact.page 279 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/CM_SearchContactService.page 199 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/CampaignMember.page 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/CampaignMemberService.page 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ConsumApplyUploadPdf.page 190 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ConsumApplyUploadPdf.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ConsumReassign.page 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ConsumTrial.page 915 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ConsumTrialPDF.page 168 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/FixtureRentalPDF.page 792 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/InsReportPDF.page 125 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/InstructReport.page 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/LeadIntention.page 1245 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditASEActivity.page 526 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditASEActivity.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditAddress.page 427 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditAddress.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditAgencyContact.page 511 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditAgencyContact.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditCampaignMember.page 421 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditCampaignMember.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditCase.page 442 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditCase.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditContact.page 485 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditContact.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditInquiryForm.page 607 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditInquiryForm.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditInspectionReport.page 436 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditInspectionReport.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditLead.page 560 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditQIS.page 558 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditQIS.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditRepairSubOrder.page 575 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditRepairSubOrder.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditReport.page 590 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditReport.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditTenderinformation.page 434 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditTenderinformation.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewConsumApply.page 402 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewConsumApply.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewConsumApplyEquipmentSetDetail.page 300 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewConsumApplyEquipmentSetDetail.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewListOfConsumables.page 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewListOfConsumables.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewOnCall.page 298 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewOnCall.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewRentalApply.page 387 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewRentalApply.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewRepair.page 327 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewRepair.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewRepairPage.page 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewRepairPage.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/OFSInsReportLayout.page 169 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/QISPDF.page 198 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/RentalApplyUploadPdf.page 190 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/RentalApplyUploadPdf.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/SLAReportDetails.page 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/SearchContactPage.page 185 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/SearchContactPage.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/SearchLeadPage.page 185 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/SearchLeadPage.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/SearchVisitor.page 266 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/SimpleEventRegister.page 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/StartTrading.page 193 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/StraightBackAddress.page 479 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/TenderInformationUploadPdf.page 190 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/TenderInformationUploadPdf.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/TestClass.page 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/TestClass.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/TestVfPage.page 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/TestVfPage.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/UploadPdf.page 190 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/UploadPdf.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewASEActivityDecryptInfo.page 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewASEActivityDecryptInfo.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewAddressDecryptInfo.page 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewAddressDecryptInfo.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewAgencyContactDecryptInfo.page 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewAgencyContactDecryptInfo.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewCaseDecryptInfo.page 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewCaseDecryptInfo.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewConsumApplyEquipmentSetDetailDecrypt.page 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewConsumApplyEquipmentSetDetailDecrypt.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewContactDecryptInfo.page 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewContactDecryptInfo.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewDecryptConsumApply.page 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewDecryptConsumApply.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewEventDecryptInfo.page 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewEventDecryptInfo.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewInquiryFormDecryptInfo.page 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewInquiryFormDecryptInfo.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewInspectionReportDecryptInfo.page 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewInspectionReportDecryptInfo.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewLeadDecryptInfo.page 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewLeadDecryptInfo.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewListOfConsumablesDecrypt.page 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewListOfConsumablesDecrypt.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewOnCallDecrypt.page 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewOnCallDecrypt.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewParticipantsDecryptInfo.page 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewParticipantsDecryptInfo.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewQISReportDecryptInfo.page 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewQISReportDecryptInfo.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewRentalApplyDecrypt.page 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewRentalApplyDecrypt.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewRepairEncrypt.page 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewRepairEncrypt.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewRepairSubOrderDecryptInfo.page 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewRepairSubOrderDecryptInfo.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewReportDecryptInfo.page 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewReportDecryptInfo.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewTenderinformationDecryptInfo.page 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewTenderinformationDecryptInfo.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/XinDailyReport.page 80 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/triggers/ContactHpDeptUpd.trigger 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/triggers/FileAddressTrigger.trigger 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/triggers/FileAddressTrigger.trigger-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/triggers/Repair.trigger 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.vim-force.com/session.properties
force-app/main/default/aura/AgencyAccount/AgencyAccount.cmp
@@ -5,7 +5,12 @@
    <aura:attribute name="hosStr" type="String"/>
    <aura:attribute name="conStr" type="String"/>
    <aura:attribute name="filedsmap" type="Map"/>
    <aura:attribute name="awsdata" type="Map"/>
    <aura:attribute name="temp_aws_id" type="String"/>
    <aura:attribute name="staticResource" type="Map"/>
    <ltng:require scripts="{! $Resource.AWSService+'/AWSService.js' }" afterScriptsLoaded="{!c.scriptsLoaded}" />
    <aura:renderIf isTrue="{!v.login}">
        <div class="slds-spinner_container height100vh">
            <div class="slds-spinner--brand slds-spinner slds-spinner--medium" role="alert">
@@ -46,17 +51,17 @@
          <th scope="col" style = "width:5px;">
            <div class="slds-truncate" title="{!v.filedsmap.Hospital_Name__c}">{!v.filedsmap.Hospital_Name__c}</div>
          </th>
          <th scope="col">
          <th scope="col" style="width: 150px;">
            <div class="slds-truncate" title="{!v.filedsmap.Department_Cateogy_F__c}">{!v.filedsmap.Department_Cateogy_F__c}</div>
          </th>
          <!-- 精琢科技  zxk  SWAG-C8F8TU end -->
          <!-- <th scope="col">
            <div class="slds-truncate" title="{!v.filedsmap.Hospital_DC_Name__c}">{!v.filedsmap.Hospital_DC_Name__c}</div>
          </th> -->
          <th scope="col">
          <th scope="col" style="width: 150px;">
            <div class="slds-truncate" title="{!v.filedsmap.Type__c}">{!v.filedsmap.Type__c}</div>
          </th>
          <th scope="col">
          <th scope="col" style="width: 150px;">
            <div class="slds-truncate" title="{!v.filedsmap.Doctor_Division1__c}">{!v.filedsmap.Doctor_Division1__c}</div>
          </th>
          <th scope="col">
@@ -68,7 +73,14 @@
          <aura:iteration items="{!v.accounts}" var="item" indexVar="index">
        <tr>
          <th scope="row" data-label="Opportunity Name">
            <div class="slds-truncate" title="{!item.Name}"><a href="{!'/partner/s/agency-contact/' + item.Id}">{!item.Name}</a></div>
            <aura:set attribute="temp_aws_id" value="{! item.AWS_Data_Id__c }" />
            <div class="slds-truncate">
                <a href="{!'/partner/s/agency-contact/' + item.Id}" style="position: relative;">
                    <span class="encrypt">{!item.Name}</span>
                    <span class="decrypt">{!item.awsdata.name}</span>
                </a>
            </div>
          </th>
            <!-- 精琢科技  zxk  SWAG-C8F8TU start -->
             <td data-label="Account Name">
@@ -94,10 +106,16 @@
          </td> -->
          <td data-label="Close Date">
            <div class="slds-truncate" title="{!item.Type__c}">{!item.Type__c}</div>
            <div class="slds-truncate" title="{!item.Type__c}">
                <span class="encrypt">{!item.Type__c}</span>
                <span class="decrypt">{!item.awsdata.type}</span>
            </div>
          </td>
          <td data-label="Stage">
            <div class="slds-truncate" title="{!item.Doctor_Division1__c}">{!item.Doctor_Division1__c}</div>
            <div class="slds-truncate" title="{!item.Doctor_Division1__c}">
                <span class="encrypt">{!item.Doctor_Division1__c}</span>
                <span class="decrypt">{!item.awsdata.doctorDivision1}</span>
            </div>
          </td>
          <td data-label="IsOlympusContact__c">
            <ui:outputCheckbox value="{!item.IsOlympusContact__c}" />
force-app/main/default/aura/AgencyAccount/AgencyAccount.css
@@ -1,3 +1,21 @@
.THIS.contents_wrapper {
    padding-top: 10px;
}
.THIS tr .decrypt{
    /* position: absolute;
    top: 0;
    left: 100%;
    display: none;
    text-align: left;
    padding-left: 5px; */
    display: none;
}
.THIS tr:hover .decrypt{
    display: unset;
}
.THIS tr:hover .encrypt{
    display: none;
}
force-app/main/default/aura/AgencyAccount/AgencyAccountController.js
@@ -10,4 +10,8 @@
    clearContact: function(component, event, helper) {
        helper.clearContact(component, event, helper);
    },
    scriptsLoaded:function(component, event, helper) {
        // AWSService.logFun = helper.saveLog;
        // AWSService.component = component;
    }
})
force-app/main/default/aura/AgencyAccount/AgencyAccountHelper.js
@@ -1,12 +1,14 @@
({
    doinit : function(component, event, helper) {
        component.set('v.login',true);
        component.set("v.awsdata",{});
        var action = component.get("c.getfiledsmap");
        action.setCallback(this, function(response) {
            var state = response.getState();
            if(state === "SUCCESS") {
                var res = response.getReturnValue();
                component.set("v.filedsmap", res);
            } else if (state === "ERROR") {
                var errors = response.getError();
@@ -27,7 +29,11 @@
            if(state === "SUCCESS") {
                var acList = response.getReturnValue();
                component.set("v.accounts", acList);
                component.set('v.login',false);
                helper.Decrypt(component,helper,function(){
                    component.set('v.login',false);
                })
            } else if (state === "ERROR") {
                var errors = response.getError();
                var toastEvent = $A.get("e.force:showToast");
@@ -40,7 +46,31 @@
                component.set('v.login',false);
            }
        });
        $A.enqueueAction(action2);
        var action3 = component.get("c.GetConfig");
        action3.setCallback(this, function(response) {
            var state = response.getState();
            if(state === "SUCCESS") {
                var res = response.getReturnValue();
                //AWSService.sfSessionId = res.sessionId;
                component.set("v.staticResource",JSON.parse(res.staticResource));
                $A.enqueueAction(action2);
            } else if (state === "ERROR") {
                var errors = response.getError();
                var toastEvent = $A.get("e.force:showToast");
                toastEvent.setParams({
                    "title": "错误",
                    "type":"error",
                    "message": errors[0].message
                });
                toastEvent.fire();
            }
        });
        $A.enqueueAction(action3);
    },
    clearContact: function(component, event, helper) {
@@ -53,15 +83,17 @@
        component.set('v.login',true);
        var hosStr = component.get("v.hosStr");
        var conStr = component.get("v.conStr");
        var action = component.get("c.searchAccounts");
        action.setParams({"hosStr": hosStr, "conStr": conStr});
        var action = component.get("c.searchAccounts2");
        let awsdata = component.get("v.awsdata");
        let staticResource = component.get("v.staticResource");
        action.setCallback(this, function(response) {
            var state = response.getState();
            if(state === "SUCCESS") {
                var acList = response.getReturnValue();
                component.set("v.accounts", acList);
                component.set('v.login',false);
                helper.Decrypt(component,helper,function(){
                    component.set('v.login',false);
                })
            } else if (state === "ERROR") {
                var errors = response.getError();
                var toastEvent = $A.get("e.force:showToast");
@@ -74,6 +106,92 @@
                component.set('v.login',false);
            }
        });
        if (conStr) {
            AWSService.search(staticResource.searchUrl,JSON.stringify({
                "name":conStr
            }),function(data){
                $A.getCallback(function(){
                    let dataIds = [];
                    if(data.object && data.object.length > 0){
                        for(let d of data.object){
                            if(d.dataId){
                                dataIds.push(d.dataId);
                                awsdata[d.dataId] = d;
                            }
                        }
                    }
                    action.setParams({"hosStr": hosStr, awsids:dataIds});
                    $A.enqueueAction(action);
                })()
           },staticResource.token);
        }else{
            action.setParams({"hosStr": hosStr});
            $A.enqueueAction(action);
        }
    },
    Decrypt :function(component, helper, callback){
        let awsdata = component.get("v.awsdata");
        let need_query = [];
        let acList = component.get("v.accounts");
        let staticResource = component.get("v.staticResource");
        for (const acc of acList) {
            if(acc.AWS_Data_Id__c &&
                (!awsdata.hasOwnProperty(acc.AWS_Data_Id__c) || !awsdata[acc.AWS_Data_Id__c])
                ){
                need_query.push(acc.AWS_Data_Id__c);
            }
        }
        let Foo = function(){
            for (const acc of acList) {
                if(acc.AWS_Data_Id__c && awsdata.hasOwnProperty(acc.AWS_Data_Id__c)){
                    acc.awsdata = awsdata[acc.AWS_Data_Id__c];
                }
            }
            component.set("v.accounts", acList);
            if(callback)callback();
        }
        if(need_query.length>0){
            AWSService.search(staticResource.searchUrl,JSON.stringify({
                 "dataIds":need_query
                }),function(data){
                    $A.getCallback(function(){
                        if(data.object && data.object.length > 0){
                            for(let d of data.object){
                                if(d.dataId){
                                    awsdata[d.dataId] = d;
                                }
                            }
                        }
                        Foo();
                    })()
            },staticResource.token);
        }else{
            Foo();
        }
    },
    saveLog:function(component,module,url,request,response,status){
        var action = component.get("c.SaveLog");
        action.setParams({
            "module": hosStr,
            "content": content,
            "status": status,
            "respMsg": respMsg
            });
        $A.enqueueAction(action);
    }
})
force-app/main/default/aura/NewAgencyContact/NewAgencyContact.cmp
New file
@@ -0,0 +1,60 @@
<aura:component implements="force:lightningQuickActionWithoutHeader,force:hasRecordId,lightning:actionOverride,lightning:isUrlAddressable" access="global"
                controller="NewAgencyContactController">
    <aura:attribute name = "recordId" type = "Id" default = ""/>
    <aura:handler name="init" value="{!this}" action="{!c.doInit}" />
    <aura:attribute name="layout" type="LayoutDescriberHelper.LayoutWrapper"/>
    <aura:attribute name="record_data" type="Map"/>
    <aura:attribute name="section_names" type="List"/>
    <aura:attribute name="showSpinner" type="Boolean" default = "False"/>
    <aura:attribute name="staticResource" type="Map"/>
    <aura:attribute name="pi_fields_map" type="Map"/>
    <div class="{! v.container_class}">
        <!-- header -->
        <header class="slds-modal__header">
            <h2 id="modal-heading-01" class="slds-modal__title slds-hyphenate">
                Create Agency Contact
            </h2>
        </header>
        <div class="slds-modal__content slds-p-around_medium">
            <aura:if isTrue="{!v.showSpinner}">
                <lightning:spinner alternativeText="Loading" size="medium" />
            </aura:if>
            <lightning:recordEditForm objectApiName="Agency_Contact__c">
                <lightning:accordion activeSectionName="{! v.section_names }" allowMultipleSectionsOpen="true" class="greyyyy" >
                    <aura:iteration items="{!v.layout}" var="section">
                        <aura:if isTrue="{! section.editHeading }">
                            <lightning:accordionSection name="{! section.label }" label="{! section.label }">
                                <aura:iteration items="{! section.layoutColumns}" var="col">
                                    <aura:iteration items="{! col.layoutItems}" var="field">
                                        <aura:if isTrue="{! field.behavior != 'Readonly' }">
                                            <lightning:inputField required="{! field.behavior == 'Required' }" fieldName="{! field.field}" value="{! field.value}" />
                                        </aura:if>
                                    </aura:iteration>
                                </aura:iteration>
                            </lightning:accordionSection>
                        </aura:if>
                    </aura:iteration>
                </lightning:accordion>
            </lightning:recordEditForm>
            <div  style="text-align:center;margin: 5px;">
                <lightning:button class="slds-button slds-button_neutral" label="取消" onclick="{! c.cancelClick }" />
                <lightning:button class="slds-button slds-button_brand" variant="brand" label="保存" onclick="{! c.saveClick }" />
            </div>
        </div>
    </div>
</aura:component>
force-app/main/default/aura/NewAgencyContact/NewAgencyContact.cmp-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<AuraDefinitionBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <description>A Lightning Component Bundle</description>
</AuraDefinitionBundle>
force-app/main/default/aura/NewAgencyContact/NewAgencyContact.css
New file
@@ -0,0 +1,15 @@
.THIS {
}
.THIS .greyyyy .slds-button_reset{
 display: flex;
    align-items: center;
 background: var(--lwc-colorBackground,rgb(243, 242, 242));
 cursor: pointer;
    width: 100%;
    height: 2rem;
    text-align: left;
    color: currentColor;
    font-size: inherit;
    padding: 0 var(--lwc-spacingXSmall,0.5rem);
}
force-app/main/default/aura/NewAgencyContact/NewAgencyContactController.js
New file
@@ -0,0 +1,217 @@
({
    doInit : function(component, event, helper) {
        let rid = component.get('v.recordId');
        let pid = null;
        if(!rid){
            pid = window.location.href.replace("https://","").split("/")[4];
        }
        component.set("v.showSpinner", true);
        helper.CallBackAction(component,'Init',{
            rid : rid,
            pid : pid,
            //rid : component.get('v.recordId'),
            record_type_id : component.get("v.pageReference").state.recordTypeId,
        },function(data){
            component.set("v.showSpinner", false);
            if(data.getState() == "SUCCESS"){
                var rv = data.getReturnValue();
                console.log(rv);
                if(rv.IsSuccess){
                    let layout = JSON.parse(rv.Data.layout);
                    let fields = rv.Data.fields;
                    let staticResource = JSON.parse(rv.Data.staticResource)
                    let section_names = [];
                    section_names = layout.map(s=>s.label);
                    component.set('v.section_names',section_names);
                    let m = {};
                    for(let f of staticResource.PIDetails){
                        m[f.SF_Field_API_Name__c] = f;
                    }
                    component.set('v.pi_fields_map',m);
                    if(rv.Data && rv.Data.data && rv.Data.data.AWS_Data_Id__c){
                        helper.AwsGet(staticResource.queryUrl, {
                            dataId : rv.Data.data.AWS_Data_Id__c
                        }, function(data){
                            console.log('data = ' + data);
                            for(let f of staticResource.PIDetails){
                                if(data.object && data.object.hasOwnProperty(f.AWS_Field_API__c)){
                                    rv.Data.data[f.SF_Field_API_Name__c] = data.object[f.AWS_Field_API__c];
                                    if(data.object.hasOwnProperty(f.AWS_Encrypted_Field_API__c) && data.object[f.AWS_Encrypted_Field_API__c]){
                                        rv.Data.data[f.SF_Field_Encrypted_API__c] = data.object[f.AWS_Encrypted_Field_API__c];
                                    }
                                }
                            }
                            for(let s of layout){
                                for(let c of s.layoutColumns){
                                    for(let item of c.layoutItems){
                                        if(rv.Data.data.hasOwnProperty(item.field)){
                                            item.value = rv.Data.data[item.field];
                                        }
                                        if(fields.hasOwnProperty(item.field)){
                                            item.fi = fields[item.field];
                                        }
                                    }
                                }
                            }
                            component.set('v.record_data',rv.Data.data);
                            component.set('v.layout',layout);
                        }, staticResource.token);
                    }else{
                        for(let s of layout){
                            for(let c of s.layoutColumns){
                                for(let item of c.layoutItems){
                                    if(rv.Data && fields.hasOwnProperty(item.field) && fields[item.field].References && fields[item.field].References.map(m=>m.value).indexOf(rv.Data.pidType) > -1){
                                        item.value = pid;
                                    }
                                }
                            }
                        }
                        component.set('v.layout',layout);
                    }
                    component.set('v.fields',fields);
                    component.set('v.staticResource',staticResource);
                }else{
                    helper.ShowToast({
                        "message" : rv.Message,
                        "type" : "error"
                    });
                }
            }else{
                helper.ShowToast({
                    "message" : "Init error",
                    "type" : "error"
                });
            }
        });
    },
    saveClick : function(component, event, helper){
        let staticResource = component.get('v.staticResource');
        let record_id = component.get('v.recordId');
        let url = staticResource.newUrl;
        let payloadPi = {};
        if (record_id) {
            url = staticResource.updateUrl
            payloadPi['dataId'] = component.get('v.record_data').AWS_Data_Id__c;
        }
        let layout = component.get('v.layout');
        let pi_fields_map = component.get('v.pi_fields_map');
        for(let s of layout){
            for(let c of s.layoutColumns){
                for(let item of c.layoutItems){
                    if(pi_fields_map.hasOwnProperty(item.field)){
                        payloadPi[pi_fields_map[item.field].AWS_Field_API__c] = item.value;
                    }
                }
            }
        }
        component.set("v.showSpinner", true);
        helper.AwsPost(url, [payloadPi], function(result){
            let obj = result.object[0];
            let data = {};
            if(record_id){
                data.Id = record_id;
            }else{
                data.AWS_Data_Id__c = obj.dataId;
            }
            for(let s of layout){
                for(let c of s.layoutColumns){
                    for(let item of c.layoutItems){
                        if(item.field && item.behavior != "Readonly"){
                            if(pi_fields_map.hasOwnProperty(item.field)){
                                data[item.field] = obj[pi_fields_map[item.field].AWS_Field_API__c];
                                data[pi_fields_map[item.field].SF_Field_Encrypted_API__c] = obj[pi_fields_map[item.field].AWS_Encrypted_Field_API__c];
                            }else{
                                data[item.field] = item.value;
                            }
                        }
                    }
                }
            }
            $A.getCallback(function(){
                helper.CallBackAction(component,'Save',{
                    data : data,
                    transId : result.txId
                },function(data){
                    component.set("v.showSpinner", false);
                    if(data.getState() == "SUCCESS"){
                        var rv = data.getReturnValue();
                        console.log(rv);
                        var sfId = rv.Data.recordId;
                        helper.AwsPost(staticResource.transactionUrl,{
                            txId: result.txId,
                            sfRecordId:sfId,
                            isSuccess: rv.IsSuccess ? 1 : 0
                        },function(data){
                            if(rv.IsSuccess){
                                helper.ShowToast({
                                    "message" : "成功",
                                    "type" : "success"
                                });
                                if (record_id){
                                    $A.get("e.force:closeQuickAction").fire();
                                    $A.get('e.force:refreshView').fire();
                                }else{
                                    var sObjectEvent = $A.get("e.force:navigateToSObject");
                                    sObjectEvent.setParams({
                                        "recordId": sfId
                                    })
                                    sObjectEvent.fire();
                                }
                            }else{
                                helper.ShowToast({
                                    "message" : rv.Message,
                                    "type" : "error"
                                });
                            }
                        },staticResource.token);
                    }else{
                        helper.ShowToast({
                            "message" : "Init error",
                            "type" : "error"
                        });
                    }
                });
            })();
        }, staticResource.token);
    },
    cancelClick : function(component, event, helper){
        $A.get("e.force:closeQuickAction").fire();
    },
    scriptsLoaded : function(component, event, helper){}
})
force-app/main/default/aura/NewAgencyContact/NewAgencyContactHelper.js
New file
@@ -0,0 +1,77 @@
({
    CallBackAction  : function(component,action_name,para,callback) {
        var action = component.get("c." + action_name.trimStart().replace("c.",""));
        if(para){
            action.setParams(para);
        }
        if(callback){
            action.setCallback(this,function(data){
                callback(data);
            });
        }
        $A.enqueueAction(action);
    },
    ShowToast : function(paras){
        var toastEvent = $A.get("e.force:showToast");
        toastEvent.setParams(paras);
        toastEvent.fire();
    },
    AwsPost : function(postURL, data ,callback,token){
        let payloadForNewPI = '';
        if(typeof(data) == 'string'){
            payloadForNewPI = data;
        }else{
            payloadForNewPI = JSON.stringify(data);
        }
        fetch(postURL, {
            method: 'POST',
            body: payloadForNewPI,
            headers: {
                'Content-Type': 'application/json',
                'pi-token': token
            }
        }).then((data) => {
            console.log('data=' + JSON.stringify(data));
            return data.json();
        }).then((result) => {
            //this.insertCalloutLog(this.insertModule,postURL,JSON.stringify(payloadForNewPI),JSON.stringify(result),this.successStatus);
            if(callback) callback(result);
        }).catch(error => {
            console.log('error');
            //this.insertCalloutLog(this.insertModule,postURL,JSON.stringify(payloadForNewPI),JSON.stringify(error),this.failStatus);
            console.log(error);
        });
    },
    AwsGet : function(url, data ,callback,token){
        if(typeof(data) == 'string'){
            url += data;
        }else{
            let i = 0;
            for(let p in data){
                url += (i++) ? '&' : '?';
                url += p + '=' + data[p];
            }
        }
        fetch(url, {
            method: 'GET',
            headers: {
                'Content-Type': 'application/json',
                'pi-token': token
            }
        }).then((data) => {
            console.log('data=' + JSON.stringify(data));
            return data.json();
        }).then((result) => {
            //this.insertCalloutLog(this.insertModule,postURL,JSON.stringify(payloadForNewPI),JSON.stringify(result),this.successStatus);
            if(callback) callback(result);
        }).catch(error => {
            console.log('error');
            //this.insertCalloutLog(this.insertModule,postURL,JSON.stringify(payloadForNewPI),JSON.stringify(error),this.failStatus);
            console.log(error);
        });
    }
})
force-app/main/default/aura/WeeklyReport/WeeklyReport.cmp
@@ -71,6 +71,14 @@
    <!-- It will display 100 records . Change for your requirement-->
    <aura:attribute name="NumOfRecords" type="Integer" default="1000"/> 
    <aura:attribute name="showMain" type="Boolean" default="true"/>
    <!-- PIPL update Yin Mingjie 21/02/2022 start -->
    <aura:attribute name="AWStoken" type="String"/>
    <aura:attribute name="AWSsearch" type="String"/>
    <aura:attribute name="AWSinsert" type="String"/>
    <aura:attribute name="AWStransactionURL" type="String"/>
    <aura:attribute name="AWSDoctor2Map" type="String"/>
    <aura:attribute name="awsurl" type="Map"/>
    <!-- PIPL update Yin Mingjie 21/02/2022 end -->
    <!-- 批量添加周报 end-->
    
@@ -135,7 +143,7 @@
                            <span class="slds-truncate" title="Name">{!v.fieldsmap.Department_Cateogy__c}</span>
                        </th>
                        <th class="table_header slds-text-title--caps">
                            <span class="slds-truncate" title="Name">{!v.fieldsmap.doctor2__c}</span>
                            <span class="slds-truncate" title="Name">{!v.fieldsmap.doctor2__r}</span>
                        </th>
                        <th class="table_header slds-text-title--caps">
                            <span class="slds-truncate" title="Name">{!v.fieldsmap.visitor_title__c}</span>
@@ -169,12 +177,18 @@
                            </td>
                            <td role="gridcell" class="slds-cell-edit">
                                <span class="slds-grid slds-grid--align-spread">
                                    <span class="slds-truncate" title="{!item.doctor2__r.Name}">{!item.doctor2__r.Name}</span>
                                    <span class="slds-truncate" title="{!item.doctor2__r.Name}">
                                        <span class="encrypt">{!item.doctor2__r.Name}</span>
                                        <span class="decrypt">{!item.doctor2__r.awsdata.name}</span>
                                    </span>
                                </span>
                            </td>
                            <td role="gridcell" class="slds-cell-edit">
                                <span class="slds-grid slds-grid--align-spread">
                                    <span class="slds-truncate" title="{!item.visitor_title__c}">{!item.visitor_title__c}</span>
                                    <span class="slds-truncate" title="{!item.visitor_title__c}">
                                        <span class="encrypt">{!item.visitor_title__c}</span>
                                        <span class="decrypt">{!item.doctor2__r.awsdata.doctorDivision1}</span>
                                    </span>
                                </span>
                            </td>
                            <td role="gridcell" class="slds-cell-edit">
@@ -342,7 +356,7 @@
                        <div class="slds-p-horizontal--small slds-size--1-of-1 slds-medium-size--1-of-5 slds-large-size--1-of-8">
                            {!v.fieldsmap.visitor_title__c}
                            <div>{!v.doctor_title}</div>
                        </div>
                        </div>
                        <!-- 活动区分 -->
                        <div class="slds-p-horizontal--small slds-size--1-of-1 slds-medium-size--1-of-5 slds-large-size--1-of-6">
                            {!v.fieldsmap.Purpose_Type__c}
@@ -409,7 +423,7 @@
                            <!-- <force:inputField value="{!v.data.Product_Category3__c}" aura:id="input-product-category3"/> -->
                            <ui:inputSelect aura:id="select_Product3" class="slds-select" change="{!c.productcategoryChange3}"/>
                        </div>
                        <!--SWAG-CBX68C fy 【委托】DAMS系统周报模块内容需求增加 start-->
                         <!--SWAG-CBX68C fy 【委托】DAMS系统周报模块内容需求增加 start-->
                        <!-- 支援需求 -->
                        <div class="slds-p-horizontal--small slds-size--1-of-1 slds-medium-size--1-of-5 slds-large-size--1-of-6">
                            {!v.fieldsmap.SupportNeeds__c}
@@ -473,12 +487,18 @@
                                            </td>
                                            <td role="gridcell" class="slds-cell-edit">
                                                <span class="slds-grid slds-grid--align-spread">
                                                    <span class="slds-truncate" title="{!item.doctor2__r.Name}">{!item.doctor2__r.Name}</span>
                                                    <span class="slds-truncate" title="{!item.doctor2__r.Name}">
                                                        <span class="encrypt">{!item.doctor2__r.Name}</span>
                                                        <span class="decrypt">{!item.doctor2NameOrigin}</span>
                                                    </span>
                                                </span>
                                            </td>
                                            <td role="gridcell" class="slds-cell-edit">
                                                <span class="slds-grid slds-grid--align-spread">
                                                    <span class="slds-truncate" title="{!item.visitor_title__c}">{!item.visitor_title__c}</span>
                                                    <span class="slds-truncate" title="{!item.visitor_title__c}">
                                                        <span class="encrypt">{!item.visitor_title__c}</span>
                                                        <span class="decrypt">{!item.visitorTitleOrigin}</span>
                                                    </span>
                                                </span>
                                            </td>
                                            <td role="gridcell" class="slds-cell-edit">
@@ -524,7 +544,7 @@
                    <lightning:messages aura:id="OppMessage" />
                    <!-- onload="{!c.showRequiredFields}" -->
                    <aura:renderIf isTrue="{!v.truthy}">
                        <lightning:inputField fieldName="Name"/>
                        <lightning:inputField fieldName="Name" aura:id="newOpportunityField" />
                        <lightning:inputField fieldName="Type__c" aura:id="newOpportunityField" />
                        <lightning:inputField fieldName="Doctor_Division1__c" aura:id="newOpportunityField" />
                        <!-- <lightning:inputField class="customRequired none" aura:id="Input_type__c" fieldName="Type__c"/>
force-app/main/default/aura/WeeklyReport/WeeklyReport.css
@@ -126,4 +126,16 @@
.THIS .none{
     display:none; 
}
.THIS tr .decrypt{
    display: none;
}
.THIS tr:hover .decrypt{
    display: unset;
}
.THIS tr:hover .encrypt{
    display: none;
}
force-app/main/default/aura/WeeklyReport/WeeklyReportController.js
@@ -63,7 +63,11 @@
        var vaildationFailReason = '';
        // var vaildationFailReason2 = '';
        // var currentDate = new Date().toJSON().slice(0,10);
        // PIPL update Yin Mingjie 21/02/2022 start
        let agencyReport = Object.create(null);
        // PIPL update Yin Mingjie 21/02/2022 end
        fields.forEach(function (field) {
            if(field.get("v.fieldName") === 'Type__c' && $A.util.isEmpty(field.get("v.value"))){
                showValidationError = true;
@@ -77,19 +81,45 @@
                }
                
            }
            // PIPL update Yin Mingjie 21/02/2022 start
            if(field.get("v.fieldName") === 'Name'){
                agencyReport['name'] = field.get("v.value");
            }else if(field.get("v.fieldName") === 'Type__c'){
                agencyReport['type'] = field.get("v.value");
            }else if(field.get("v.fieldName") === 'Doctor_Division1__c'){
                agencyReport['doctorDivision1'] = field.get("v.value");
            }
            // PIPL update Yin Mingjie 21/02/2022 end
        });
         
        if (!showValidationError) {
            // PIPL update Yin Mingjie 21/02/2022 start
            /*
            var eventFields = event.getParam("fields");
            eventFields["Agency_Hospital__c"] = component.get('v.hospitalLinkId');
            component.find('recordEditForm').submit(eventFields);
            */
            var agencyHospitalid = component.get('v.hospitalLinkId');
            var arr = new Array();
            arr.push(agencyReport);
            var data = JSON.stringify(arr);
            // helper.set_aws_url(component,data,agencyHospitalid);
            var token = component.get('v.AWStoken');
            var newUrl = component.get('v.AWSinsert');
            component.set('v.login',true);
            helper.insert_agencycontact(component,token,newUrl,data,agencyHospitalid,helper);
            // PIPL update Yin Mingjie 21/02/2022 end
        }else{
            component.find('OppMessage').setError(vaildationFailReason);
        }
        // var eventFields = event.getParam("fields");
        // eventFields["Agency_Hospital__c"] = component.get('v.hospitalLinkId');
        // component.find('recordEditForm').submit(eventFields);
         // vivek 添加验证 end
        // vivek 添加验证 end
    },
    
    createCancel : function(component, event, helper) {
force-app/main/default/aura/WeeklyReport/WeeklyReportHelper.js
@@ -17,11 +17,12 @@
                component.find('select_purpose_type').set('v.options', this.conv_selected(res.allselectlist.Purpose_Type__c));
                component.find('select_result').set('v.options', this.conv_selected(res.allselectlist.Result__c));
                component.find('select_stageName').set('v.options', this.conv_selected(res.allselectlist.StageName__c));
                //SWAG-CBX68C fy 【委托】DAMS系统周报模块内容需求增加 start
                component.find('SupportNeeds__c').set('v.options', this.conv_selected(res.allselectlist.SupportNeeds__c));
                //SWAG-CBX68C fy 【委托】DAMS系统周报模块内容需求增加 end
                 //SWAG-CBX68C fy 【委托】DAMS系统周报模块内容需求增加 start
                 component.find('SupportNeeds__c').set('v.options', this.conv_selected(res.allselectlist.SupportNeeds__c));
                 //SWAG-CBX68C fy 【委托】DAMS系统周报模块内容需求增加 end
                component.set('v.selected_agency_person', res.allselectlist.AgencyPerson__c[0].label);
                component.set('v.dialog_type', '新建');
                component.set('v.awsurl', res.awsurl);// 20220222 PI改造 by Bright
                
                this.get_reports(component, event, helper, component.find('select_date').get('v.value'), component.find('select_agency_person').get('v.value'));
                
@@ -95,6 +96,38 @@
            if(state == 'SUCCESS'){
                var res = response.getReturnValue();
                component.set('v.reports', res.reports);
                // 20220222 PI改造 by Bright--start
                let dataIds = [];
                for (const rep of res.reports) {
                    if (rep.doctor2__r && rep.doctor2__r.AWS_Data_Id__c) {
                        dataIds.push(rep.doctor2__r.AWS_Data_Id__c);
                    }
                }
                if(dataIds.length > 0){
                    let awsurl = component.get('v.awsurl');
                    helper.search_agency_contact_core(awsurl.token,awsurl.searchUrl,JSON.stringify({
                        "dataIds":dataIds
                    }),(result)=>{
                        if(result.status == '0'){
                            let mm = {};
                            for (const m of result.object) {
                                mm[m.dataId] = m;
                            }
                            for (const rep of res.reports) {
                                if (rep.doctor2__r && rep.doctor2__r.AWS_Data_Id__c && mm.hasOwnProperty(rep.doctor2__r.AWS_Data_Id__c)) {
                                    rep.doctor2__r.awsdata = mm[rep.doctor2__r.AWS_Data_Id__c];
                                }
                            }
                            component.set('v.reports', res.reports);
                        }else{
                            this.error('AWS search status : ' + result.status);
                        }
                    },component);
                }
                // 20220222 PI改造 by Bright--end
                component.set('v.report_count', res.reports.length);
                // 更新保存後のselect_data用
@@ -276,9 +309,9 @@
                    if (reportDate != null) {
                        component.set('v.data.Report_Date__c', reportDate);
                    }
                        component.set('v.edit_copy_select_report_id', "");
                    }
                    component.set('v.edit_copy_select_report_id', "");
                }
            }
        } else {
            // CLOSE
@@ -422,6 +455,9 @@
        component.set('v.selected_date', select_date);
        var name = component.get('v.selected_agency_person');
        var ret = this.create_report_header(component, name, select_agency, select_date);
        // PIPL update Yin Mingjie 21/02/2022 start
        this.set_aws_url(component)
        // PIPL update Yin Mingjie 21/02/2022 end
    },
    
    copy_button : function(component, event, helper) {
@@ -491,6 +527,19 @@
    },
    
    save_report : function(component, event, helper) {
        // 20220222 PI改造  by Bright--start
        let doctor2Name = '';
        let visitortitle = '';
        for(let op of component.find('select_doctor').get('v.options')){
            if (op.selected) {
                doctor2Name = op.label;
                visitortitle = op.Doctor_Division1__c;
            }
        }
        // 20220222 PI改造  by Bright--end
        component.find('save_button').set('v.disabled', true);
        var Report_Date__c = component.get('v.data.Report_Date__c');
@@ -527,7 +576,7 @@
        
        // 活动区分 Purpose_Type__c
        var Purpose_Type__c = component.find('select_purpose_type').get('v.value');
        //SWAG-CBX68C fy 【委托】DAMS系统周报模块内容需求增加 start
          //SWAG-CBX68C fy 【委托】DAMS系统周报模块内容需求增加 start
        // 支援需求 SupportNeeds__c
        var SupportNeeds__c = component.find('SupportNeeds__c').get('v.value');
        //SWAG-CBX68C fy 【委托】DAMS系统周报模块内容需求增加 end
@@ -604,9 +653,9 @@
                "Agency_Report_Id" : Agency_Report__c,
                "Department_Cateogy" : Department_Cateogy__c,
                "Purpose_Type" : Purpose_Type__c,
                //SWAG-CBX68C fy 【委托】DAMS系统周报模块内容需求增加 start
                "SupportNeedsc" : SupportNeeds__c,
                //SWAG-CBX68C fy 【委托】DAMS系统周报模块内容需求增加 end
                 //SWAG-CBX68C fy 【委托】DAMS系统周报模块内容需求增加 start
                 "SupportNeedsc" : SupportNeeds__c,
                 //SWAG-CBX68C fy 【委托】DAMS系统周报模块内容需求增加 end
                "Agency_Report_Header" : Agency_Report_Header__c,
                "Agency_Hospital" : Agency_Hospital__c,
                "Person_In_Charge2" : Person_In_Charge2__c,
@@ -716,6 +765,10 @@
                            // Save&New時のウィンドウ内データ一覧
                            if (res.length > 0) {
                                // 20220222 PI改造  by Bright--start
                                res[0].doctor2NameOrigin = doctor2Name;
                                res[0].visitorTitleOrigin = visitortitle;
                                // 20220222 PI改造  by Bright--end
                                reports_now[reports_now_count] = res[0];
                                
                                reports_now.sort(function(a,b) {
@@ -804,10 +857,10 @@
        var ret_obj = [];
        var now = new Date();
        for (var i = 0; i < count; i++) {
            var start_day = new Date(now.getFullYear(), now.getMonth(), (now.getDate() - now.getDay() + 1 - (i * 7)));
            var end_day = new Date(now.getFullYear(), now.getMonth(), now.getDate() + (7 - now.getDay()) - (i * 7));
            var start_day_show = new Date(now.getFullYear(), now.getMonth(), (now.getDate() - now.getDay() - (i * 7)));
            var end_day_show = new Date(now.getFullYear(), now.getMonth(), now.getDate() + (6 - now.getDay()) - (i * 7));
            var date_text = start_day.getFullYear() + '/' + (start_day.getMonth() + 1) + '/' + start_day.getDate() + '~' + end_day.getFullYear() + '/' + (end_day.getMonth() + 1) + '/' + end_day.getDate();
@@ -1012,7 +1065,129 @@
            component.set('v.doctor_title', '');
        }
    },
    // PIPL update Yin Mingjie 21/02/2022 start
    set_aws_url : function(component) {
        var action = component.get('c.getAwsurl');
        action.setParams({
            "sobj" : "Agency_Contact__c",
        });
        action.setCallback(this,function(response){
            var state = response.getState();
            if(state == 'SUCCESS'){
                var awsmap = this.conv_selected(response.getReturnValue());
                component.set('v.AWStoken',awsmap.token);
                component.set('v.AWSinsert',awsmap.newUrl);
                component.set('v.AWStransactionURL',awsmap.transactionURL);
            }
            else{
                this.error('AWS url/token error.');
                component.set('v.login',false);
            }
        });
        $A.enqueueAction(action);
    },
    insert_agencycontact : function(component,token,newUrl,payload,agencyHospitalid,helper) {
        fetch(newUrl, {
            method: 'POST',
            body: payload,
            headers: {
                'Content-Type': 'application/json',
                'pi-token': token
            }
        }).then((data) => {
            return data.json();
        }).then((result) => {
            if(result.status == '0'){
                $A.getCallback(function(){
                    helper.to_agencycontact(component,result,agencyHospitalid);
                })();
            }else{
                console.log('AWS status error:' + result)
                component.set('v.login',false);
                component.find('OppMessage').setError('AWS insert error.');
            }
        }).catch(error => {
            console.log('AWS insert error:' + error)
            component.set('v.login',false);
            component.find('OppMessage').setError('AWS insert error.');
        });
    },
    to_agencycontact : function(component,result,agencyHospitalid) {
        var action = component.get('c.saveAgencyContact');
        action.setParams({
            "name" : result.object[0].name,
            "nameEncrypt" : result.object[0].nameEncrypt,
            "type" : result.object[0].type,
            "typeEncrypt" : result.object[0].typeEncrypt,
            "doctorDivision1" : result.object[0].doctorDivision1,
            "doctorDivision1Encrypt" : result.object[0].doctorDivision1Encrypt,
            "agencyHospitalid" : agencyHospitalid,
            "awsid" : result.object[0].dataId,
        });
        action.setCallback(this,function(response){
            var state = response.getState();
            if(state == 'SUCCESS'){
                var acMap = this.conv_selected(response.getReturnValue());
                console.log(acMap);
                if(acMap.AgencyContactId != ''){
                    //确认事务
                    var token = component.get('v.AWStoken');
                    var confirmUrl = component.get('v.AWStransactionURL');
                    let data = Object.create(null);
                    data['isSuccess'] = 1;
                    data['sfRecordId'] = '';
                    data['txId'] = result.txId;
                    this.to_confirm(component,token,confirmUrl,JSON.stringify(data));
                }else if(acMap.errormsg != ''){
                    this.error(acMap.errormsg);
                    component.set('v.login',false);
                }else {
                    this.error('agency contact insert id error.');
                    component.set('v.login',false);
                }
            }
            else{
                this.error('agency contact insert error.');
                component.set('v.login',false);
            }
        });
        $A.enqueueAction(action);
    },
    to_confirm : function(component,token,confirmUrl,payload) {
        fetch(confirmUrl, {
            method: 'POST',
            body: payload,
            headers: {
                'Content-Type': 'application/json',
                'pi-token': token
            }
        }).then((data) => {
            return data.json();
        }).then((result) => {
            if(result.status == '0' && result.hasOwnProperty('success') && result.success){
                component.set('v.truthy', false);
                var modal_newAC = component.find('modal_newAC')
                $A.util.addClass(modal_newAC, 'disp_none');
                this.success('.客户人员已创建。');
                this.set_doctor_list(component);
            }else {
                this.error('AWS confirm error.');
                component.set('v.login',false);
            }
        }).catch(error => {
            this.error('AWS confirm error.');
            component.set('v.login',false);
        });
    },
    // PIPL update Yin Mingjie 21/02/2022 end
    set_doctor_list : function(component) {
        var hospital_id = component.get('v.hospitalLinkId');
        if (hospital_id) {
@@ -1024,8 +1199,10 @@
            action.setCallback(this,function(response){
                var state = response.getState();
                if(state == 'SUCCESS'){
                    var res = this.conv_selected(response.getReturnValue());
                    var retMap = this.conv_selected(response.getReturnValue());
                    // PIPL update Yin Mingjie 21/02/2022 start
                    this.AWS_search(retMap,component);
                    /*
                    var default_doctor = component.get('v.default_select_doctor_id');
                    if (default_doctor != '' && res.length > 0) {
                        var doctor_title = '';
@@ -1050,6 +1227,8 @@
                    component.set('v.default_select_doctor_id', '');
                    component.set('v.doctor_list', res);
                    component.set('v.login',false);
                    */
                   // PIPL update Yin Mingjie 21/02/2022 end
                }
                else{
                    this.error('set_doctor_list failed.');
@@ -1059,6 +1238,111 @@
            $A.enqueueAction(action);
        }
    },
    // PIPL update Yin Mingjie 21/02/2022 start
    AWS_search : function(retMap,component) {
        var token = retMap.sre.token;
        var searchUrl = retMap.sre.searchUrl;
        var dataArr = new Array();
        for (const key in retMap) {
            if (key == 'sre') {continue;}
            dataArr.push(key);
        }
        let obj= Object.create(null);
        obj['dataIds'] = dataArr;
        var data = JSON.stringify(obj);
        this.search_agency_contact(token,searchUrl,data,retMap,component);
    },
    search_agency_contact : function(token,searchUrl,payload,retMap,component) {
        this.search_agency_contact_core(token,searchUrl,payload,(result)=>{
            if(result.status == '0'){
                this.to_doctor_list(result,retMap,component);
            }else{
                this.error('AWS search status : ' + result.status);
                component.set('v.login',false);
            }
        },component);
        // fetch(searchUrl, {
        //     method: 'POST',
        //     body: payload,
        //     headers: {
        //         'Content-Type': 'application/json',
        //         'pi-token': token
        //     }
        // }).then((data) => {
        //     return data.json();
        // }).then((result) => {
        // }).catch(error => {
        //     this.error('AWS search error.');
        //     component.set('v.login',false);
        // });
    },
    search_agency_contact_core : function(token,searchUrl,payload,callback,component) {
        fetch(searchUrl, {
            method: 'POST',
            body: payload,
            headers: {
                'Content-Type': 'application/json',
                'pi-token': token
            }
        }).then((data) => {
            return data.json();
        }).then((result) => {
            component.set('v.login',false);
            if(callback)callback(result);
        }).catch(error => {
            this.error('AWS search error.');
            component.set('v.login',false);
        });
    },
    to_doctor_list : function(result,retMap,component) {
        var resls = result.object;
        var res = [];
        var space = {};
        space['label'] = '';
        space['selected'] = true;
        space['value'] = '';
        res.push(space);
        for (var i = 0; i < resls.length; i++) {
            var t = {};
            t['label'] = resls[i].name;
            t['selected'] = false;
            t['Doctor_Division1__c'] = resls[i].doctorDivision1;
            t['value'] = retMap[resls[i].dataId].value;
            res.push(t);
        }
        var default_doctor = component.get('v.default_select_doctor_id');
        if (default_doctor != '' && res.length > 0) {
            var doctor_title = '';
            for (var i = 0; i < res.length; i++) {
                if (res[i].value == default_doctor) {
                    res[i].selected = true;
                    doctor_title = res[i].Doctor_Division1__c;
                } else {
                    res[i].selected = false;
                }
            }
            component.find('select_doctor').set('v.options', res);
            component.set('v.doctor_title', doctor_title);
        } else {
            component.find('select_doctor').set('v.options', res);
            if (res.length > 0) {
                component.set('v.doctor_title', res[0].Doctor_Division1__c);
            }
        }
        component.set('v.default_select_doctor_id', '');
        component.set('v.doctor_list', res);
        component.set('v.login',false);
    },
    // PIPL update Yin Mingjie 21/02/2022 end
    // stageNameChange : function(component, event, helper) {
    //     var options = component.find('input-oppstage').get("v.body")[0].get('v.options');
@@ -1332,8 +1616,8 @@
        this.set_doctor_list(component);
    },
    
     createCancel : function(component, event, helper) {
         component.set('v.truthy', false);
    createCancel : function(component, event, helper) {
        component.set('v.truthy', false);
        var modal_newAC = component.find('modal_newAC')
        $A.util.addClass(modal_newAC, 'disp_none');
    },
@@ -1448,13 +1732,13 @@
        var selectDate = component.find('select_date').get('v.value');
        var fieldsList=['Name','Phone','AccountNumber']; //Please write your code dynamic fields
        action.setParams({ 
                          fileData : component.get("v.fileContentData"),
                          //selectDateselectDate :component.find('select_date').get('v.value'),
                          sobjectName:'Account', //Any object
                          fields:fieldsList
            fileData : component.get("v.fileContentData"),
            //selectDateselectDate :component.find('select_date').get('v.value'),
            sobjectName:'Account', //Any object
            fields:fieldsList
                      });
        });
        action.setCallback(this, function(response) {
            var state = response.getState();
            if (state === "SUCCESS") {
@@ -1656,4 +1940,40 @@
        $A.util.addClass(modalimport, 'disp_none');
        $A.util.addClass(modalimportbg,'disp_none');
    }
    // searchAgencyContact : function(res) {
    //     var agencyContacts = [];
    //     for (let idx = 0; idx < res.length; idx++) {
    //         agencyContacts.push(res[idx].awsid);
    //     }
    //     var action = component.get('c.getAWStoken');
    //     action.setCallback(this,function(response){
    //         var state = response.getState();
    //         console.log('state : ' + state);
    //         if(state === 'SUCCESS') {
    //             console.log('get name : ' + action.getName());
    //         }
    //         else if(state === 'INCOMPLETE') {
    //             console.log('incomplete state');
    //         } else if(state === 'ERROR') {
    //             if (errors) {
    //                 if (errors[0] && errors[0].message) {
    //                     console.log("Error message: " +
    //                              errors[0].message);
    //                 }
    //             } else {
    //                 console.log("Unknown error");
    //             }
    //         }
    //     });
    //     $A.enqueueAction(action);
    //     // var requestSearchPayload = new Map();
    //     // requestSearchPayload.set("dataIds",agencyContacts);
    //     var data = '{"dataIds": ["944233643042144256", "943645353649897473"]}';
    //     var token = 'eyJhbGciOiJIUzUxMiJ9.eyJjcmVhdGVkIjoxNjQ0NzY4MTIwNjc2LCJhcHBpZCI6IjZMeml6Y1JmN2g4eUx4MjgiLCJleHAiOjE2NDk5NTIxMjB9.6vORDP8BRaf_beCt4SEXrl3DEuYZ3owotkUqh27r8YhfmKDDWrv_NpVVpjTPeFjvzlQqaJMcFobZeAmPxpmq2A';
    //     var searchUrl = 'https://52.83.101.205/api/agencycontact/search';
    //     var data = this.search(searchUrl,data,token);
    //     return data;searchUrl,requestSearchPayload,token
    // },
})
force-app/main/default/classes/AWSServiceTool.cls
@@ -9,14 +9,44 @@
 * */
public without sharing class AWSServiceTool {
    public static String getAWSToken(){
        String app_id = '6LzizcRf7h8yLx28';
        String app_secret = 'UkLohQcHNjg164SdRc7gnS4rgu4d7FjINM3mtzRbyTS6IrUP5V';
        String url = 'https://52.83.101.205/api/token/getToken?app_id=' + app_id + '&app_secret=' + app_secret;
        HttpRequest req = new HttpRequest();
        req.setEndpoint(url);
        req.setMethod('GET');
        Http h = new Http();
        HttpResponse res = h.send(req);
        return res.getBody();
        AWS_Integration_Info__mdt awsConfiguration = [SELECT App_Id__c,Token_URL__c,App_Secret__c,Host_URL__c FROM AWS_Integration_Info__mdt  WHERE DeveloperName = 'AWS_Default_Configuration'];
        if (awsConfiguration == null) {
            System.debug('AWS_Integration_Info__mdt没配置');
            return null;
        }
        String awsAppId = awsConfiguration.App_Id__c;
        String awsAppSecret = awsConfiguration.App_Secret__c;
        Http http = new Http();
        HttpRequest request = new HttpRequest();
        String url = awsConfiguration.Token_URL__c;
        request.setEndpoint(url);
        request.setMethod('GET');
        HttpResponse response = http.send(request);
        Map<String, Object> results = (Map<String, Object>) JSON.deserializeUntyped(response.getBody());
        String token = (String)results.get('object');
        return token;
    }
    @future(callout=true)
    public static void deleteFileAddress(Set<String> fileAddressIds){
        //1. Get file address id
        system.debug('fileAddressId = '+ JSON.serialize(fileAddressIds));
        PIHelper.PIIntegration documentPI=PIHelper.getPIIntegrationInfo('Document');
        //2. Delete aws file doucment and post aws service
        Http http = new Http();
        HttpRequest request = new HttpRequest();
        String url = documentPI.deleteUrl;
        request.setEndpoint(url);
        request.setMethod('POST');
        request.setHeader('pi-token',documentPI.token);
        request.setHeader('Content-Type', 'application/json');
        request.setBody(JSON.serialize(fileAddressIds));
        HttpResponse response = http.send(request);
        system.debug('response = ' + response);
        if(response.getStatusCode() == 200){
            Map<String, Object> results = (Map<String, Object>) JSON.deserializeUntyped(response.getBody());
            if(results.get('status')=='0'){
                System.debug('成功删除');
            }
        }
    }
}
force-app/main/default/classes/AgencyAccountCmp.cls
@@ -75,4 +75,52 @@
        return acList1;
    }
    @AuraEnabled
    public static void SaveLog(String module,String content,String status,String respMsg){
        string awsDataId = '';
        string sfId = '';
        string transId = '';
        try {
            Map<string,object> mso = (Map<string,object>)JSON.deserializeUntyped(respMsg);
            awsDataId = String.valueOf(mso.get('AWS_Data_Id__c'));
            transId = String.valueOf(mso.get('txId'));
        } catch (Exception e) {
        }
        PIHelper.saveTransLog(module, awsDataId, sfId, transId, content, status, respMsg);
    }
    // 20220222 PI改造 by Bright--start
    @AuraEnabled
    public static Map<string,string> GetConfig() {
        Map<String,string> result = new Map<String,string>();
        result.put('staticResource', JSON.serialize(PIHelper.getPIIntegrationInfo('Agency_Contact__c')));
        //result.put('sessionId', UserInfo.getSessionId());
        return result;
    }
    @AuraEnabled
    public static List<Agency_Contact__c> searchAccounts2(String hosStr, List<string> awsids) {
        System.debug('hosStr='+hosStr);
        System.debug('awsids='+awsids);
        String f1 = '%'+hosStr+'%';
        if (String.isBlank(hosStr)) f1 = '%';
        Set<String> hospitalSet = new Set<String>();
        Set<String> aHospitalSet = new Set<String>();
        List<Agency_Hospital_Link__c> ahls = [select Id, Hospital__c from Agency_Hospital_Link__c];
        for (Agency_Hospital_Link__c ahl : ahls) {
            hospitalSet.add(ahl.Hospital__c);
            aHospitalSet.add(ahl.Id);
        }
        List<Agency_Contact__c> acList1 = LightningUtil.searchOCMAgencyContact(hospitalSet, aHospitalSet, f1, awsids);
        return acList1;
    }
    // 20220222 PI改造 by Bright--end
}
force-app/main/default/classes/AgencyContactHandler.cls
@@ -47,15 +47,25 @@
                }
                nObj.Agency_ID__c = nObj.Agency_ID_F__c;
            }
            nameSet.add(nObj.Name);
            nameSet.add(nObj.Name_Encrypted__c);
            ahIdSet.add(nObj.Agency_Hospital__c);
            keyMap.put(nObj.Agency_Hospital__c + nObj.Name, nObj);
            // PIPL update Yin Mingjie 21/02/2022 start
            // keyMap.put(nObj.Agency_Hospital__c + nObj.Name, nObj);
            keyMap.put(nObj.Agency_Hospital__c + nObj.Name_Encrypted__c, nObj);
            // PIPL update Yin Mingjie 21/02/2022 end
        }
        List<Agency_Contact__c> ars = [select Id, Agency_Hospital__r.Name, Agency_Hospital__c, Name from Agency_Contact__c
            where Name in :nameSet and Agency_Hospital__c in :ahIdSet and Agency_Hospital__c != null];
        // PIPL update Yin Mingjie 21/02/2022 start
        // List<Agency_Contact__c> ars = [select Id, Agency_Hospital__r.Name, Agency_Hospital__c, Name from Agency_Contact__c
        //     where Name in :nameSet and Agency_Hospital__c in :ahIdSet and Agency_Hospital__c != null];
        List<Agency_Contact__c> ars = [select Id, Agency_Hospital__r.Name, Agency_Hospital__c, Name, Name_Encrypted__c from Agency_Contact__c
            where Name_Encrypted__c in :nameSet and Agency_Hospital__c in :ahIdSet and Agency_Hospital__c != null];
        // PIPL update Yin Mingjie 21/02/2022 end
        for (Agency_Contact__c ar : ars) {
            String key = ar.Agency_Hospital__c + ar.Name;
            // PIPL update Yin Mingjie 21/02/2022 start
            // String key = ar.Agency_Hospital__c + ar.Name;
            String key = ar.Agency_Hospital__c + ar.Name_Encrypted__c;
            // PIPL update Yin Mingjie 21/02/2022 end
            //system.debug('========3333333key'+key);
            if (keyMap.containsKey(key)) {
                Agency_Contact__c a = keyMap.get(key);
force-app/main/default/classes/AssessmentReportController.cls
@@ -7,6 +7,8 @@
    public integer ASRRecordsNumber;
    public boolean hasError;
    public String ErrorMessages;
    public String awsString{get; set;}
    public String staticResource {get; set;}
    public AssessmentReportController() {
@@ -71,6 +73,7 @@
                return null;
            }
            setCurrentAssessmentReportStaff();
            staticResource = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));
        } catch (Exception ex) {
            ApexPages.addMessages(ex);
@@ -221,6 +224,7 @@
        list<CampaignMember__c> CMlist = [
                                             SELECT Id, Name, Department_ID__c,
                                             Contact_ID__c, Contact_ID__r.Name,
                                             Contact_ID__r.AWS_Data_Id__c,
                                             dept__c, State__c, City__c
                                             FROM CampaignMember__c
                                             where Campaign__c = : AssessmentReport.Campaign__c
@@ -237,7 +241,7 @@
        for (AssessmentReportStaff__c tempARS : tempAmrsList) {
            ARSMap.put(tempARS.CampaignMember__c, tempARS);
        }
        for (CampaignMember__c tempCM : CMlist) {
            if (ARSMap.containsKey(tempCM.id)) {
                TempARSInfoList.add(
@@ -259,8 +263,8 @@
            }
        }
        ARSInfoList = TempARSInfoList.clone();
        awsString = JSON.serialize(ARSInfoList);
    }
    public PageReference Submit() {
        system.debug('Submit start:');
force-app/main/default/classes/B_Test.cls
New file
@@ -0,0 +1,161 @@
public without sharing class B_Test {
    public Contact newCon { get; set; }
    public Contact searchCon { get; set; }
    public List<LineInfo> lineInfoList { get; set; }
    public String conId { get; set; }
    public String openLine { get; set; }
    private String accountId;
    // SWAG-BB44G7  所在医院id start
    private String HPId;
    private Integer i = 0;
    // SWAG-BB44G7  所在医院id end
    private String nowValue;
    public final string ApiPrefix{get;private set;}
    public String staticResource {get; set;}
    public B_Test() {
        openLine = Apexpages.currentPage().getParameters().get('line');
        accountId = Apexpages.currentPage().getParameters().get('acc');
        // SWAG-BB44G7  检索所在医院id start
        Account temAccount =
            [select id, Parent.parentid from account where id = : accountId];
        if (temAccount.Parent.parentid != null) {
            HPId = temAccount.Parent.parentid;
            i = 1;
        }else{
            HPId = accountId;
            i = 2;
        }
        // SWAG-BB44G7  检索所在医院id end
        nowValue = Apexpages.currentPage().getParameters().get('now');
        lineInfoList = new List<LineInfo>();
        ApiPrefix = 'PIBackApi';
        PIHelper.PIIntegration piIntegration = PIHelper.getPIIntegrationInfo('Contact');
        staticResource = JSON.serialize(piIntegration);
        System.debug('B_Test');
    }
    public void init() {
        searchCon = new Contact();
        if (nowValue != null && nowValue != '') {
            searchCon = [select Id, Name, Department__c, Type__c, Search_LastName__c, Search_FirstName__c, Phone, Supplement__c,
                         FirstName, LastName
                         from Contact where Id = :nowValue];
            searchCon.Search_LastName__c = searchCon.LastName;
            searchCon.Search_FirstName__c = searchCon.FirstName;
        }
        searchContact();
        newCon = new Contact();
        newCon.AccountId = accountId;
        return;
    }
    public PageReference searchContact() {
        String searchStr = 'select Id, Name, Department__c, Type__c, AccountName__c, Supplement__c, Phone,accountid ';
        searchStr += '        from Contact ';
        searchStr += '       where Isactive__c = \'有效\' ';
        // SWAG-BB44G7  检索所在医院的客户人员 start
        if(i == 1 ){
            searchStr += '         and Account.parent.parentid = :HPId ';
        }
        if(i == 2){
            searchStr += '         and AccountId = :HPId ';
        }
        // searchStr += '         and Account.parent.parentid = :HPId ';
        // SWAG-BB44G7  检索所在医院的客户人员 end
        if (searchCon.Search_LastName__c != null && searchCon.Search_LastName__c != '') {
            searchStr += '     and LastName like \'%' + searchCon.Search_LastName__c + '%\'';
        }
        if (searchCon.Search_FirstName__c != null && searchCon.Search_FirstName__c != '') {
            searchStr += '     and FirstName like \'%' + searchCon.Search_FirstName__c + '%\'';
        }
        system.debug('=====searchStr:' + searchStr);
        List<Contact> searchResult = Database.query(searchStr);
        lineInfoList = new List<LineInfo>();
        Integer line = 0;
        for (Contact con : searchResult) {
            line += 1;
            LineInfo li = new LineInfo(line, con);
            lineInfoList.add(li);
        }
        editClear();
        return null;
    }
    public PageReference editContact() {
        if (conId != null && conId != '') {
            newCon = [select Id, Name, Department__c, Type__c, Search_LastName__c, Search_FirstName__c, Phone, Supplement__c,LastName_Encrypted__c,Phone_Encrypted__c,
                      FirstName, LastName,AWS_Data_Id__c
                      from Contact where Id = :conId];
        }
        System.debug(newCon);
        System.debug('editContact');
        return null;
    }
    public PageReference saveNew()  {
        if (newCon.Search_LastName__c == null || newCon.Search_LastName__c == '') {
            newCon.Search_LastName__c.addError('必须填写。');
            return null;
        }
        newCon.LastName = newCon.Search_LastName__c;
        newCon.FirstName = newCon.Search_FirstName__c;
        upsert newCon;
        searchCon.Search_LastName__c = newCon.LastName;
        searchCon.Search_FirstName__c = newCon.FirstName;
        searchContact();
        return null;
    }
    public PageReference editClear()  {
        newCon = new Contact();
        newCon.AccountId = accountId;
        return null;
    }
    class LineInfo {
        public Integer lineNo { get; set; }
        public Contact con { get; set; }
        public LineInfo(Integer in_line) {
            lineNo = in_line;
            con = new Contact();
        }
        public LineInfo(Integer in_line, Contact in_con) {
            lineNo = in_line;
            con = in_con;
        }
    }
    // @RemoteAction
    // global static Response saveContact(String leadJson,String transId) {
    //     return NewAndEditBaseController.save(new Contact(),leadJson,transId,isNew);
    // }
}
force-app/main/default/classes/B_Test.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>52.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/BmeWorkController.cls
@@ -16,6 +16,17 @@
    public String numtextD2 { get; set; } //数据字段02
    public String numtextD { get; set; }//数据字段03
    public String limits { get; set; }//日期03
    public String AwsDataIds { get; set; }//PI 改造
    public String[] AwsDataIdArr{
        get{
            if(String.isBlank(AwsDataIds)){
                return new string[]{};
            }
            return AwsDataIds.split(';');
        }
    }
    //public List<SelectOption> dateOpts { get; private set; }
    public List<SelectOption> textOpts { get; private set; }
    public List<SelectOption> textOpts01 { get; private set; }
@@ -49,33 +60,41 @@
    private String strRtColumus;
    @TestVisible private String accTypeForSort = null;
    private static Integer oppLimit = 500;
    // 20220222 PI改造 by Bright--start
    public List<SelectOption> equalOpts2 { get; private set; }
    public string staticResource { get; private set; }
    // 20220222 PI改造 by Bright--end
    public BmeWorkController() {
        oppRecords = new List<ConMeetInfo>();
        //数据字段下拉列表
        textOpts = new List<SelectOption>();
        textOpts.add(new SelectOption('Account.Name', '医院科室'));
        textOpts.add(new SelectOption('CampaignName__c', '学会培训名称'));
        textOpts.add(new SelectOption('MedicalStaff_Full_name__c', '拜访人姓名'));
        // textOpts.add(new SelectOption('MedicalStaff_Full_name__c', '拜访人姓名'));
        textOpts.add(new SelectOption('CampaignOwnerName__c', '学会培训主担当'));
        textOpts.add(new SelectOption('', '--无--'));
        textOpts01 = new List<SelectOption>();
        textOpts01.add(new SelectOption('CampaignName__c', '学会培训名称'));
        textOpts01.add(new SelectOption('MedicalStaff_Full_name__c', '拜访人姓名'));
        // textOpts01.add(new SelectOption('MedicalStaff_Full_name__c', '拜访人姓名'));
        textOpts01.add(new SelectOption('CampaignOwnerName__c', '学会培训主担当'));
        textOpts01.add(new SelectOption('Account.Name', '医院科室'));
        textOpts01.add(new SelectOption('', '--无--'));
        textOpts02 = new List<SelectOption>();
        textOpts02.add(new SelectOption('MedicalStaff_Full_name__c', '拜访人姓名'));
        textOpts02.add(new SelectOption('Account.Name', '医院科室'));
        textOpts02.add(new SelectOption('CampaignName__c', '学会培训名称'));
        textOpts02.add(new SelectOption('CampaignOwnerName__c', '学会培训主担当'));
        // textOpts02.add(new SelectOption('Account.Name', '医院科室'));
        // textOpts02.add(new SelectOption('CampaignName__c', '学会培训名称'));
        // textOpts02.add(new SelectOption('CampaignOwnerName__c', '学会培训主担当'));
        textOpts02.add(new SelectOption('', '--无--'));
        textOpts03 = new List<SelectOption>();
        textOpts03.add(new SelectOption('CampaignOwnerName__c', '学会培训主担当'));
        textOpts03.add(new SelectOption('MedicalStaff_Full_name__c', '拜访人姓名'));
        // textOpts03.add(new SelectOption('MedicalStaff_Full_name__c', '拜访人姓名'));
        textOpts03.add(new SelectOption('Account.Name', '医院科室'));
        textOpts03.add(new SelectOption('CampaignName__c', '学会培训名称'));
        textOpts03.add(new SelectOption('', '--无--'));
@@ -86,6 +105,10 @@
        equalOpts.add(new SelectOption('contains', '包含'));
        equalOpts.add(new SelectOption('notcontains', '不包含'));
        equalOpts.add(new SelectOption('starts with', '起始字符'));
        equalOpts2 = new List<SelectOption>();
        equalOpts2.add(new SelectOption('contains', '包含'));
        //首要显示包含
        firstOpts = new List<SelectOption>();
        firstOpts.add(new SelectOption('contains', '包含'));
@@ -104,11 +127,12 @@
        limitOpts.add(new SelectOption('1000', '全部'));
        //数据显示默认条数
        limits = '50';
        staticResource = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));
    }
    //--------------------------------------init()--------------------------------------------------------------------------------
    public PageReference init() {
        setLayoutRWInfo();
        searchOppInner();
        //searchOppInner();
        system.debug(oppRecords);
        return null;
    }
@@ -192,117 +216,126 @@
    //----------------------------------SOQL(拼接)---------------------------------------------
    public void searchOppInner() {
        //try {
            //SOQL:拼接检索条件以及经销商询价的SOQL语句
            String soql = ' SELECT Campaign__c, CampaignOwnerID__c, Campaign__r.Ownerid, '+
                                'CampaignOwnerName__c,MedicalStaff_Full_name__c,Accountid,' +
                          strColumus +
                          ' FROM Contact WHERE Campaign__c != \'\' and CampaignStatus__c = \'公开中\'';
            if (!String.isBlank(numtextA)) {
                String newNumtext = numtextA.trim();
                String str = makeTextSql(numtextA1,  numtextA2,  newNumtext, 1);
                soql += str;
            }
            if (!String.isBlank(numtextB)) {
                String newNumtext = numtextB.trim();
                String str = makeTextSql(numtextB1,  numtextB2,  newNumtext, 1);
                soql += str;
            }
            if (!String.isBlank(numtextC)) {
                String newNumtext = numtextC.trim();
                String str = makeTextSql(numtextC1,  numtextC2,  newNumtext, 1);
                soql += str;
            }
            if (!String.isBlank(numtextD)) {
                String newNumtext = numtextD.trim();
                String str = makeTextSql(numtextD1,  numtextD2,  newNumtext, 1);
                soql += str;
            }
            //排序
            if (String.isBlank(this.sortKey)) {
                soql += ' order by LastModifiedDate desc limit ' + Integer.valueOf(limits);
            } else {
                if (Integer.valueOf(this.sortKey) != null) {
                    soql += ' order by ' + this.selColumus[Integer.valueOf(this.sortKey)] + ' ' + (this.sortOrderAsc == true ? 'asc nulls first' : 'desc nulls last') + ' limit ' + Integer.valueOf(limits);
                } else {
                    soql += ' order by ' + this.selColumus[Integer.valueOf(this.sortKey)] + ' ' + (this.sortOrderAsc == true ? 'asc nulls first' : 'desc nulls last') + ' limit ' + Integer.valueOf(limits);
                }
            }
            system.debug('联系人:' + soql);
            List<Contact> InfoList = Database.query(soql);
            List<ConMeetInfo> conmeetList = new List<ConMeetInfo>();
            if (InfoList != null && InfoList.size() > 0) {
                String str = '';
                for (Contact agc : InfoList) {
                    if (str == '' && agc.Id != null) {
                        str = '\'' + agc.Id + '\'';
                    } else if (agc.Id != null) {
                        str += ',\'' + agc.Id + '\'';
                    }
                }
                System.debug('-----Str-----:' + str );
                //SOQL1:拼接询价SOQL语句;
                Date dateToday = Date.toDay();
                Integer year = dateToday.year();
                Integer month = dateToday.month();
                Integer day = dateToday.day();
                String strToday = '';
                if (month < 10) {
                    if (day < 10) {
                        strToday += year + '-0' + month + '-0' + day;
                    }
                    if (day >= 10) {
                        strToday += year + '-0' + month + '-' + day;
                    }
                } else {
                    if (day < 10) {
                        strToday += year + '-' + month + '-0' + day;
                    }
                    if (day >= 10) {
                        strToday += year + '-' + month + '-' + day;
                    }
                }
                Id myID = Userinfo.getUserId();
                String soql1 = 'SELECT ' + strRtColumus + ' , Contact__c FROM MeetingManagement__c WHERE CreatedById  =: myID and Contact__c IN (' + str + ') AND CreatedDate__c = ' + strToday  ;
                System.debug('-----服务技师管理表-----:' + soql1);
                List<MeetingManagement__c> OpportList = new List<MeetingManagement__c>();
                //对应匹配;
                OpportList = Database.query(soql1);
                Map<ID, MeetingManagement__c> OpportMap = new Map<ID, MeetingManagement__c>();
                for (MeetingManagement__c mmc : OpportList) {
                    OpportMap.put(mmc.Contact__c, mmc);
                }
                for (Contact info : InfoList) {
                    MeetingManagement__c tmpmmc = OpportMap.get(info.Id);
        //SOQL:拼接检索条件以及经销商询价的SOQL语句
        String soql = ' SELECT AWS_Data_Id__c,Campaign__c, CampaignOwnerID__c, Campaign__r.Ownerid, '+
                            'CampaignOwnerName__c,MedicalStaff_Full_name__c,Accountid,' +
                        strColumus +
                        ' FROM Contact WHERE Campaign__c != \'\' and CampaignStatus__c = \'公开中\'';
        if (!String.isBlank(numtextA)) {
            String newNumtext = numtextA.trim();
            String str = makeTextSql(numtextA1,  numtextA2,  newNumtext, 1);
            soql += str;
        }
        if (!String.isBlank(numtextB)) {
            String newNumtext = numtextB.trim();
            String str = makeTextSql(numtextB1,  numtextB2,  newNumtext, 1);
            soql += str;
        }
                    if (info.IsEndoscope__c == null) {
                        info.IsEndoscope__c = '是';
                    }
                    if (tmpmmc == null) {
                        tmpmmc = new MeetingManagement__c();
                        tmpmmc.Contact__c = info.Id;
                        tmpmmc.Name  = info.MedicalStaff_Full_name__c + ':' + Date.today().format();
                        tmpmmc.CreatedDate__c  = Date.today();
                        //tmpmmc.Campaign__c = info.Campaign__c;
                    }
                    conmeetList.add(new ConMeetInfo(info, tmpmmc));
                    conmeetList[conmeetList.size() - 1].lineNo = conmeetList.size() - 1;
        // if (!String.isBlank(numtextC)) {
        //     String newNumtext = numtextC.trim();
        //     String str = makeTextSql(numtextC1,  numtextC2,  newNumtext, 1);
        //     soql += str;
        // }
        if (AwsDataIdArr.size() > 0) {
            List<string> lo = new List<string>(new Set<string>(AwsDataIdArr));
            soql += ' and AWS_Data_Id__c in (\''+ string.join(lo, '\',\'')+'\') ';
        }
        if (!String.isBlank(numtextD)) {
            String newNumtext = numtextD.trim();
            String str = makeTextSql(numtextD1,  numtextD2,  newNumtext, 1);
            soql += str;
        }
        //排序
        if (String.isBlank(this.sortKey)) {
            soql += ' order by LastModifiedDate desc limit ' + Integer.valueOf(limits);
        } else {
            if (Integer.valueOf(this.sortKey) != null) {
                soql += ' order by ' + this.selColumus[Integer.valueOf(this.sortKey)] + ' ' + (this.sortOrderAsc == true ? 'asc nulls first' : 'desc nulls last') + ' limit ' + Integer.valueOf(limits);
            } else {
                soql += ' order by ' + this.selColumus[Integer.valueOf(this.sortKey)] + ' ' + (this.sortOrderAsc == true ? 'asc nulls first' : 'desc nulls last') + ' limit ' + Integer.valueOf(limits);
            }
        }
        system.debug('联系人:' + soql);
        List<Contact> InfoList = Database.query(soql);
        System.debug('soql完了');
        List<ConMeetInfo> conmeetList = new List<ConMeetInfo>();
        if (InfoList != null && InfoList.size() > 0) {
            String str = '';
            for (Contact agc : InfoList) {
                if (str == '' && agc.Id != null) {
                    str = '\'' + agc.Id + '\'';
                } else if (agc.Id != null) {
                    str += ',\'' + agc.Id + '\'';
                }
            }
            oppRecords = conmeetList.clone();
            oppCount = oppRecords.size();
            //显示提示操作信息
            if (String.isBlank(this.saveType) && String.isBlank(this.sortKey)) {
                ApexPages.addmessage(new ApexPages.message(ApexPages.severity.INFO, '取得最近的 ' + oppCount + ' 条数据'));
            } else if (!String.isBlank(this.sortKey)) {
                if (oppCount > oppLimit) {
                    ApexPages.addmessage(new ApexPages.message(ApexPages.severity.INFO, '数据超过' + oppLimit + '件,只显示前' + oppLimit + '件'));
                } else {
                    ApexPages.addmessage(new ApexPages.message(ApexPages.severity.INFO, '共有 ' + oppCount + ' 条数据'));
            System.debug('-----Str-----:' + str );
            //SOQL1:拼接询价SOQL语句;
            Date dateToday = Date.toDay();
            Integer year = dateToday.year();
            Integer month = dateToday.month();
            Integer day = dateToday.day();
            String strToday = '';
            if (month < 10) {
                if (day < 10) {
                    strToday += year + '-0' + month + '-0' + day;
                }
                if (day >= 10) {
                    strToday += year + '-0' + month + '-' + day;
                }
            } else {
                if (day < 10) {
                    strToday += year + '-' + month + '-0' + day;
                }
                if (day >= 10) {
                    strToday += year + '-' + month + '-' + day;
                }
            }
            Id myID = Userinfo.getUserId();
            String soql1 = 'SELECT ' + strRtColumus + ' , Contact__c, Contact__r.Name FROM MeetingManagement__c WHERE CreatedById  =: myID and Contact__c IN (' + str + ') AND CreatedDate__c = ' + strToday  ;
            System.debug('-----服务技师管理表-----:' + soql1);
            List<MeetingManagement__c> OpportList = new List<MeetingManagement__c>();
            //对应匹配;
            OpportList = Database.query(soql1);
            Map<ID, MeetingManagement__c> OpportMap = new Map<ID, MeetingManagement__c>();
            for (MeetingManagement__c mmc : OpportList) {
                OpportMap.put(mmc.Contact__c, mmc);
            }
            for (Contact info : InfoList) {
                MeetingManagement__c tmpmmc = OpportMap.get(info.Id);
                if (info.IsEndoscope__c == null) {
                    info.IsEndoscope__c = '是';
                }
                if (tmpmmc == null) {
                    tmpmmc = new MeetingManagement__c();
                    tmpmmc.Contact__c = info.Id;
                    tmpmmc.Contact__r = info;
                    tmpmmc.Name  = info.MedicalStaff_Full_name__c + ':' + Date.today().format();
                    tmpmmc.CreatedDate__c  = Date.today();
                    //tmpmmc.Campaign__c = info.Campaign__c;
                }
                conmeetList.add(new ConMeetInfo(info, tmpmmc));
                conmeetList[conmeetList.size() - 1].lineNo = conmeetList.size() - 1;
            }
        }
        oppRecords = conmeetList.clone();
        oppCount = oppRecords.size();
        System.debug('searchOppInner完了'+oppRecords);
        //显示提示操作信息
        if (String.isBlank(this.saveType) && String.isBlank(this.sortKey)) {
            ApexPages.addmessage(new ApexPages.message(ApexPages.severity.INFO, '取得最近的 ' + oppCount + ' 条数据'));
        } else if (!String.isBlank(this.sortKey)) {
            if (oppCount > oppLimit) {
                ApexPages.addmessage(new ApexPages.message(ApexPages.severity.INFO, '数据超过' + oppLimit + '件,只显示前' + oppLimit + '件'));
            } else {
                ApexPages.addmessage(new ApexPages.message(ApexPages.severity.INFO, '共有 ' + oppCount + ' 条数据'));
            }
        } else {
            ApexPages.addmessage(new ApexPages.message(ApexPages.severity.INFO, '共有 ' + oppCount + ' 条数据'));
        }
        //} catch (Exception e) {
        //    system.debug(e);
        //}
force-app/main/default/classes/CM_SearchContact.cls
@@ -11,6 +11,10 @@
    private Integer i = 0;
    // SWAG-BB44G7  所在医院id end
    private String nowValue;
    public String staticResource {get; set;}
    public String contactAWSIds {set;get;}
    public String contactsInfo {set;get;}
    public String awsDataIdArray {set;get;}
    public CM_SearchContact() {
        openLine = Apexpages.currentPage().getParameters().get('line');
@@ -28,6 +32,26 @@
        }
        // SWAG-BB44G7  检索所在医院id end
        nowValue = Apexpages.currentPage().getParameters().get('now');
        //2022/02/15 张华建 PI PL start
        //1. Query Contact by accountId
        List<Contact> conList = new List<Contact>();
        system.debug('Account Id from Front-end:'+accountId);
        if(String.isNotBlank(accountId) && String.isNotEmpty(accountId)){
            conList = new List<Contact>([select Id,AWS_Data_Id__c from Contact where AccountId=:accountId and AWS_Data_Id__c!='']);
        }
        //2. Prepare the Contact Info
        Map<String,Contact> awsIdToContactMap = new Map<String,Contact>();
        List<String> conAWSIds = new List<String>();
        for(Contact con:conList){
            conAWSIds.add(con.AWS_Data_Id__c);
            awsIdToContactMap.put(con.AWS_Data_Id__c,con);
        }
        //conAWSIds.add('943114607025717249');
        contactsInfo = JSON.serialize(awsIdToContactMap);
        contactAWSIds = JSON.serialize(conAWSIds);
        staticResource = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));
        //2022/02/15 张华建 PI PL end
    }
    public void init() {
@@ -50,9 +74,9 @@
    public PageReference searchContact() {
        String searchStr = 'select Id, Name, Department__c, Type__c, AccountName__c, Supplement__c, Phone,accountid ';
        String searchStr = 'select Id, Name, Department__c, Type__c, AccountName__c, Supplement__c, Phone,accountid,AWS_Data_Id__c';
        searchStr += '        from Contact ';
        searchStr += '       where Isactive__c = \'有效\' ';
        searchStr += '       where Isactive__c = \'有效\' and AWS_Data_Id__c!=\'\' ';
        // SWAG-BB44G7  检索所在医院的客户人员 start
        if(i == 1 ){
            searchStr += '         and Account.parent.parentid = :HPId ';
@@ -60,14 +84,31 @@
        if(i == 2){
            searchStr += '         and AccountId = :HPId ';
        }
        // searchStr += '         and Account.parent.parentid = :HPId ';
        //searchStr += '         and Account.parent.parentid = :HPId ';
        // SWAG-BB44G7  检索所在医院的客户人员 end
        if (searchCon.Search_LastName__c != null && searchCon.Search_LastName__c != '') {
            searchStr += '     and LastName like \'%' + searchCon.Search_LastName__c + '%\'';
        //2022/02/15 张华建 检索 start
        // if (searchCon.Search_LastName__c != null && searchCon.Search_LastName__c != '') {
        //     searchStr += '     and LastName like \'%' + searchCon.Search_LastName__c + '%\'';
        // }
        // if (searchCon.Search_FirstName__c != null && searchCon.Search_FirstName__c != '') {
        //     searchStr += '     and FirstName like \'%' + searchCon.Search_FirstName__c + '%\'';
        // }
        System.debug('awsDataIdArray = ' + awsDataIdArray);
        if (awsDataIdArray != null && awsDataIdArray != '') {
            String[] arr = awsDataIdArray.split(',');
            System.debug('arr = ' + arr);
            String awsDataIdSql = '';
            for(String s : arr){
                System.debug('s = ' + s);
                awsDataIdSql = awsDataIdSql + ',' + '\'' + s+'\'';
            }
            awsDataIdSql = awsDataIdSql.substring(1);
            System.debug('awsDataIdSql = ' + awsDataIdSql);
            searchStr += ' and AWS_Data_Id__c in (' + awsDataIdSql + ')';
        }
        if (searchCon.Search_FirstName__c != null && searchCon.Search_FirstName__c != '') {
            searchStr += '     and FirstName like \'%' + searchCon.Search_FirstName__c + '%\'';
        }
        //2022/02/15 张华建 检索 end
        system.debug('=====searchStr:' + searchStr);
        List<Contact> searchResult = Database.query(searchStr);
@@ -87,8 +128,8 @@
    public PageReference editContact() {
        if (conId != null && conId != '') {
            newCon = [select Id, Name, Department__c, Type__c, Search_LastName__c, Search_FirstName__c, Phone, Supplement__c,
                      FirstName, LastName
            newCon = [select Id, Name, Department__c, Type__c, Search_LastName__c, Search_FirstName__c, Phone, Supplement__c,LastName_Encrypted__c,Phone_Encrypted__c,
                      FirstName, LastName,AWS_Data_Id__c
                      from Contact where Id = :conId];
            newCon.Search_LastName__c = newCon.LastName;
            newCon.Search_FirstName__c = newCon.FirstName;
@@ -120,6 +161,11 @@
        return null;
    }
    public PageReference clearLineInfoList()  {
        lineInfoList = new List<LineInfo>();
        return null;
    }
    class LineInfo {
        public Integer lineNo { get; set; }
        public Contact con { get; set; }
force-app/main/default/classes/CM_SearchContactServiceController.cls
@@ -8,10 +8,35 @@
    private String accountId;
    private String nowValue;
    public String staticResource {get; set;}
    public String contactAWSIds {set;get;}
    public String contactsInfo {set;get;}
    public String awsDataIdArray {set;get;}
    public CM_SearchContactServiceController() {
        openLine = Apexpages.currentPage().getParameters().get('line');
        accountId = Apexpages.currentPage().getParameters().get('acc');
        nowValue = Apexpages.currentPage().getParameters().get('now');
        //2022/02/15 张华建 PI PL start
        //1. Query Contact by accountId
        List<Contact> conList = new List<Contact>();
        system.debug('Account Id from Front-end:'+accountId);
        if(String.isNotBlank(accountId) && String.isNotEmpty(accountId)){
            conList = new List<Contact>([select Id,AWS_Data_Id__c from Contact where AccountId=:accountId and AWS_Data_Id__c!='']);
        }
        //2. Prepare the Contact Info
        Map<String,Contact> awsIdToContactMap = new Map<String,Contact>();
        List<String> conAWSIds = new List<String>();
        for(Contact con:conList){
            conAWSIds.add(con.AWS_Data_Id__c);
            awsIdToContactMap.put(con.AWS_Data_Id__c,con);
        }
        //conAWSIds.add('943114607025717249');
        contactsInfo = JSON.serialize(awsIdToContactMap);
        contactAWSIds = JSON.serialize(conAWSIds);
        staticResource = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));
        //2022/02/15 张华建 PI PL end
    }
    public void init() {
@@ -34,17 +59,35 @@
    public PageReference searchContact() {
        String searchStr = 'select Id, Name, Department__c, Type__c, AccountName__c, Supplement__c, Phone ';
        String searchStr = 'select Id, Name, Department__c, Type__c, AccountName__c, Supplement__c, Phone,AWS_Data_Id__c ';
         searchStr += ', City__c , State__c '; //2018/11/19 HWAG-B399RW 读取省和市
        searchStr += '        from Contact ';
        searchStr += '       where Isactive__c = \'有效\' ';
        searchStr += '       where Isactive__c = \'有效\' and AWS_Data_Id__c!=\'\' ';
        searchStr += '         and AccountId = :accountId ';
        if (searchCon.Search_LastName__c != null && searchCon.Search_LastName__c != '') {
            searchStr += '     and LastName like \'%' + searchCon.Search_LastName__c + '%\'';
        //2022/02/15 张华建 检索 start
        // if (searchCon.Search_LastName__c != null && searchCon.Search_LastName__c != '') {
        //     searchStr += '     and LastName like \'%' + searchCon.Search_LastName__c + '%\'';
        // }
        // if (searchCon.Search_FirstName__c != null && searchCon.Search_FirstName__c != '') {
        //     searchStr += '     and FirstName like \'%' + searchCon.Search_FirstName__c + '%\'';
        // }
        System.debug('awsDataIdArray = ' + awsDataIdArray);
        if (awsDataIdArray != null && awsDataIdArray != '') {
            String[] arr = awsDataIdArray.split(',');
            System.debug('arr = ' + arr);
            String awsDataIdSql = '';
            for(String s : arr){
                System.debug('s = ' + s);
                awsDataIdSql = awsDataIdSql + ',' + '\'' + s+'\'';
            }
            awsDataIdSql = awsDataIdSql.substring(1);
            System.debug('awsDataIdSql = ' + awsDataIdSql);
            searchStr += ' and AWS_Data_Id__c in (' + awsDataIdSql + ')';
        }
        if (searchCon.Search_FirstName__c != null && searchCon.Search_FirstName__c != '') {
            searchStr += '     and FirstName like \'%' + searchCon.Search_FirstName__c + '%\'';
        }
        //2022/02/15 张华建 检索 end
        system.debug('=====searchStr:' + searchStr);
        List<Contact> searchResult = Database.query(searchStr);
@@ -64,8 +107,8 @@
    public PageReference editContact() {
        if (conId != null && conId != '') {
            newCon = [select Id, Name, Department__c, Type__c, Search_LastName__c, Search_FirstName__c, Phone, Supplement__c,
                             FirstName, LastName
            newCon = [select Id, Name, Department__c, Type__c, Search_LastName__c, Search_FirstName__c, Phone, Supplement__c,LastName_Encrypted__c,Phone_Encrypted__c,
                      FirstName, LastName,AWS_Data_Id__c
                        from Contact where Id = :conId];
            newCon.Search_LastName__c = newCon.LastName;
            newCon.Search_FirstName__c = newCon.FirstName;
@@ -97,6 +140,11 @@
        return null;
    }
    public PageReference clearLineInfoList()  {
        lineInfoList = new List<LineInfo>();
        return null;
    }
    class LineInfo {
        public Integer lineNo { get; set; }
        public Contact con { get; set; }
force-app/main/default/classes/CampaignMemberController.cls
@@ -10,9 +10,12 @@
    public String saveflg { get; set; }
    public String errorStr { get; set; }
    // 20220216 PI改造 by 徐亮
    public String staticResource {get; set;}
    public CampaignMemberController() {
        campaignId = ApexPages.currentPage().getParameters().get('id');
        staticResource = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact')); // 20220216 PI改造 by 徐亮
    }
    public Integer getLineInfoListSize() {
@@ -35,9 +38,10 @@
        localuser = [select id, State_Hospital__c from User where id = :UserInfo.getUserId()];
        // 20220216 PI改造 by 徐亮
        List<CampaignMember__c> cmList = [
                                             select id, Name, Campaign__c, Department__c, Department_ID__c, Opportunity__c, Opportunity_ID__c,
                                             Contact__c, Contact_ID__c, Type__c, Contact_ID__r.Strategic_dept_Class__r.Name
                                             Contact__c, Contact_ID__c, Type__c, Contact_ID__r.Strategic_dept_Class__r.Name, Contact_ID__r.AWS_Data_Id__c
                                             from CampaignMember__c
                                             where Campaign__c = :campaignId];
force-app/main/default/classes/CampaignMemberServiceController.cls
@@ -10,9 +10,12 @@
    public String saveflg { get; set; }
    public String errorStr { get; set; }
    // 20220216 PI改造 by 徐亮
    public String staticResource {get; set;}
    public CampaignMemberServiceController() {
        campaignId = ApexPages.currentPage().getParameters().get('id');
        staticResource = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact')); // 20220216 PI改造 by 徐亮
    }
    public Integer getLineInfoListSize() {
@@ -35,9 +38,10 @@
        localuser = [select id, State_Hospital__c from User where id = :UserInfo.getUserId()];
        // 20220216 PI改造 by 徐亮
        List<CampaignMember__c> cmList = [
                                             select id, Name, Campaign__c, Department__c, Department_ID__c, Opportunity__c, Opportunity_ID__c,
                                             Contact__c, Contact_ID__c, Type__c, Contact_ID__r.Strategic_dept_Class__r.Name
                                             Contact__c, Contact_ID__c, Type__c, Contact_ID__r.Strategic_dept_Class__r.Name, Contact_ID__r.AWS_Data_Id__c
                                             , State__c, City__c // 2018/11/19 HWAG-B399RW 获取参会人员所在省和市
                                             from CampaignMember__c
                                             where Campaign__c = :campaignId];
force-app/main/default/classes/ConsumFixtureSetSelectController.cls
@@ -166,7 +166,7 @@
            saveType = false;
        }
        system.debug('==zheli1=='+this.parentId);
        caes = new Consum_Apply_Equipment_Set__c();
        caes.Consum_Start_Date__c = Date.today();
        //备品配套下的所有明细
@@ -190,7 +190,7 @@
                parentObj = parentObjs.get(0);
            }
            //Integer aaa=Integer.valueof(parentObjs);
        }
        if (parentObj == null) {
force-app/main/default/classes/ConsumReassignController.cls
@@ -1,4 +1,5 @@
public with sharing class ConsumReassignController {
    public string staticResource { get; private set; }
    // 明细行项目
    public List<LineInfo> lineInfoList { get; set; }
    //备品申请书ID
@@ -12,6 +13,7 @@
    public ConsumReassignController() {
        //Apexpages.currentPage().getHeaders().put('X-UA-Compatible', 'IE=8');
        caId = ApexPages.currentPage().getParameters().get('caid');
        staticResource = JSON.serialize(PIHelper.getPIIntegrationInfo('Consum_Apply_Equipment_Set_Detail__c'));
    }
    // 画面初始化
@@ -24,6 +26,7 @@
            // 耗材借出申请
            caesdList = [
                SELECT Id
                     , AWS_Data_Id__c
                     , Fixture_Model_No_F__c
                     , Asset__c
                     , Consum_Start_Date__c
force-app/main/default/classes/ConsumTrialController.cls
@@ -15,6 +15,8 @@
    public Boolean showEditButton{get;set;}
    private String case_OR_animal_organLabel{get;set;}
    private String saveType{get;set;}
    public String staticResource {get; set;}
    public String rowListString{set;get;}
    public ConsumTrialController(ApexPages.StandardController stdController) {
        parId = System.currentPageReference().getParameters().get('Id');
@@ -25,6 +27,8 @@
        if (String.isBlank(parId)) {
            parId = stdController.getId();
        }
        PIHelper.PIIntegration piIntegration = PIHelper.getPIIntegrationInfo('Consum_Apply_Equipment_Set_Detail__c');
        staticResource = JSON.serialize(piIntegration);
    }
    public void init() {
@@ -36,6 +40,7 @@
                        // , DateOfDelivery__c
                        // , ReceivingNoteNo__c
                        , Status__c
                        ,AWS_Data_Id__c
                        // , Asset_loaner_category__c
                        , RA_Status__c
                        , demo_purpose2__c
@@ -63,6 +68,7 @@
            assetFieldApiList.addAll(assetFieldApiSet);
            receivingNoteFieldApiList.addAll(receivingNoteFieldApiSet);
            pageB = new PageBean(rnList[0], assetFieldApiList, receivingNoteFieldApiList);
            rowListString = JSON.serialize(pageB.rowBList);
            showEditButton = (rnList[0].Status__c != '申请中' && rnList[0].Status__c != '取消');
        }
        catch (Exception e) {
@@ -408,6 +414,7 @@
                    + String.join(assetFieldApiList, ',')
                    + (assetFieldApiList.size() > 0 ? ',' : '')
                    + String.join(receivingNoteFieldApiList, ',')
                    + ',AWS_Data_Id__c'
                 + ' FROM Consum_Apply_Equipment_Set_Detail__c '
                + ' WHERE Consum_Apply_Equipment_Set__r.Consum_Apply__c = \'' + rn.Id + '\'' + wher
                  + ' AND (Cancel_Select__c = false OR NG_Select_Again__c = true)'
@@ -477,7 +484,7 @@
            // dataConfirmation = rnd1.DataConfirmation__c;
            lineNo = lineNo1 + 1;
            canChangeField = 'Show_demonstration__c, Operation_Type__c, Consum_Start_Date__c';
            canChangeField += ', Case_OR_animal_organ__c, Trial_User__c, Follower_User__c, Spare__c, Comment__c, Degree_Of_Importance__c';
            canChangeField += ',AWS_Data_Id__c, Case_OR_animal_organ__c, Trial_User__c, Follower_User__c, Spare__c, Comment__c, Degree_Of_Importance__c';
            haveAsset = String.isNotBlank(rnd1.Asset__c);
        }
force-app/main/default/classes/ConsumTrialPDFController.cls
@@ -21,12 +21,17 @@
    public Integer consumApplySetDetailListSize { get; set; }  // 耗材备品总数量
    public String errorMsg { get; set; }  // 错误信息
    public string staticResource { get; private set; }
    public string BRSrc{get;private set;}
    public string QRSrc{get;private set;}
    public ConsumTrialPDFController() {
        targetConsumApplyId = ApexPages.currentPage().getParameters().get('id');
        if (String.isBlank(targetConsumApplyId)) {
            throw new ControllerUtil.myException('参数错误:请指定Id。');
        }
        pdfPageList = new List<PdfPageClass>();
        staticResource = JSON.serialize(PIHelper.getPIIntegrationInfo('Consum_Apply_Equipment_Set_Detail__c'));
    }
    /**
@@ -40,6 +45,10 @@
            ApexPages.addMessage(new ApexPages.Message(ApexPages.severity.ERROR, errorMsg));
            return;
        }
        BRSrc = GetImageBase64(targetConsumApply.BRId__c);
        QRSrc = GetImageBase64(targetConsumApply.QRId__c);
        // 获取耗材备品配套一览明细
        List<Consum_Apply_Equipment_Set_Detail__c> targetConsumSetDetailList = getTargetConsumSetDetailList();
@@ -139,6 +148,7 @@
                     , Follower_User__r.Name
                     , Spare__c  // 备用
                     , Comment__c  // 备注
                     , AWS_Data_Id__c
                     , ManagementCode__c  // 管理编码 yc 耗材追溯
                     , EquipmentManagementCode__c  // 备品管理码 yc 耗材追溯
                  FROM Consum_Apply_Equipment_Set_Detail__c
@@ -207,4 +217,12 @@
            equipSetDetailList = new List<Consum_Apply_Equipment_Set_Detail__c>();
        }
    }
    public static string GetImageBase64(string id){
        List<Attachment> atts = [SELECT Id, IsDeleted, ParentId, Name, IsPrivate, ContentType, BodyLength, Body, OwnerId, CreatedDate, CreatedById, LastModifiedDate, LastModifiedById, SystemModstamp, Description FROM Attachment where id=:id];
        if (atts.size()==0) {
            return null;
        }
        return 'data:image/png;base64,' + EncodingUtil.base64Encode(atts[0].body);
    }
}
force-app/main/default/classes/ControllerResponse.cls
New file
@@ -0,0 +1,16 @@
public class ControllerResponse {
    @AuraEnabled
    public boolean IsSuccess{get;set;}
    @AuraEnabled
    public string Message{get;set;}
    @AuraEnabled
    public object Data{get;set;}
    public ControllerResponse(){
        IsSuccess = false;
        Message = '';
    }
}
force-app/main/default/classes/ControllerResponse.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/DeleteBatch.cls
New file
@@ -0,0 +1,20 @@
global class DeleteBatch implements Database.Batchable<sObject>{
    global String queryString;
    global DeleteBatch(String queryString){
        this.queryString = queryString;
    }
    global Database.QueryLocator start(Database.BatchableContext bc) {
        return Database.getQueryLocator(this.queryString);
    }
    global void execute(Database.BatchableContext BC, List<sObject> scope) {
        try{
            delete scope;
        }Catch(Exception e){
            system.debug('ERROR:' + e.getMessage());
        }
    }
    global void finish(Database.BatchableContext BC) {
    }
}
force-app/main/default/classes/DeleteBatch.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/DeveloperUtility.cls
New file
@@ -0,0 +1,62 @@
public class DeveloperUtility {
    public static List<HTTPResponse> CreateFields(string sobject_name,string [] fields){
        List<HTTPResponse> results = new List<HTTPResponse>();
        for(string f : fields){
            string old_label = f.removeEnd('__c').replace('_',' ');
            string label = old_label + ' Encrypted';
            string name =  label.replace(' ','_')+'__c';
            string description = '';
            system.debug('old_label='+old_label);
            system.debug('label='+label);
            system.debug('name='+name);
            results.add(CreateField(sobject_name,label,name,description,'Text'));
        }
        return results;
    }
    public static HTTPResponse CreateField(string sobject_name, string label,string name,string description,string type){
        HTTP h = new HTTP();
        HTTPRequest req = new HTTPRequest();
        req.setMethod('POST');
        req.setHeader('Content-Type', 'text/xml');
        req.setHeader('SOAPAction', 'create');
        //string sobject_name = 'Contact';
        //string label = 'Title';
        //string name =  'Title'+'_Encrypted__c';
        //string description = '';
        //string type = 'Text';
        boolean typeSpecified = true;
        String b = '<?xml version="1.0" encoding="UTF-8"?>';
        b += '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">';
        b += '<soapenv:Header>';
        b += '<ns1:SessionHeader soapenv:mustUnderstand="0" xmlns:ns1="http://soap.sforce.com/2006/04/metadata">';
        b += '<ns1:sessionId>' + UserInfo.getSessionId() + '</ns1:sessionId>';
        b += '</ns1:SessionHeader>';
        b += '</soapenv:Header>';
        b += '<soapenv:Body>';
        b += '<create xmlns="http://soap.sforce.com/2006/04/metadata">';
        b += '<metadata xsi:type="ns2:CustomField" xmlns:ns2="http://soap.sforce.com/2006/04/metadata">';
        b += '<type>'+type+'</type>';
        b += '<fullName>'+sobject_name+'.'+name+'</fullName>';
        b += '<label>'+label+'</label>';
        b += '<length>255</length>';
        b += '<description>'+type+'</description>';
        b += '</metadata>';
        b += '</create>';
        b += '</soapenv:Body>';
        b += '</soapenv:Envelope>';
        req.setBody(b);
        req.setCompressed(false);
        req.setEndpoint('https://ocsm--pipl.my.salesforce.com/services/Soap/m/25.0');
        HTTPResponse resp = h.send(req);
        System.debug(resp.getBody());
        return resp;
    }
}
force-app/main/default/classes/DeveloperUtility.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>53.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/FieldInfo.cls
New file
@@ -0,0 +1,44 @@
public class FieldInfo
{
    @AuraEnabled public string TypeEnumName{get;set;}
    @AuraEnabled public string Label{get;set;}
    @AuraEnabled public string Name{get;set;}
    @AuraEnabled public object Value{get;set;}
    //@AuraEnabled public schema.DisplayType DisplayType{get;set;}
    @AuraEnabled public List<Option> Options{get;set;}
    @AuraEnabled public boolean IsRequired{get;set;}
    @AuraEnabled public List<Option> References{get;set;}
    public Option GetFirstItemByLabel(string label){
        if(Options == null)return null;
        for(Option lv : Options){
            if(lv!=null&&lv.value == label)return lv;
        }
        return null;
    }
    public Option GetFirstItemByValue(string val){
        if(Options == null)return null;
        for(Option lv : Options){
            if(lv!=null&&lv.value == val)return lv;
        }
        return null;
    }
   public static void CopyTo(FieldInfo source,FieldInfo target)
   {
       if(source == null || target == null )
       {
           return;
       }
       target.TypeEnumName = source.TypeEnumName;
       target.Label = source.Label;
       target.Name = source.Name;
       target.IsRequired = source.IsRequired;
       target.Options = source.Options;
       target.Value = source.Value;
   }
}
force-app/main/default/classes/FieldInfo.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/FileUploadController.cls
New file
@@ -0,0 +1,68 @@
global without sharing class FileUploadController {
    public String staticResource {get; set;}
    public static String sobjectTypeValue = 'Document';
    public String PIPL_Input_PDF_Error_Msg{set;get;}
    public List<FileAddress__c>  fileList{set;get;}
    public Document documentData{set;get;}
    public String parentId{set;get;}
    public FileUploadController(ApexPages.StandardController controller) {
        staticResource = JSON.serialize(PIHelper.getPIIntegrationInfo('Document'));
        SObject obj = controller.getRecord();
        parentId = obj.Id;
        system.debug('Parent Id:'+parentId);
        fileList=getFileds(parentId);
    }
    global class Response{
        public String recordId{set;get;}
        public String message{set;get;}
        public String status{set;get;}
    }
    @RemoteAction
    global static Response saveFile(String fileName,String key,String transId,String parentId){
        FileAddress__c file = new FileAddress__c();
        PIHelper.PIIntegration pI=PIHelper.getPIIntegrationInfo('Document');
        file.DownloadLink__c =pI.undeleteUrl+key+'&fileName='+fileName;
        file.DownloadLink2__c =pI.undeleteUrl+key+'&fileName='+fileName;
        file.FileName__c =fileName;
        file.ViewLink__c =pI.queryUrl+key;
        file.ParentRecordId__c =parentId;
        file.AWS_File_Key__c = key;
        Response response =new Response();
        Savepoint sp = Database.setSavepoint();
        try {
            insert file;
            //4. 插入日志
            //update 20220218 加入新的日志方式
            PIHelper.saveTransLog(sobjectTypeValue,key,transId,file.Id,JSON.serialize(file),'success','');
            response.recordId=file.Id;
            response.status='success';
            return response;
        } catch (Exception e) {
            System.debug('into catch'+e.getMessage());
            PIHelper.saveTransLog(sobjectTypeValue,key,transId,file.Id,JSON.serialize(file),'fail',e.getMessage());
            Database.rollback(sp);
            response.message=e.getMessage();
            response.status='fail';
            return response;
        }
    }
    public PageReference refreshFiles() {
        system.debug('refresh files');
        fileList=getFileds(parentId);
        system.debug('fileList size:'+String.valueOf(fileList.size()));
        system.debug(JSON.serialize(fileList));
        return null;
    }
    public static List<FileAddress__c> getFileds(String parentId){
        if(String.isNotBlank(parentId)){
            return [SELECT Id,ParentRecordId__c, FileName__c,DownloadLink__c,DownloadLink2__c,FileAddress__c.ViewLink__c FROM FileAddress__c where ParentRecordId__c=:parentId order by createddate desc];
        }
        return [SELECT Id, ParentRecordId__c,FileName__c,DownloadLink__c,DownloadLink2__c,FileAddress__c.ViewLink__c FROM FileAddress__c order by createddate desc limit 100];
    }
}
force-app/main/default/classes/FileUploadController.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>52.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/FixtureRentalPDFController.cls
@@ -30,12 +30,18 @@
    public String centreAddress { get; set; }
    public Boolean IsShowLU { get; set; } //是否显示签收单左上角文字 true显示 20201119 LJH OCSM_BP5-61 add
    public Boolean IsMain; //是否是现地分配的主单 20201120 LJH OCSM_BP5-61 add
    public string staticResource { get; private set; }
    public Boolean addFlag { get; private set; }//敏感地址使用标记
    public String qrcode { get; private set; }
    public FixtureRentalPDFController() {
        pageNum = Integer.valueOf(ApexPages.currentPage().getParameters().get('page'));
        rentalApplyIdIMG = ApexPages.currentPage().getParameters().get('raid');
        //Apexpages.currentPage().getHeaders().put('X-UA-Compatible', 'IE=8');
        // rentalApplyId = ApexPages.currentPage().getParameters().get('raid');//20201120 ljh 
        String tempStr = ApexPages.currentPage().getParameters().get('raid');
        staticResource = JSON.serialize(PIHelper.getPIIntegrationInfo('Rental_Apply__c'));
        addFlag = false;
        rentalApplyId = new List<String>();
        if(tempStr != null){
           rentalApplyId.add(tempStr); 
@@ -96,13 +102,17 @@
                                Root_Rental_Apply__c,//20210617 ljh 1732 add
                                BRId__c, // 20211209 ljh SFDC-C923SR add 
                                QRImg__c,
                                QRId__c
                                QRId__c,
                                AWS_Data_Id__c,//20220304
                                Direct_Shippment_Address_Encrypt__c,//20220304
                                Phone_Number_Encrypt__c//20220304
                        from  Rental_Apply__c
                        where id = :rentalApplyId];
        }
        if(ApplyList.size()>0){
            ApplyHeadShow = ApplyList[0];
            qrcode = ConsumTrialPDFController.GetImageBase64(ApplyHeadShow.QRId__c);
        }
        //增加借出备品SET一览List,为了获取借出备品SET一览明细
        List<String> RAESSearchList = New List<String>();
@@ -191,6 +201,7 @@
            ShippMentAdr = ApplyHeadShow.Shippment_adress_detail__c;
        } else {
            ShippMentAdr = ApplyHeadShow.Direct_shippment_address__c;
            addFlag = true;
        }
        Integer ShipAdrSize = ShippMentAdr == null ? 0 : ShippMentAdr.length();
@@ -313,7 +324,6 @@
                        Rental_Apply_Equipment_Set__r.Name,
                        Rental_Apply_Equipment_Set__r.Fixture_Set__r.Name,
                        Rental_Apply_Equipment_Set__r.Loaner_code__c,
                        // Rental_Apply_Equipment_Set__r.Received_ng_detail__c,// 20220124 ljh SFDC-C4U3PH add start
                        FSD_Name_CHN__c,
                        Fixture_Name_text__c,
                        Fixture_Model_No_F__c,
@@ -607,8 +617,6 @@
        public String dQRCode { get; private set; }  //  二维码
        private Integer maxLineContact;
        public String wh_location { get; private set; }  //  货位号
        // 20220124 ljh SFDC-C4U3PH add start
        // public String Received_ng_detail { get; private set; }  //  收到确认NG内容
        public String name1 { get; private set; }
@@ -672,7 +680,6 @@
           //serialNumber2 = esd2.SerialNumber__c;
           height = height ==null ? MAXLINEHRIGHT: height;
           wh_location = raesd.Asset__r.WH_location__c;
           // Received_ng_detail = raesd.Rental_Apply_Equipment_Set__r.Received_ng_detail__c; // 20220124 ljh SFDC-C4U3PH add start
        }
    }
    // Data Bean
force-app/main/default/classes/InsReportPDFController.cls
@@ -11,6 +11,10 @@
    public String endfen {get;set;}
    //add by rentx 20210707 end
    
    // 20220222 PI改造 by Bright---start
    public string staticResource { get; private set; }
    // 20220222 PI改造 by Bright---end
    public Integer getItemCount() {
        return itemList.size();
    }
@@ -27,6 +31,12 @@
    
    private static Integer commentMax = 15;
    
    public InsReportPDFController(){
        // 20220222 PI改造 by Bright---start
        staticResource = JSON.serialize(PIHelper.getPIIntegrationInfo('Inspection_Report__c'));
        // 20220222 PI改造 by Bright---end
    }
    public void init() {
        //add by rentx 20210707 start
        startfen = '';
force-app/main/default/classes/InstructReportController.cls
@@ -6,9 +6,14 @@
    public list<InstructedstaffInfo> checkedISList { get; private set; }
    public list<InstructedstaffInfo> uncheckedISList { get; private set; }
    public boolean ReadOnly { get; private set; }
    // 20220222 PI改造 by Bright--start
    public string staticResource { get; private set; }
    // 20220222 PI改造 by Bright--end
    public InstructReportController() {
        this.ReadOnly = true;
        staticResource = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));// 20220222 PI改造 by Bright
    }
    public InstructReportController(ApexPages.StandardController controller) {
        this();
@@ -102,6 +107,7 @@
                                             Is_Active_Formula__c
                                             //增加检索 有效/无效 精琢技术 wql 2021/02/04 end
                                             ,Contact_ID__c, Contact_ID__r.Name,
                                             Contact_ID__r.AWS_Data_Id__c,// 20220222 PI改造 by Bright
                                             // LJPH-BVNBMM start
                                             Contact_ID__r.AccountId,
                                             Department_Service__c,
@@ -123,6 +129,7 @@
             ,Is_Active_Formula__c
             //增加检索 有效/无效 精琢技术 wql 2021/02/04 end
             , ContactID__C
             ,ContactID__r.AWS_Data_Id__c// 20220222 PI改造 by Bright
             //带教报告 新增查询字段:带教地点、带教地点(其他)、设备类别、具体型号、备注 精琢技术 wql 2020/04/14 start
             , Instruct_place_other__c, Specific_model__c,
             Instruct_remarks__c, Equipment_category__c, Instruct_place__c, Instruct_content__c
@@ -169,12 +176,14 @@
        for (InstructedstaffInfo uncheckedIS : uncheckedISList) {
            if (uncheckedIS.rec_checkBox) {
                System.debug('uncheckedIS.CamMem.Contact_ID__r='+uncheckedIS.CamMem.Contact_ID__r.AWS_Data_Id__c);
                uncheckedIS.IS = new Instructed_staff__c(Name = uncheckedIS.CamMem.Contact_ID__r.Name,
                        // LJPH-BVNBMM 改为同步当前联系人所在的科室 start
                        Department__c = uncheckedIS.CamMem.Contact_ID__r.AccountId,
                        // LJPH-BVNBMM 改为同步当前联系人所在的科室 start
                        CampaignMember__c = uncheckedIS.CamMem.id,
                        ContactID__c = uncheckedIS.CamMem.Contact_ID__c
                        ContactID__c = uncheckedIS.CamMem.Contact_ID__c,
                        ContactID__r = uncheckedIS.CamMem.Contact_ID__r // 20220222 PI改造 by Bright
                         );
                uncheckedIS.lineNo = temuncheckedISList.size();
                temcheckedISList.add(uncheckedIS);
force-app/main/default/classes/LayoutDescriberHelper.cls
@@ -10,11 +10,29 @@
public class LayoutDescriberHelper {
    public static String urlPrefixToUse {get;set;}
    public static Set<String> ConcatenationNameSType = new Set<String>{'Lead','Contact'};
    public static List<String> requiredFieldAPIList{set;get;}
    public static Map<String,String> fieldAPIToLabelMap{set;get;}
    public static Set<String> CaseWebFields = new Set<String>{'SuppliedCompany','SuppliedName','SuppliedEmail','SuppliedPhone'};
    public static Set<String> ConcatenationNameSType = new Set<String>{'Lead','Contact'};
    public static LayoutWrapper describeSectionWithFieldsWrapper(Id recordTypeId, String objectType,String userMode){
        if(String.isEmpty(recordTypeId)){
            //Assign default record type for sobject
            recordTypeId = getDefaultRecordType(objectType);
        }
        List<LayoutSection> layoutSections = describeSectionWithFields(recordTypeId,objectType,userMode);
        LayoutWrapper layoutWrapperValue = new LayoutWrapper();
        layoutWrapperValue.layoutSections = layoutSections;
        layoutWrapperValue.requiredFieldAPIList = requiredFieldAPIList;
        layoutWrapperValue.fieldAPIToLabelMap = fieldAPIToLabelMap;
        system.debug('required API List:'+JSON.serialize(requiredFieldAPIList));
        return layoutWrapperValue;
    }
    public static List<LayoutSection> describeSectionWithFields(Id recordTypeId, String objectType,String userMode){
        system.debug('record type id ===>'+ recordTypeId+' object type===>'+objectType + ' userMode===>'+userMode);
        List<LayoutSection> layoutSections;
        Map<String,List<LayoutField>> layoutFields;
        requiredFieldAPIList = new List<String>();
        fieldAPIToLabelMap = new Map<String,String>();
        layoutSections = new List<LayoutSection>();
        String theRespBody = getLayoutSchema(recordTypeId, objectType,userMode);      
        Map<String, Object> layoutSection = (Map<String, Object>) JSON.deserializeUntyped(theRespBody);
@@ -87,18 +105,28 @@
                                    lf.isPlaceHolder = placeholderF;
                                    lf.editableField = isEditable;
                                    lf.fieldAPI = fieldLabelPrefix+addressType;
                                    lf.fieldLabel = fieldLabelPrefix+' '+addressType;
                                    lf.fieldType = 'string';
                                    lf.fieldType = 'string';
                                    if(ls.Name != '' || layoutSections.size() == 1){
                                        ls.layoutFields.add(lf);
                                    }else if(layoutSections.size() - 2 >= 0){
                                        layoutSections.get(layoutSections.size() - 2).layoutFields.add(lf); 
                                    }
                                    }
                                    if(lf.isRequired){
                                        requiredFieldAPIList.add(lf.fieldAPI);
                                    }
                                    if(string.isBlank(lf.fieldAPI)){
                                        system.debug('==================================2');
                                        continue;
                                    }else{
                                        fieldAPIToLabelMap.put(lf.fieldAPI,lf.fieldLabel);
                                    }
                                }
                                continue;
                            }
                            if(userMode == 'classic' && apiName == 'Name' && ConcatenationNameSType.contains(objectType)){
                                List<String> nameDetail = new List<String>{'LastName'};
                                List<String> nameDetail = new List<String>{'Salutation','LastName'};
                                for(String nameField:nameDetail){
                                    LayoutField lf = new LayoutField();
                                    lf.isRequired = (Boolean)fields.get('required');
@@ -111,8 +139,20 @@
                                        ls.layoutFields.add(lf);
                                    }else if(layoutSections.size() - 2 >= 0){
                                        layoutSections.get(layoutSections.size() - 2).layoutFields.add(lf); 
                                    }
                                    }
                                    if(lf.isRequired){
                                        requiredFieldAPIList.add(lf.fieldAPI);
                                    }
                                    if(string.isBlank(lf.fieldAPI)){
                                        system.debug('==================================3');
                                        continue;
                                    }else{
                                        fieldAPIToLabelMap.put(lf.fieldAPI,lf.fieldLabel);
                                    }
                                }
                                continue;
                            }
                            if(objectType == 'Case' && CaseWebFields.contains(apiName)){
                                continue;
                            }
                            LayoutField lf = new LayoutField();
@@ -126,7 +166,17 @@
                                ls.layoutFields.add(lf);
                            }else if(layoutSections.size() - 2 >= 0){
                                layoutSections.get(layoutSections.size() - 2).layoutFields.add(lf);
                            }
                            }
                            if(lf.isRequired){
                                requiredFieldAPIList.add(lf.fieldAPI);
                            }
                            if(string.isBlank(lf.fieldAPI)){
                                system.debug('==================================1');
                                continue;
                            }else{
                                fieldAPIToLabelMap.put(lf.fieldAPI,lf.fieldLabel);
                            }
                            priorFieldLayoutAdded = true;
                        }else
                            priorFieldLayoutAdded = false;
@@ -138,6 +188,7 @@
            }
        }
        System.debug('Layout Section Result:'+JSon.serialize(layoutSections));
        system.debug('required API List:'+JSON.serialize(requiredFieldAPIList));
        return layoutSections;
    }
    public static String getUrlPrefix(){
@@ -159,6 +210,7 @@
        req.setMethod('GET');        
        if(userMode =='lightning'){
            req.setEndPoint('callout:SF_Rest_API'+urlPost);
            system.debug('callout:SF_Rest_API'+urlPost);
        }else if(userMode == 'classic'){
            req.setEndpoint(urlForClassic); 
            req.setHeader('Authorization', 'Bearer ' + UserInfo.getsessionid());
@@ -169,8 +221,10 @@
        return resp.getBody();
    }
    public static Id  getDefaultRecordType(SObject obj) {
        Schema.DescribeSObjectResult describeResult = obj.getsObjectType().getDescribe();
    public static Id  getDefaultRecordType(String ObjectName) {
        Map<String, Schema.SObjectType> GlobalDescribeMap = Schema.getGlobalDescribe();
        Schema.SObjectType obj = GlobalDescribeMap.get(ObjectName);
        Schema.DescribeSObjectResult describeResult = obj.getDescribe();
        List<Schema.RecordTypeInfo> rtInfos = describeResult.getRecordTypeInfos();
        for(Schema.RecordTypeInfo rtInfo : rtInfos) {
            if(rtInfo.DefaultRecordTypeMapping) {              
@@ -179,7 +233,11 @@
        }
        return null;
    }
    public class LayoutWrapper{
        @AuraEnabled public List<LayoutSection> layoutSections{set;get;}
        @AuraEnabled public List<String> requiredFieldAPIList{set;get;}
        @AuraEnabled public Map<String,String> fieldAPIToLabelMap{set;get;}
    }
    public class LayoutSection{
        @AuraEnabled public boolean useHeader {get;set;}
        @AuraEnabled public String name {get;set;}
force-app/main/default/classes/LeadIntentionController.cls
@@ -1,4 +1,4 @@
public with sharing class LeadIntentionController {
public without sharing class LeadIntentionController {
        public List<PCLInfo> pclInfos { get; set; }
    
    /*****************検索用******************/
@@ -72,6 +72,8 @@
    private String soqlForMoneyWithoutSort = null;
    private static Integer searchLimit = 1000;
    public String staticResource {get; set;}
    public String awsDataIds {get; set;}
    public LeadIntentionController() {
        pclInfos = new List<PCLInfo>();
@@ -134,6 +136,7 @@
        isActiveFormula = '有效';
        staticResource = JSON.serialize(PIHelper.getPIIntegrationInfo('Inquiry_form__c'));
    }
    public PageReference init() {
@@ -178,7 +181,12 @@
        System.debug('最后取得:'+pclInfos.size());
        pclCount = pclInfos.size();
        ApexPages.addmessage(new ApexPages.message(ApexPages.severity.INFO, '取得最近的 ' + pclCount + ' 条数据'));
        List<String> a = new List<String>();
        for(Inquiry_form__c ifc : queryList){
            a.add(ifc.AWS_Data_Id__c);
        }
        awsDataIds = JSON.serialize(a);
        return null;
    }
@@ -355,7 +363,7 @@
                + ' Opp_Name_Search__c, Opportunity_Division__c, LeadSource__c, Campaign__c,'
                + ' Urgent__c, Request_Detail__c ,Contact_Id__c,Hospital_ID__c,Department_ID__c,Opp_Name_Search_ID__c,'
                + 'Campaign_ID__c,Last_Name__c,Family_Name__c,Name,Reasons_options__c,'
                + 'Product1__c,Confirmation_Date__c'
                + 'Product1__c,Confirmation_Date__c,AWS_Data_Id__c'
                //,Lead_link__c
                + ' from Inquiry_form__c where Id != null ';
                //2021-11-24  mzy  共通平台项目-首页修改  start
force-app/main/default/classes/LightningUtil.cls
@@ -16,6 +16,21 @@
        return [select Id, Agency_Hospital__c, IsOlympusContact__c, Name, Doctor_Division1__c, Type__c, Hospital_DC_Name__c,Department_Cateogy_F__c,Hospital_Name__c from Agency_Contact__c 
                    where (Department_Class__r.Hospital_Department_Class__c in :hospitalSet or (Department_Class__c = null and Agency_Hospital__c in :aHospitalSet)) and Name like :conStr and Hospital_DC_Name__c like :hosStr order by Name];
    }
    // 20220222 PI改造 by Bright--start
    public static List<Agency_Contact__c> searchOCMAgencyContact(Set<String> hospitalSet, Set<String> aHospitalSet, String hosStr, List<string> awsids) {
        string sql = 'select Id, Agency_Hospital__c, IsOlympusContact__c, Name, Doctor_Division1__c, Type__c, Hospital_DC_Name__c,Department_Cateogy_F__c,Hospital_Name__c,AWS_Data_Id__c from Agency_Contact__c';
        sql += ' where (Department_Class__r.Hospital_Department_Class__c in :hospitalSet or (Department_Class__c = null and Agency_Hospital__c in :aHospitalSet)) and Hospital_DC_Name__c like :hosStr';
        if (awsids!=null && awsids.size()>0) {
            sql += ' and AWS_Data_Id__c in :awsids ';
        }
        sql += ' order by Hospital_DC_Name__c';
        system.debug('sql='+sql);
        return Database.query(sql);
    }
    // 20220222 PI改造 by Bright--end
    public static List<Contact> selectContact(String cId) {
        return [select Id, AccountId, Name from Contact where id=:cId];
    }
@@ -67,6 +82,21 @@
        // return data;
    }
    // PIPL update Yin Mingjie 21/02/2022 start
    public static Map<String, String> insertAgencyContact(Agency_Contact__c data) {
        Map<String, String> acmap = new Map<String, String>();
        acmap.put('AgencyContactId', '');
        acmap.put('errormsg', '');
        try {
            insert data;
            acmap.put('AgencyContactId', data.Id);
        } catch (Exception e) {
            acmap.put('errormsg', e.getMessage());
        }
        return acmap;
    }
    // PIPL update Yin Mingjie 21/02/2022 end
    public static Agency_Report__c insertAgencyReport(Agency_Report__c data) {
        if (String.isBlank(data.Hospital__c)) {
            List<Agency_Hospital_Link__c> agency_hospital_link = [select Id, Hospital__c from Agency_Hospital_Link__c where Id=:data.Agency_Hospital__c];
@@ -117,6 +147,7 @@
            List<Contact> person_list = selectAgencyPerson();
            return [Select Id, Name, Report_Date__c, Product_Category1__r.Name, Product_Category2__r.Name, Product_Category3__r.Name, Product_Category1__c, Product_Category2__c, Product_Category3__c,ConsumptionOfConsumables__c, WorkMark__c,warlocksNumber__c,Department_Cateogy__c,ProductClassification__c,WarlockClassification__r.WarlockClassification__c,WarlockClassification__c,ProductCcategory__c, ProductCcategory__r.ProductCcategory__c,productCategories__c, productCategories__r.productCategories__c,DealerPersonnel__c,WorkRecord__c, Agency_Report_Header__c, Agency_Hospital__r.Name, Agency_Hospital__r.Hospital__c, OppName__c,
                            Person_In_Charge2__c,DealerPersonnel__r.Name, Person_In_Charge2__r.Name, doctor2__c, doctor2__r.Name, Submit_date__c,
                            doctor2__r.AWS_Data_Id__c,// 20220222 PI改造 by Bright
                            Product_Category__c, Product_Category__r.Name, Result__c, visitor_title__c, Opportunity__c, Opportunity__r.Name,EffectProgress__r.EffectProgress__c,EffectProgress__c,
                            UseProduct1__c,UseProduct2__c,UseProduct3__c,UseProduct1__r.Name,UseProduct2__r.Name,UseProduct3__r.Name    
                            From Agency_Report__c
@@ -124,6 +155,7 @@
        } else {
            return [Select Id, Name, Report_Date__c, Product_Category1__r.Name, Product_Category2__r.Name, Product_Category3__r.Name, Product_Category1__c, Product_Category2__c, Product_Category3__c,ConsumptionOfConsumables__c, WorkMark__c,warlocksNumber__c,Department_Cateogy__c,DealerPersonnel__c,ProductClassification__c,WarlockClassification__r.WarlockClassification__c,WarlockClassification__c,ProductCcategory__c,ProductCcategory__r.ProductCcategory__c, productCategories__c, productCategories__r.productCategories__c,WorkRecord__c, Agency_Report_Header__c, Agency_Hospital__r.Name, Agency_Hospital__r.Hospital__c, OppName__c,
                            Person_In_Charge2__c,DealerPersonnel__r.Name, Person_In_Charge2__r.Name, doctor2__c, doctor2__r.Name, Submit_date__c,
                            doctor2__r.AWS_Data_Id__c,// 20220222 PI改造 by Bright
                            Product_Category__c, Product_Category__r.Name, Result__c, visitor_title__c, Opportunity__c, Opportunity__r.Name,EffectProgress__r.EffectProgress__c,EffectProgress__c,
                            UseProduct1__c,UseProduct2__c,UseProduct3__c,UseProduct1__r.Name,UseProduct2__r.Name,UseProduct3__r.Name   
                            From Agency_Report__c
@@ -138,12 +170,14 @@
            return [Select Id, Name, Report_Date__c, Product_Category1__r.Name, Product_Category2__r.Name, Product_Category3__r.Name, Product_Category1__c, Product_Category2__c, Product_Category3__c,ConsumptionOfConsumables__c, WorkMark__c,warlocksNumber__c,Department_Cateogy__c,ProductClassification__c,WarlockClassification__r.WarlockClassification__c,WarlockClassification__c,ProductCcategory__c,ProductCcategory__r.ProductCcategory__c,productCategories__c, productCategories__r.productCategories__c, DealerPersonnel__c,WorkRecord__c, Agency_Report_Header__c, Agency_Hospital__r.Name, Agency_Hospital__r.Hospital__c, OppName__c,
                            Person_In_Charge2__c,DealerPersonnel__r.Name, Person_In_Charge2__r.Name, doctor2__c, doctor2__r.Name, Submit_date__c,
                            Product_Category__c, Product_Category__r.Name, Result__c, visitor_title__c, Opportunity__c, Opportunity__r.Name,EffectProgress__r.EffectProgress__c,EffectProgress__c,
                            doctor2__r.AWS_Data_Id__c,// 20220222 PI改造 by Bright
                            UseProduct1__c,UseProduct2__c,UseProduct3__c,UseProduct1__r.Name,UseProduct2__r.Name,UseProduct3__r.Name    
                            From Agency_Report__c
                            where Submit_date__c=:week and Person_In_Charge2__c in :person_list and WeeklyReportClassification__c != '' order by LastModifiedDate desc];
        } else {
            return [Select Id, Name, Report_Date__c, Product_Category1__r.Name, Product_Category2__r.Name, Product_Category3__r.Name, Product_Category1__c, Product_Category2__c, Product_Category3__c,ConsumptionOfConsumables__c, WorkMark__c,warlocksNumber__c,Department_Cateogy__c,DealerPersonnel__c,ProductClassification__c,WarlockClassification__r.WarlockClassification__c,WarlockClassification__c,ProductCcategory__c,ProductCcategory__r.ProductCcategory__c,productCategories__c, productCategories__r.productCategories__c, WorkRecord__c, Agency_Report_Header__c, Agency_Hospital__r.Name, Agency_Hospital__r.Hospital__c, OppName__c,
                            Person_In_Charge2__c,DealerPersonnel__r.Name, Person_In_Charge2__r.Name, doctor2__c, doctor2__r.Name, Submit_date__c,
                            doctor2__r.AWS_Data_Id__c,// 20220222 PI改造 by Bright
                            Product_Category__c, Product_Category__r.Name, Result__c, visitor_title__c, Opportunity__c, Opportunity__r.Name,EffectProgress__r.EffectProgress__c,EffectProgress__c,
                            UseProduct1__c,UseProduct2__c,UseProduct3__c,UseProduct1__r.Name,UseProduct2__r.Name,UseProduct3__r.Name   
                            From Agency_Report__c
@@ -164,6 +198,7 @@
    public static List<Agency_Report__c> selectMAgencyReport01(Date date1, Date date2 ,List<Contact> conMList) {
        List<Agency_Report__c> reportlist = [Select Id, Name, Report_Date__c, Product_Category1__r.Name, Product_Category2__r.Name, Product_Category3__r.Name, Product_Category1__c, Product_Category2__c, Product_Category3__c,ConsumptionOfConsumables__c,warlocksNumber__c,WorkMark__c,Department_Cateogy__c, DealerPersonnel__c,WorkRecord__c, ProductClassification__c,WarlockClassification__r.WarlockClassification__c,WarlockClassification__c,ProductCcategory__c,ProductCcategory__r.ProductCcategory__c,productCategories__c, productCategories__r.productCategories__c,Agency_Report_Header__c, Agency_Hospital__r.Name, Agency_Hospital__r.Hospital__c, OppName__c,
                            Person_In_Charge2__c,DealerPersonnel__r.Name,Person_In_Charge2__r.Name, doctor2__c, doctor2__r.Name, Submit_date__c,
                            doctor2__r.AWS_Data_Id__c,// 20220222 PI改造 by Bright
                            Product_Category__c, Product_Category__r.Name, Result__c, visitor_title__c, Opportunity__c, Opportunity__r.Name,EffectProgress__r.EffectProgress__c,EffectProgress__c,
                            UseProduct1__c,UseProduct2__c,UseProduct3__c,UseProduct1__r.Name,UseProduct2__r.Name,UseProduct3__r.Name  
                            From Agency_Report__c
@@ -174,6 +209,7 @@
    public static List<Agency_Report__c> selectAgencyReportById(String report_id) {
        return [Select Id, Name, Department_Cateogy__c, ConsumptionOfConsumables__c,warlocksNumber__c,WorkMark__c,WorkRecord__c,EffectProgress__c,ProductClassification__c,ProductCcategory__c,productCategories__c, Agency_Report_Header__c, Agency_Hospital__r.Name, Agency_Hospital__r.Hospital__c, OppName__c,
                            Person_In_Charge2__c,DealerPersonnel__c,DealerPersonnel__r.Name, Person_In_Charge2__r.Name, doctor2__c, doctor2__r.Name, Submit_date__c,
                            doctor2__r.AWS_Data_Id__c,// 20220222 PI改造 by Bright
                            Product_Category__c, Product_Category__r.Name, Result__c, visitor_title__c 
                            From Agency_Report__c
                            where id=:report_id ];
@@ -182,6 +218,7 @@
    public static List<Agency_Report__c> selectAgencyReportById01(String report_id) {
        return [Select Id, Name, Department_Cateogy__c, ConsumptionOfConsumables__c,warlocksNumber__c,WorkMark__c,WorkRecord__c,EffectProgress__c,ProductClassification__c,ProductCcategory__c,productCategories__c, Agency_Report_Header__c, Agency_Hospital__r.Name, Agency_Hospital__r.Hospital__c, OppName__c,
                            Person_In_Charge2__c,DealerPersonnel__c,DealerPersonnel__r.Name, Person_In_Charge2__r.Name, doctor2__c, doctor2__r.Name, Submit_date__c,
                            doctor2__r.AWS_Data_Id__c,// 20220222 PI改造 by Bright
                            Product_Category__c, Product_Category__r.Name, Result__c, visitor_title__c 
                            From Agency_Report__c
                            where id=:report_id ];
force-app/main/default/classes/MetaDataUtility.cls
New file
@@ -0,0 +1,177 @@
public without sharing class MetaDataUtility {
    public static List<Metadata.LayoutSection> GetRecordTypePageLayout(string record_type_id,string objectType){
        Map<string,object> mso = null;
        string layout_name = GetRecordTypePageLayoutName(record_type_id,objectType,UserInfo.getProfileId());
        List<Metadata.LayoutSection>  temp =  GetLayoutSections(objectType,layout_name);
        List<Metadata.LayoutSection>  layoutSectionList = new List<Metadata.LayoutSection>();
        for(Metadata.LayoutSection section : temp){
            boolean a = false;
            for( Metadata.LayoutColumn c: section.layoutColumns){
                //system.debug(c);
                if(c.layoutItems != null && c.layoutItems.size() > 0 ){
                    a = true;
                }
            }
            if(a){
                layoutSectionList.add(section);
            }
        }
        return layoutSectionList;
    }
    /*[{
            "attributes": {
                "type": "Layout",
                "url": "/services/data/v53.0/tooling/sobjects/Layout/00h10000009iAb5AAE"
            },
            "Id": "00h10000009iAb5AAE",
            "Name": ".客户人员レイアウト",
            "TableEnumOrId": "01I10000000er3hEAA",
            "LayoutType": "Standard"
        }]
     */
    public static string GetTableOrEnumId(string objectType){
        Map<string,object> mso = null;
        string resp = null;
        string table_or_enum_id = objectType;
        if(objectType.endsWith('__c')){
            resp = ToolingQuery('SELECT id,DeveloperName from CustomObject where DeveloperName =\''+objectType.replace('__c', '')+'\'');
            if(resp == null){
                system.debug('resp is not ok');
                return null;
            }else{
                mso = (Map<string,object>)Json.deserializeUntyped(resp);
                if(integer.valueOf(mso.get('size')) > 0){
                    table_or_enum_id =  string.valueOf(((Map<string,object>)(((List<object>)mso.get('records'))[0])).get('Id'));
                }else{
                    system.debug('no records');
                    return null;
                }
            }
        }
        return table_or_enum_id;
    }
    public static List<object> GetAllPageLayout(string objectType){
        string resp = null;
        Map<string,object> mso = null;
        string table_or_enum_id =  GetTableOrEnumId(objectType);
        if(string.isBlank(table_or_enum_id)){
            return new List<object>();
        }
        resp = ToolingQuery('SELECT id,name,TableEnumOrId,LayoutType  FROM Layout where TableEnumOrId = \''+table_or_enum_id+'\'');
        if(resp == null){
            system.debug('Layout where TableEnumOrId='+table_or_enum_id+' is null');
            return null;
        }else{
            mso = (Map<string,object>)Json.deserializeUntyped(resp);
            if(integer.valueOf(mso.get('size')) > 0){
                return (List<object>)mso.get('records');
            }else{
                system.debug('no records');
                return new List<object>();
            }
        }
    }
    public static string GetRecordTypePageLayoutName(string record_type_id,string objectType, string profile_id){
        if(!string.isBlank(objectType)){
            List<sobject> lso = [SELECT Id, Name, DeveloperName, SobjectType, IsActive, Description, BusinessProcessId FROM RecordType where SobjectType = :objectType];
            if(lso.size()==0){
                return string.valueOf(((Map<string,object>)(GetAllPageLayout(objectType)[0])).get('Name'));
            }
        }
        // 01210000000QfWdAAK
        string query = 'SELECT Layout.Name, Layout.TableEnumOrId, ProfileId, Profile.Name, RecordTypeId FROM ProfileLayout where id!=null ';
        if(!string.isBlank(record_type_id)){
            query += ' and RecordTypeId = \''+record_type_id+'\'';
        }
        if(!string.isBlank(objectType)){
            query += ' and TableEnumOrId = \''+ GetTableOrEnumId(objectType) +'\'';
        }
        if(!string.isBlank(profile_id)){
            query += ' and ProfileId = \''+profile_id+'\'';
        }
        query += ' order by LastModifiedDate desc ';
        system.debug('query='+query);
        string s = ToolingQuery(query);
        if(string.isBlank(s)){
            system.debug('s is blank');
            return null;
        }else{
            Map<string,object> mso = (Map<string,object>)JSON.deserializeUntyped(s);
            if(integer.valueOf(mso.get('size')) > 0){
                List<object> records = ((List<object>)mso.get('records'));
                mso = (Map<string,object>)(records[0]);
                return string.valueOf(((Map<string,object>)(mso.get('Layout'))).get('Name'));
            }else{
                return null;
            }
        }
    }
    public static string ToolingQuery(string query){
        system.debug('query='+query);
        String baseURL = 'callout:SF_Rest_API/services/data/v41.0/tooling/query?q='+ query.replace(' ', '+');
        HttpResponse resp = null;
        HttpRequest req = new HttpRequest();
        req.setMethod('GET');
        //req.setHeader('Authorization', 'Bearer ' + UserInfo.getsessionid());
        //req.setEndpoint(baseURL);
        req.setEndpoint(baseURL);
        Http client = new Http();
        resp = client.send(req);
        system.debug(resp.getStatus());
        system.debug(resp.getStatusCode());
        if(resp.getStatus() == 'OK'){
            string s = resp.getBody();
            system.debug(resp.getBody());
            return s;
        }else{
            system.debug('status is not ok,error:'+resp.getBody());
            return null;
        }
    }
    public static List<Metadata.LayoutSection> GetLayoutSections(string object_name, string layout_name){
        List<String> componentNameList = new List<String>{object_name+'-'+layout_name};
        //通过Metadata.Operations.retrieve获取metadata
        //Metadata.Layout -> Metadata.LayoutSection -> Metadata.LayoutColumn objects -> Metadata.LayoutItem objects
        List<Metadata.Metadata> componentList = Metadata.Operations.retrieve(Metadata.MetadataType.Layout, componentNameList);
        if(componentList?.size() > 0){
            Metadata.Layout layout = (Metadata.Layout) componentList.get(0);
            List<Metadata.LayoutSection> layoutSectionList = layout.layoutSections;
            return layoutSectionList;
        }
        else{
            return null;
        }
    }
}
force-app/main/default/classes/MetaDataUtility.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/NFM103Controller.cls
@@ -103,6 +103,9 @@
        public String ReturnType;//返品方式
        public String UpdateStatus;//直返修改标识
        //add by wangweipeng  2021/07/14   end
        //add pi 加密 sushanhu 20220222 start
        public String DataId;//AWS存储凭证
        //add pi 加密 sushanhu 20220222 end
    }
    ////NFM103修改Rest end
@@ -327,7 +330,7 @@
                                         ,Returns_Product_way__c    //返品方式
                                         ,FSE_ApplyForRepair_time__c    //申请修理时间
                                         //add by wangweipeng  2021/07/14   start
                                         ,AWS_Data_Id__c //add by sushanhu AWSDateID for PIPL
                                         from Repair__c where Id IN :repairIds];          // 削除データを検索しないはず、All ROWS いらないはず
            System.debug(Logginglevel.DEBUG, 'NFM103_ recptList.size()=' + recptList.size());
@@ -472,7 +475,11 @@
                 element.Postal                     = rpr.address_ZipCode__c;    //邮编
                 element.ReturnType                 = NFMUtil.getMapValue(ReturnsProductWayMap,'Returns_Product_way__c', rpr.Returns_Product_way__c, iflog);//返品方式
                 element.UpdateStatus               = rpr.Address_type__c;    //申请修理时间
                 //add by wangweipeng  2021/07/14   start
                 //add by wangweipeng  2021/07/14   end
                 //add pi 密文 sushanhu 20220222 start
                 element.DataId                     =rpr.AWS_Data_Id__c;//aws存储凭证
                 //add pi 密文 sushanhu 20220222 end
            }
            if (repairRequest.GeneralData.size() > 0) {
@@ -571,10 +578,24 @@
            // NFM103修改Rest end
            // WLIG-BXQBH6 start
            NFMUtil.response response =
                NFMUtil.sendToSapStatusAndBody(rowDataStr, NFMUtil.NFM103_ENDPOINT);
            status = response.status;
            // NFMUtil.response response =
            //     NFMUtil.sendToSapStatusAndBody(rowDataStr, NFMUtil.NFM103_ENDPOINT);
                //update to aws 20220222 sushanhu start for PIPL
                NFMUtil.response res = NFMUtil.getAwsToken();
                String token=res.responseBody;
                if(String.isBlank(token)){
                    iflog.ErrorLog__c='NFM103'+'获取aws token 失败';
                }
                NFMUtil.response response =     NFMUtil.sendToPiAWS(rowDataStr, NFMUtil.NFM103_ENDPOINT,token);
                //update to aws 20220222 sushanhu end for PIPL
                status = response.status;
                system.debug('AWS Response status:'+status);
            ResponseBody = response.responseBody;
            //update to aws 20220302 sushanhu start for PIPL
            Map<String, Object> results = (Map<String, Object>)JSON.deserializeUntyped(ResponseBody);
            system.System.debug('NGM103 AWS result--'+ ResponseBody);
            //update to aws 20220302 sushanhu end for PIPL
            NFM103Response NFM103Response = new NFM103Response();
            system.debug(ResponseBody);
            if (string.isNotEmpty(ResponseBody)) {
force-app/main/default/classes/NFM203Rest.cls
@@ -1,6 +1,9 @@
@RestResource(urlMapping = '/NFM203/*')
global with sharing class NFM203Rest {
    //add Response to aws 20220221 add sushanhu
    static Boolean SFStatus=true;
    static String SFMessage='';
    global class GeDatas {
        public NFMUtil.Monitoring Monitoring;
        public GeData[] Partners;
@@ -78,7 +81,7 @@
        public String BusinessAddress;          //经营场所(等同办公地址)
        //WLIG-CA48WC pk start 2022-1-7
        public String RegisterAddress;          //住所地址
        //WLIG-CA48WC pk end 2022-1-7
        //WLIG-CA48WC pk end 2022-1-7
        public String WarehouseAddress;         //库房地址
        public String BusinessScope;            //经营二类范围
        public String BusinessScope1;           //经营三类范围
@@ -93,10 +96,16 @@
    // 收货人层级
    global class Consignee_Info {
        public String ContactName;
        public String ContactNameEncrypted;//add 20220221
        public String ContactPhone;
        public String ContactPhoneEncrypted;//add 20220221
        public String PostalCode;
        public String PostalCodeEncrypted;//add 20220221
        public String ContactAddress;
        public String ContactAddressEncrypted;//add 20220221
        public String ContactCity; //有效收货人城市
        public String ContactDataId;// add  20220221 CONTACT aws 存储id
        public String AddressDataId;// add 2020221 adress aws 存储id
    }
    // 销售人层级
@@ -154,13 +163,18 @@
        // 取得接口传输内容
        String strData = RestContext.request.requestBody.toString();
        GeDatas ges = (GeDatas) JSON.deserializeStrict(strData, GeDatas.class);
        NFMUtil.NFMResponse result = NFMUtil.getNFMResponse();
        if (ges == null ) {
            SFMessage+='参数为空';
            system.debug('SFMessage---'+SFMessage);
            return;
        }
        NFMUtil.Monitoring Monitoring = ges.Monitoring;
        if (Monitoring == null) {
            SFMessage+='Monitoring为空';
            system.debug('SFMessage---'+SFMessage);
            return;
        }
@@ -173,7 +187,12 @@
        res.addHeader('Content-Type', 'application/json');
        res.statusCode = 200;
        //String jsonResponse = '{"status": "Success", "Message":'  + gedata + '}';
        String jsonResponse = '{"status": "Success", "Message":""}';
        // String jsonResponse = '{"status": "Success", "Message":""}';
        //updata response toAWS
        result.SFStatus=SFStatus;
        result.SFMessage=SFMessage;
        String jsonResponse =JSON.serialize(result);
        system.debug('result---'+jsonResponse);
        res.responseBody = blob.valueOf(jsonResponse);
        return;
    }
@@ -263,6 +282,11 @@
                    if (String.isNotBlank(result.split('/')[0])) {
                        iflog.ErrorLog__c += result.split('/')[0];
                        //add response to aws 2022022 sushanhu start
                        SFMessage=iflog.ErrorLog__c;
                        system.debug('ErrorLog__c--'+iflog.ErrorLog__c);
                        system.debug('SFMessage---'+SFMessage);
                        //add response to aws 20220222 sushanhu end
                    } else {
                        logstr += result.split('/')[1];
                    }
@@ -270,7 +294,13 @@
                }
                //WYAN-BS8B2A -XHL -20200925 -End
                if (String.isBlank(gda.BPType)) {
                    iflog.ErrorLog__c += 'BPCode[ ' + gda.BPCode + ' ] of BPType is required,This data is skipped.\n';
                    //add response to aws 20220221 sushanhu start
                    SFMessage=iflog.ErrorLog__c;
                    system.debug('SFMessage--'+SFMessage);
                    //add response to aws 20220221 sushanhu end
                    continue;
                }
                if (gda.BPType != '02' && gda.BPType != '03' && gda.BPType != '04' && gda.BPType != '05') {
@@ -278,16 +308,28 @@
                }
                if (String.isBlank(gda.BPCode)) {
                    iflog.ErrorLog__c += 'BPCode is required,This data is skipped.\n';
                    //add response to aws 20220221 sushanhu start
                    SFMessage=iflog.ErrorLog__c;
                    system.debug('SFMessage---'+SFMessage);
                    //add response to aws 20220221 sushanhu end
                    continue;
                }
                if (gda.BPType == '02') {
                    // 经销商的场合
                    if (String.isBlank(gda.CompanyName)) {
                        iflog.ErrorLog__c += 'BPCode[ ' + gda.BPCode + ' ] of CompanyName is required,This data is skipped.\n';
                        //add response to aws 20220221 sushanhu start
                        SFMessage=iflog.ErrorLog__c;
                        system.debug('SFMessage---'+SFMessage);
                        //add response to aws 20220221 sushanhu end
                        continue;
                    }
                    if (String.isBlank(gda.AgentType)) {
                        iflog.ErrorLog__c += 'BPCode[ ' + gda.BPCode + ' ] of AgentType is required,This data is skipped.\n';
                        //add response to aws 20220221 sushanhu start
                        SFMessage=iflog.ErrorLog__c;
                        system.debug('SFMessage---'+SFMessage);
                        //add response to aws 20220221 sushanhu end
                        continue;
                    }
                    //当经销商的分类为“特约经销商(区域)”、“特约经销商(产品)”、"特约经销商(区域+产品)"、"集采经销商"时,验证契约的必填字段
@@ -298,6 +340,10 @@
                            //CHAN-BF8CCU ---XHL---updateEnd---20190821
                            if (String.isBlank(contractInfos.TermContractNo)) {
                                iflog.ErrorLog__c += 'BPCode[ ' + gda.BPCode + ' ] of TermContractNo is required ,This data is skipped.\n';
                               //add response to aws 20220221 sushanhu start
                                SFMessage=iflog.ErrorLog__c;
                                system.debug('SFMessage---'+SFMessage);
                                //add response to aws 20220221 sushanhu end
                                flg = true;
                                continue;
                            }
@@ -321,6 +367,10 @@
                    applyTypeMap.put(gda.BPCode, gda.ApplyType);
                }
                //add result message 20220222 sushanhu satrt
                    SFMessage=iflog.ErrorLog__c;
                    system.debug('SFMessage---'+SFMessage);
                //add result message 20220222 sushanhu end
                bPCodeList.add(gda.BPCode);
                nfmgd.add(gda);
@@ -403,6 +453,10 @@
                    //判断BPCode是否已经存在,不存在的话会提示不存在,并且跳过
                    if (!accsMap.containsKey(gda.BPCode)) {
                        iflog.ErrorLog__c += ' This BPCode[' + gda.BPCode + '] is not exist,This data is skipped .\n';
                        //add response to aws 20220221 sushanhu start
                        SFMessage=iflog.ErrorLog__c;
                        system.debug('SFMessage---'+SFMessage);
                        //add response to aws 20220221 sushanhu end
                        continue;
                    }
                }
@@ -497,6 +551,9 @@
                    accountInfo.SPO_ApplicationNo__c = GetApplicationNo(gda);
                }
                accountUpsertList.add(accountInfo);
                // //add response to aws 20220221 sushanhu start
                // SFMessage=iflog.ErrorLog__c;
                // //add response to aws 20220221 sushanhu end
            }
            // 新建/更新客户主数据
            if (accountUpsertList.size() > 0) {
@@ -580,6 +637,10 @@
                                    } 
                                } else {
                                    iflog.ErrorLog__c += 'This Contract[ ' + contractInfos.TermContractNo + ' ] not exist,The Data Not  Cancel';
                                     //add response to aws 20220221 sushanhu start
                                    SFMessage=iflog.ErrorLog__c;
                                    system.debug('SFMessage---'+SFMessage);
                                    //add response to aws 20220221 sushanhu end
                                    continue ;
                                }
@@ -640,6 +701,9 @@
                                if (cdcErrorMap.size() > 0) {
                                    iflog.ErrorLog__c += ' This BPCode[' + gda.BPCode + '] of ContractDepartmentClass [' + cdcErrorMap.values() + '] noneffective, [' + cdcErrorMap.values() + '] skipped .\n';
                                     //add response to aws 20220221 sushanhu start
                                    SFMessage=iflog.ErrorLog__c;
                                    //add response to aws 20220221 sushanhu end
                                }
                                contractInfoAcc.Contract_Start_Date__c = NFMUtil.parseStr2Date(contractInfos.ContractStartDate);
                                contractInfoAcc.Contract_End_Date__c = NFMUtil.parseStr2Date(contractInfos.ContractEndDate);
@@ -805,6 +869,10 @@
                    if (String.isBlank(gdds.LicenseType)) {
                        iflog.ErrorLog__c += 'BPCode[ ' + gda.BPCode + ' ] of LicenseType is required ,This data is skipped.\n';
                        //add response to aws 20220221 sushanhu start
                        SFMessage=iflog.ErrorLog__c;
                        system.debug('SFMessage---'+SFMessage);
                        //add response to aws 20220221 sushanhu end
                        continue;
                    }
                    if (gdds.LicenseType == '23' || gdds.LicenseType == '24') { //3PL相关证
@@ -812,6 +880,10 @@
                    }
                    if (String.isBlank(gdds.BusLicenseNo)) {
                        iflog.ErrorLog__c += 'BPCode[ ' + gda.BPCode + ' ] of BusLicenseNo is required,This data is skipped .\n';
                        //add response to aws 20220221 sushanhu start
                        SFMessage=iflog.ErrorLog__c;
                        system.debug('SFMessage---'+SFMessage);
                        //add response to aws 20220221 sushanhu end
                        continue;
                    }
                    geDataDetailsMap.put(gdds.LicenseType, gdds);
@@ -847,6 +919,7 @@
                    licenseInfo.IsFromSPO__c = true;
                    licenseInfo.Scope__c = gdds.BusinessScope;
                    licenseInfo.Scope3__c = gdds.BusinessScope1;
                    licenseInfoUpsertList.add(licenseInfo);
                    //对"经销商"主数据中的"营业许可证书状况"的相关字段进行赋值
@@ -960,11 +1033,20 @@
            logstr += '\nend';
            rowData.retry_cnt__c = 0;
            //add response to AWS 20220221 start
            SFStatus =true;
            SFMessage+=logstr;
            system.debug('SFMessage---'+SFMessage);
             //add response to AWS 20220221 end
        } catch (Exception ex) {
            Database.rollback(sp);
            System.debug(Logginglevel.ERROR, 'NFM203_' + rowData.MessageGroupNumber__c + ':' + ex.getMessage());
            System.debug(Logginglevel.ERROR, 'NFM203_' + rowData.MessageGroupNumber__c + ':' + ex.getStackTraceString());
            logstr += '\n' + ex.getMessage();
            //add response to AWS 20220221 start
            SFMessage+=ex.getMessage();
            system.debug('SFMessage---'+SFMessage);
            //add response to AWS 20220221 end
            iflog.ErrorLog__c = ex.getMessage() + '\n' + ex.getStackTraceString() + '\n' + iflog.ErrorLog__c;
            if (rowData.retry_cnt__c == null) rowData.retry_cnt__c = 0;
@@ -1148,10 +1230,14 @@
                if (complianceDataMap.containsKey(accountCode)) {
                    // 获取客户Id
                    for(Consignee_Info info:complianceDataMap.get(accountCode)){
                        String accountId = tempAccountMap.get(accountCode).Id;
                        // add  sushanhu for pi '000000'为Consignee_Info源数据为空
                        if (!'000000'.equals(info.ContactDataId)) {
                            String accountId = tempAccountMap.get(accountCode).Id;
                        String contactPhone = info.ContactPhone;
                        String contactName = info.ContactName;
                        String contactAllName = contactAllName(contactName);
                        // String contactAllName = contactAllName(contactName);
                        //update to aws contactName 20220221 sushanhu
                        String contactAllName=info.contactName;
                        // 联系人字段赋值
                        Contact contact  = new Contact();
@@ -1160,30 +1246,47 @@
                        contact.Phone = contactPhone;
                        contact.MobilePhone = contactPhone;
                        contact.LastName = contactAllName.split('_')[0];
                        contact.FirstName = contactAllName.split('_')[1];
                        // contact.FirstName = contactAllName.split('_')[1];//delete for pi 20220304
                        contact.IsFromSPO__c = true;
                        // SFDC电话重复人员创建信息确认  pk 2022-2-28 start
                        contact.RecordTypeId = '01210000000QfWi';
                        // SFDC电话重复人员创建信息确认  pk 2022-2-28 end
                        contact.Ignore_Same_Name__c = true;//不是重复的客户名 跳过 客户人员名字已存在 验证
                        // add pi 密文 start 20220221 sushanhu
                        contact.Phone_Encrypted__c = info.ContactPhoneEncrypted;
                        contact.MobilePhone_Encrypted__c = info.ContactPhoneEncrypted;
                        contact.LastName_Encrypted__c =info.ContactNameEncrypted;
                        contact.AWS_Data_Id__c = info.ContactDataId;
                        // add pi 密文 end 20220221 sushanhu
                        insertContactList.add(contact);
                        // 收货地址字段赋值
                        if (!'000000'.equals(info.AddressDataId)) {
                            // 收货地址字段赋值
                        String contactCity = info.ContactCity;
                        Address__c addressData = new Address__c();
                        addressData.Customer__c = accountId;//客户
                        addressData.IsFromSPO__c = true;//是否SPO来源
                        addressData.Telephone__c = contactPhone;//电话
                        addressData.Telephone_Encrypted__c =info.ContactPhoneEncrypted;//电话密文 add sushanhu for pi 20220304
                        addressData.Address_Classification__c = '经销商';//地址分类
                        addressData.Detailed_Address__c = info.ContactAddress;//详细地址
                        // 因接口不传输省,导致保存时报错。因此将其注掉,城市字段不赋值 XHL 20210823
                        // if (cityMap.containsKey(contactCity)) {
                        //     addressData.City__c = cityMap.get(contactCity).Id;//市
                        // }
                        // add pi 密文 start sushanhu 20220221
                        addressData.AWS_Data_Id__c =info.AddressDataId;
                        addressData.Detailed_Address_Encrypted__c =info.ContactAddressEncrypted;
                        // add pi 密文 end sushanhu 20220221
                        String mapkey = accountCode + contactName;
                        insertAddressMap.put(mapkey,addressData);
                        accountCodeList.add(accountCode);
                       }
                        }
                    }
                    
                }
force-app/main/default/classes/NFM501Controller.cls
@@ -1,5 +1,6 @@
public with sharing class NFM501Controller implements Queueable {
    //先定义
    //add aws response
    public class AllData {
        public String code;
        public QLMData data;
@@ -45,6 +46,17 @@
        public String[] ZhaoRelationName;
        public String[] ZhongRelationName;
        public String infoTypeSegment;
        //add aws pi start sushanhu 20220223 start
        public String[] AgentRelationWayEncrypted;//代理机构联系方式密文
        public String[] AgentRelationNameEncrypted;//代理机构联系方式人密文
        public String[] ZhongRelationWayEncrypted;//中标单位联系方式密文
        public String[] ZhongRelationNameEncrypted;//中标单位联系人密文
        public String[] ZhaoRelationNameEncrypted;//招标单位联系人密文
        public String[] ZhaoRelationWayEncrypted;//招标单位联系方式密文
        public String DataId;// AWS 存储凭据
        //add aws pi start sushanhu 20220223 start
    }
    public class AmountItem {
        public String Amount;
@@ -166,7 +178,10 @@
            System.debug('++++1++++' + token + '  : ' + timeslot);
            if (string.isblank(token) || timeslot > 1800000) {
                System.debug('++++2++++' + token + '  : ' + timeslot);
                NFMUtil.response response = NFMUtil.receiveToken();
                // NFMUtil.response response = NFMUtil.receiveToken();
                //update to aws token sushanhu start 20220223
                NFMUtil.response response=NFMUtil.getAwsToken();
                //update to aws token sushanhu end 20220223
                System.debug('++++response++++' + response);
                //判断rowdata中数据获取成功与否,如果失败重发三次,如果大于三次则手动操作
                if (String.isBlank(response.responseBody)) {
@@ -188,11 +203,19 @@
                oldTimeTran.NFM501_Gain_End_Time__c = oldTime;
            }
            //替换获取到数据中的关键字
            NFMUtil.response response = NFMUtil.getQLMData(NFMUtil.NFM501_ENDPOINT
                                        + oldMark.Internal_Value__c + '/10', token);
            // aaaaaaaa 这里顺序错了,肯定是应该先判断是不是因为http 报错,然后才是千里马的code解析
            // //替换获取到数据中的关键字
            // NFMUtil.response response = NFMUtil.getQLMData(NFMUtil.NFM501_ENDPOINT
            //                             + oldMark.Internal_Value__c + '/10', token);
            // // aaaaaaaa 这里顺序错了,肯定是应该先判断是不是因为http 报错,然后才是千里马的code解析
            //update to aws start sushanhu 20220223
            PIHelper.PIIntegration NFM501AWS =PIHelper.getPIIntegrationInfo('QLMNFM501');
            NFMUtil.response response = NFMUtil.getAWSQLMData(NFM501AWS.newUrl+'cursorMark='
                                         + oldMark.Internal_Value__c + '&pageSize=10', token);
            //update to aws  sushanhu end 20220223
            //http的报错处理(重发三遍)
            //
            if (String.isBlank(response.responseBody)) {
                System.debug('-------7-------');
                // aaaaaaaa 报错原因写的不对
@@ -209,7 +232,14 @@
            // 解析后的code报错处理
            String NFM501responseBody = response.responseBody;
            System.debug('-------------NFM501responseBody------------' + NFM501responseBody);
            NFM501responseBody = NFM501responseBody.replaceAll('"list"', '"list1"').replaceAll('"number":', '"number1":');
            //update to aws response sushanhu 20220223 start
            Map<String, Object> results = (Map<String, Object>) JSON.deserializeUntyped(NFM501responseBody);
            //String qlmResult =(String)results.get('object');
            String qlmResult =JSON.serialize(results.get('object'));
            System.debug('-------------NFM501responseBody qlmResult------------' + qlmResult);
            // NFM501responseBody = NFM501responseBody.replaceAll('"list"', '"list1"').replaceAll('"number":', '"number1":');
            NFM501responseBody = qlmResult.replaceAll('"list"', '"list1"').replaceAll('"number":', '"number1":');
            //update to aws response sushanhu 20220223 end
            AllData getQLMData =  (AllData) JSON.deserializeStrict(NFM501responseBody, AllData.class);
            System.debug('-------------8------------' + getQLMData);
            if (!getQLMData.code.equals('0')) {
@@ -223,6 +253,8 @@
                return;
            }
            rowData = NFMUtil.QLMmakeRowData(NFM501responseBody, rowData);
            rowData.AWS_Transaction_Id__c = (String)results.get('txId');// add for pi susanhu 20220310
            system.debug('rowData---'+rowData);
            System.debug('======2221234======');
            update tokenTran;
@@ -244,7 +276,7 @@
                // 12点自动抓取招投标数据
                // NFM501Controller.TwoMarkEqualAgainSend();
            }
            rowData.retry_cnt__c = 0;
            if (System.Test.isRunningTest()) {
                throw new ControllerUtil.myException('aaa');
force-app/main/default/classes/NFM501FutureController.cls
@@ -3,6 +3,10 @@
    //先定义
    //     投标截止时间
    // 2021/01/04 18:00
    //add by sushanhu for pi 20220310 start
    public static String txId;
    //add by sushanhu for pi 20220310 end
    public String rowData_id;
    public NFM501FutureController(String rowData_id) {
        this.rowData_id = rowData_id;
@@ -13,16 +17,20 @@
        BatchIF_Log__c rowData = [Select Id, Name, Log__c, ErrorLog__c, Log2__c, Log3__c,
            Log4__c, Log5__c, Log6__c, Log7__c, Log8__c, Log9__c, Log10__c, Log11__c,
            Log12__c, MessageGroupNumber__c, retry_cnt__c, NFM501Future_Count__c,
            NFM501_Web_Annex_Count__c
            NFM501_Web_Annex_Count__c,
            AWS_Transaction_Id__c //ADD BY SUSHANHU for pi 20220310
            from BatchIF_Log__c where RowDataFlg__c = true and Id = : rowData_id
        ];
        //存放报错信息
        txId =rowData.AWS_Transaction_Id__c; //add by sushanhu for pipl 20220310
        system.debug('nfm501future awsid'+txId);
        BatchIF_Log__c iflog501Future = new BatchIF_Log__c();
        iflog501Future.Type__c = 'NFM501';
        iflog501Future.MessageGroupNumber__c = rowData.MessageGroupNumber__c;
        iflog501Future.Log__c = ' ';
        iflog501Future.ErrorLog__c = ' ';
        iflog501Future.RowDataFlg__c = false;
        iflog501Future.AWS_Transaction_Id__c=rowData.AWS_Transaction_Id__c;
        insert iflog501Future;
        NFM501FutureController.main(rowData.Id, iflog501Future.Id, false);
    }
@@ -49,9 +57,12 @@
        String QLMDataStr = NFMUtil.QLMgetRowDataStr(rowData);
        NFM501controller.AllData getQLMData1 = (NFM501controller.AllData)
        JSON.deserialize(QLMDataStr, NFM501controller.AllData.class);
        if (getQLMData1 == null) {
            return;
        }
        List<PIHelper.IdList> idList = new List<PIHelper.IdList>();//存储更新后得sfid和awsid add by sushanhu 20220310
        PIHelper.PIIntegration NFM501AWS =PIHelper.getPIIntegrationInfo('QLMNFM501'); //add by sushanhu 20220310
        Savepoint sp = Database.setSavepoint();
        //IF转换表(为实现选项列表的下拉选项)
        Map < String, String > transferMap = new Map < String, String > ();
@@ -122,15 +133,20 @@
            tempbidInfoFileURLList.add(bidInfoFile.infoAddress__c);
            SelectbidInfoFileMap.put(bidInfoFile.Tender_information__r.ProjectId__c, tempbidInfoFileURLList);
        }
        try {
            // 招标信息
            Map < string, List < bidInfoFile__c >> createbidInfoFileMap = new map < string, List < bidInfoFile__c >> ();
            Map < String, List < Tender_information_details__c >> tempList1 = new Map < String, List < Tender_information_details__c >> ();
            Map < string, Tender_information__c > updateTenderMap = new map < string, Tender_information__c > ();
            Set < String > TarDetailSet = new Set < String > ();
            for (NFM501Controller.ListItem LI: getQLMData1.data.list1) {
                // 項目転送のセット
                Tender_information__c te1 = new Tender_information__c();
                //add aws dataid sushanhu 20220223 start
                te1.AWS_Data_Id__c = LI.DataId;
                //add aws dataid sushanhu 20220223 end
                if (String.isBlank(LI.projectId)) {
                    iflog501Future.ErrorLog__c += 'Error! [' + LI.projectId + ']NotExist. This information is skipped.\n';
                    continue;
@@ -183,6 +199,9 @@
                //拼接字符串
                if (LI.ZhaoRelationWay != null && LI.ZhaoRelationWay.size() > 0) {
                    te1.ZhaoRelationWay__c = String.join(LI.ZhaoRelationWay, ',');
                     //add 密文 sushanhu 20220223 start
                     te1.ZhaoRelationWay_Encrypted__c =String.join(LI.ZhaoRelationWayEncrypted,',');
                     //add 密文 sushanhu 20220223 end
                }
                //转换表(选项列表的下拉选项)
                te1.IsElectronic__c = NFMUtil.getMapValue(transferMap, 'IsElectronic__c', LI.isElectronic, iflog501Future);
@@ -283,6 +302,9 @@
                }
                if (LI.AgentRelationWay != null && LI.AgentRelationWay.size() > 0) {
                    te1.AgentRelationWay__c = String.join(LI.AgentRelationWay, ',');
                    //add 密文 sushanhu 20220223 start
                    te1.AgentRelationWay_Encrypted__c =String.join(LI.AgentRelationWayEncrypted,',');
                    //add 密文 sushanhu 20220223 end
                }
                // 将改附件存入招投标项目子对象中
                if (LI.InfoFile != null && LI.InfoFile.size() > 0) {
@@ -327,6 +349,9 @@
                }
                if (LI.AgentRelationName != null && LI.AgentRelationName.size() > 0) {
                    te1.AgentRelationName__c = String.join(LI.AgentRelationName, ',');
                    //add 密文 sushanhu 20220223 start
                    te1.AgentRelationName_Encrypted__c =String.join(LI.AgentRelationNameEncrypted,',');
                    //add 密文 sushanhu 20220223 end
                }
                if (String.isNotBlank(LI.bidingEndTime)) {
                    te1.BidingEndTime__c = Datetime.valueOf(LI.bidingEndTime);
@@ -355,6 +380,9 @@
                }
                if (LI.ZhongRelationWay != null && LI.ZhongRelationWay.size() > 0) {
                    te1.ZhongRelationWay__c = String.join(LI.ZhongRelationWay, ',');
                    //add 密文 sushanhu 20220223 start
                    te1.ZhongRelationWay_Encrypted__c =String.join(LI.ZhongRelationWayEncrypted,',');
                    //add 密文 sushanhu 20220223 end
                }
                if (String.isNotBlank(LI.bidingAcquireTime)) {
                    te1.BidingAcquireTime__c = Datetime.valueOf(LI.bidingAcquireTime);
@@ -462,10 +490,18 @@
                }
                if (LI.ZhaoRelationName != null && LI.ZhaoRelationName.size() > 0) {
                    te1.ZhaoRelationName__c = String.join(LI.ZhaoRelationName, ',');
                    //add 密文 sushanhu 20220223 start
                    te1.ZhaoRelationName_Encrypted__c =String.join(LI.ZhaoRelationNameEncrypted,',');
                    //add 密文 sushanhu 20220223 end
                }
                if (LI.ZhongRelationName != null && LI.ZhongRelationName.size() > 0) {
                    te1.ZhongRelationName__c = String.join(LI.ZhaoRelationName, ',');
                     //add 密文 sushanhu 20220223 start
                     te1.ZhongRelationName_Encrypted__c =String.join(LI.ZhongRelationNameEncrypted,',');
                     //add 密文 sushanhu 20220223 end
                }
                //精琢科技   zxk   2021-11-11  SWAG-C637NF   start
                // 如果第一次项目阶段就传来变更状态的话,那么就不生成招投标项目(由于变更阶段项目名称传来为空,为了不让项目名自动赋值为Id)
                if (String.isNotBlank(te1.InfoType__c) && String.isNotBlank(LI.projectId)) {
@@ -499,8 +535,15 @@
            System.debug('123456789123456789:' + updateTenderMap);
            //将招标信息和招标信息详情关联起来(通过ProjectId这一唯一标识)
            Map < string, Tender_information__c > TenderMap = new map < string, Tender_information__c > ();
            for (Tender_information__c TMap: updateTenderMap.values()) {
                TenderMap.put(TMap.ProjectId__c, TMap);
                PIHelper.IdList il= new PIHelper.IdList();
                // add for pipl  sushanhu 20220310 start
                il.awsId =TMap.AWS_Data_Id__c;
                il.sfRecordId=TMap.Id;
                idList.add(il);
                // add for pipl  sushanhu 20220310 end
            }
            System.debug('12345678!!!!!' + TenderMap.values());
            List < Tender_information_details__c > TenList = new List < Tender_information_details__c > ();
@@ -537,9 +580,15 @@
            if (System.Test.isRunningTest()) {
                throw new ControllerUtil.myException('aaa');
            }
            //确认事务 add for pi sushanhu 20220310 start
            PIHelper.confirmTrans('NFM501',1,null,txId,NFM501AWS.token,NFM501AWS.transactionURL,idList);
            //确认事务 add for pi sushanhu 20220310 end
        } catch (Exception ex) {
            // 如果数据获取过程中,有错误(同一游标,如果报错,是他重新获取一遍,如果三次都没能获取到,就发送邮件报错信息,然后手动进行获取)
            Database.rollback(sp);
            //确认事务 add for pi sushanhu 20220310 start
            PIHelper.confirmTrans('NFM501',0,null,txId,NFM501AWS.token,NFM501AWS.transactionURL,idList);
            //确认事务 add for pi sushanhu 20220310 end
            System.debug(Logginglevel.ERROR, 'QLMData_' + rowData.MessageGroupNumber__c + ':' + ex.getMessage());
            System.debug(Logginglevel.ERROR, 'QLMData_' + rowData.MessageGroupNumber__c + ':' + ex.getStackTraceString());
            // logstr += '\n' + ex.getMessage();
force-app/main/default/classes/NFM502Controller.cls
@@ -1,6 +1,10 @@
public with sharing class NFM502Controller implements Queueable {
    public String rowData_id;
    //add staic sushanhu 20220302 start
    public static String transUrl;
    public static String transId;
    public static String token;
    //add staic sushanhu 20220302 end
    public NFM502Controller(String rowData_id) {
        this.rowData_id = rowData_id;
    }
@@ -46,7 +50,9 @@
        // Savepoint sp = Database.setSavepoint();
        try {
            String token;
            //update 同staic 20220302 satrt
            // String token;
            //update 同staic 20220302 end
            Datetime oldTime;
            // 从转换表中获取token
            BatchIF_Transfer__c token502 = [Select ID, NFM501_Token__c
@@ -75,11 +81,13 @@
            }
            // System.debug('++++1++++' + token + '  : ' + timeslot);
            if (string.isblank(token) || timeslot > 1800000) {
                NFMUtil.response response = NFMUtil.receiveToken();
                // NFMUtil.response response = NFMUtil.receiveToken();
                //update to aws token sushanhu 20220301  start
                NFMUtil.response response = NFMUtil.getAWSToken();
                //判断rowdata中数据获取成功与否,如果失败重发三次,如果大于三次则手动操作
                if (String.isBlank(response.responseBody)) {
                    System.debug('response.responseBody:' + response.responseBody);
                    iflog502.ErrorLog__c = '502token:' + response.status;
                    iflog502.ErrorLog__c = '502token:' + response.responseBody;
                    // rowData.NFM501_Web_Annex_Count__c = 0;
                    if (!Manual_execution502) {
                        NFM501Controller.againSendRequest(iflog502, 'NFM501_Web_Annex_Count__c', rowData);
@@ -92,6 +100,7 @@
                oldTime = Datetime.now();
                token502.NFM501_Token__c = token;
                oldTime502.NFM501_Gain_End_Time__c = oldTime;
                //update to aws token sushanhu 20220301  end
            }
            //关联附件与招投标项目(通过Id)
@@ -116,7 +125,12 @@
            }
            //循环URL
            List<Attachment> TenAttList = new List<Attachment>();
            // List<Attachment> TenAttList = new List<Attachment>();
            //update to aws pi sushanhu 20220301 start
            List<FileAddress__c> fileList = new List<FileAddress__c>();
            List<String> queryUrlList = new List<String>();
            Map<String, NFM501Controller.ListItem> queryMap = new Map<String, NFM501Controller.ListItem>();
            //update to aws pi sushanhu 20220301 end
            for (NFM501Controller.ListItem QLMWebAtt : getQLMData502.data.list1) {
                if (QLMWebAtt.projectId == null) {
                    iflog502.ErrorLog__c += 'Error! [' + QLMWebAtt.projectId + ']NotExist. This information is skipped.\n';
@@ -129,54 +143,111 @@
                                            ']Is 香港特别行政区(澳门特别行政区,台湾省). This information is skipped.\n';
                    continue;
                }
                //调用接口3
                NFMUtil.response response = NFMUtil.getQLMData(NFMUtil.NFM502_ENDPOINT + QLMWebAtt.infoQianlimaUrl, token);
                if (String.isBlank(response.responseBody)) {
                    System.debug('response.responseBody:' + response.responseBody);
                    iflog502.ErrorLog__c = '502接口调用:' + response.status;
                    rowData.NFM501_Web_Annex_Count__c = 0;
                    if (!Manual_execution502) {
                        NFM501Controller.againSendRequest(iflog502, 'NFM501_Web_Annex_Count__c', rowData);
                    }
                    //更新日志数据
                    update token502;
                    update oldTime502;
                    return;
                }
                //update to aws pi sushanhu 20220301 start
                queryUrlList.add(QLMWebAtt.infoQianlimaUrl);
                queryMap.put(QLMWebAtt.infoQianlimaUrl,QLMWebAtt);
                //update to aws pi sushanhu 20220301 start
            //     //调用接口3
            //     NFMUtil.response response = NFMUtil.getQLMData(NFMUtil.NFM502_ENDPOINT + QLMWebAtt.infoQianlimaUrl, token);
            //     if (String.isBlank(response.responseBody)) {
            //         System.debug('response.responseBody:' + response.responseBody);
            //         iflog502.ErrorLog__c = '502接口调用:' + response.status;
            //         rowData.NFM501_Web_Annex_Count__c = 0;
            //         if (!Manual_execution502) {
            //             NFM501Controller.againSendRequest(iflog502, 'NFM501_Web_Annex_Count__c', rowData);
            //         }
            //         //更新日志数据
            //         update token502;
            //         update oldTime502;
            //         return;
            //     }
                //解析后的code报错处理
                string NFM502responseBody = response.responseBody;
                Map<String, Object> Body502 = (Map<String, Object>) JSON.deserializeUntyped(NFM502responseBody);
                if (!Body502.get('code').equals('0')) {
                    System.debug('-------9-------');
                    iflog502.ErrorLog__c = '502解析:' + Body502.get('msg').tostring() ;
                    if (!Manual_execution502) {
                        NFM501Controller.againSendRequest(iflog502, 'NFM501_Web_Annex_Count__c', rowData);
                    }
                    update token502;
                    update oldTime502;
                    return;
                }
                System.debug('Body502.data:' + Body502.get('data').tostring() + '---------'
                             + Body502.get('msg').tostring() + '-------' + Body502.get('code').tostring());
            //     //解析后的code报错处理
            //     string NFM502responseBody = response.responseBody;
            //     Map<String, Object> Body502 = (Map<String, Object>) JSON.deserializeUntyped(NFM502responseBody);
            //     if (!Body502.get('code').equals('0')) {
            //         System.debug('-------9-------');
            //         iflog502.ErrorLog__c = '502解析:' + Body502.get('msg').tostring() ;
            //         if (!Manual_execution502) {
            //             NFM501Controller.againSendRequest(iflog502, 'NFM501_Web_Annex_Count__c', rowData);
            //         }
            //         update token502;
            //         update oldTime502;
            //         return;
            //     }
            //     System.debug('Body502.data:' + Body502.get('data').tostring() + '---------'
            //                  + Body502.get('msg').tostring() + '-------' + Body502.get('code').tostring());
                //获取网页信息转存为附件
                //截切数据(使数据成为解析的格式)
                Integer start = NFM502responseBody.indexOf('"infoHtml":"');
                Integer theEnd = NFM502responseBody.lastIndexOf('"},"msg');
                NFM502responseBody = NFM502responseBody.substring(start + 12, theEnd);
                //将其转换为附件
                // System.debug('---------' + NFM502responseBody);
                Attachment WebAtt = new Attachment();
                // System.debug('projectId:' + QLMWebAtt.projectId);
                if (TenMap.containskey(QLMWebAtt.projectId)) {
                    WebAtt.ParentId = TenMap.get(QLMWebAtt.projectId).Id;
                    WebAtt.Body = Blob.valueOf(NFM502responseBody);
                    WebAtt.Name = TenMap.get(QLMWebAtt.projectId).InfoType__c + ':' + QLMWebAtt.infoTitle + '.html';
                    TenAttList.add(WebAtt);
            //     //获取网页信息转存为附件
            //     //截切数据(使数据成为解析的格式)
            //     Integer start = NFM502responseBody.indexOf('"infoHtml":"');
            //     Integer theEnd = NFM502responseBody.lastIndexOf('"},"msg');
            //     NFM502responseBody = NFM502responseBody.substring(start + 12, theEnd);
            //     //将其转换为附件
            //     // System.debug('---------' + NFM502responseBody);
            //     Attachment WebAtt = new Attachment();
            //     // System.debug('projectId:' + QLMWebAtt.projectId);
                // if (TenMap.containskey(QLMWebAtt.projectId)) {
                //     WebAtt.ParentId = TenMap.get(QLMWebAtt.projectId).Id;
                //     WebAtt.Body = Blob.valueOf(NFM502responseBody);
                //     WebAtt.Name = TenMap.get(QLMWebAtt.projectId).InfoType__c + ':' + QLMWebAtt.infoTitle + '.html';
                //     TenAttList.add(WebAtt);
                // }
             }
            //update to aws pi  sushanhu 20220301 start
            PIHelper.piIntegration pi =PIHelper.getPIIntegrationInfo('NFM502');
            transUrl=pi.searchUrl;
            //调用接口3
            system.debug('Payload for NFM 520:'+JSON.serialize(queryUrlList));
            NFMUtil.response response = NFMUtil.getAWSQLMData(pi.newUrl ,JSON.serialize(queryUrlList), token);
            Map<String, Object> result = (Map<String, Object>)JSON.deserializeUntyped(response.responseBody);
            String statusCode =(String)result.get('status');
            transId =(String)result.get('txId');
            if (!'0'.equals(statusCode)) {
                System.debug('response.responseBody:' + response.responseBody);
                iflog502.ErrorLog__c = '502接口调用:' + (String)result.get('message');
                rowData.NFM501_Web_Annex_Count__c = 0;
                if (!Manual_execution502) {
                    NFM501Controller.againSendRequest(iflog502, 'NFM501_Web_Annex_Count__c', rowData);
                }
                //更新日志数据
                update token502;
                update oldTime502;
                return;
            }
            //解析后的code报错处理
            string NFM502responseBody = response.responseBody;
            Map<String, Object> Body502 = (Map<String, Object>) JSON.deserializeUntyped(NFM502responseBody);
            if (!String.valueOf(Body502.get('status')).equals('0')) {
                System.debug('-------9-------');
                iflog502.ErrorLog__c = '502解析:' + Body502.get('message').tostring() ;
                if (!Manual_execution502) {
                    NFM501Controller.againSendRequest(iflog502, 'NFM501_Web_Annex_Count__c', rowData);
                }
                update token502;
                update oldTime502;
                return;
            }
            System.debug('Body502.data:' + Body502.get('object').tostring() + '---------'
                         + Body502.get('message').tostring() + '-------' + Body502.get('status').tostring());
            //获取aws返回的地址并存储
            Map<String, Object> fileMap = (Map<String, Object >)result.get('object');
            for(String url:queryUrlList){
                NFM501Controller.ListItem QLMWebAtt = queryMap.get(url);
                if (TenMap.containskey(QLMWebAtt.projectId)) {
                    FileAddress__c file =new FileAddress__c();
                    file.ParentRecordId__c = TenMap.get(QLMWebAtt.projectId).Id;
                    file.FileName__c = TenMap.get(QLMWebAtt.projectId).InfoType__c + ':' + QLMWebAtt.infoTitle + '.html';
                    file.DownloadLink__c =pi.undeleteUrl+(String)fileMap.get(url)+'&fileName='+file.FileName__c;
                    file.ViewLink__c = pi.queryUrl+(String)fileMap.get(url) ;
                    file.AWS_File_Key__c =(String)fileMap.get(url) ;
                    fileList.add(file);
                }
            }
            //删除同名的附件
            List<String> UrlList = new List<String>();
            for (NFM501Controller.ListItem UrlName : getQLMData502.data.list1) {
@@ -185,22 +256,34 @@
                }
            }
            List<Attachment> DeleAttList = [select id, name, ParentId from Attachment
                                            where name in :UrlList and ParentId in :TenIdSet];
            if (DeleAttList.size() > 0) {
                delete DeleAttList;
            List<FileAddress__c> DeleFileList = [select id, FileName__c, ParentRecordId__c from FileAddress__c
                                            where FileName__c in :UrlList and ParentRecordId__c in :TenIdSet];
            if (DeleFileList.size() > 0) {
                delete DeleFileList;
            }
            System.debug('----1----' + TenAttList);
            if (TenAttList.size() > 0) {
                upsert TenAttList;
            System.debug('----1----' + fileList);
            if (fileList.size() > 0) {
                upsert fileList;
            }
            //确认事务
            List<String> sfRecordIds = new List<String>();
            for (FileAddress__c file : fileList) {
                sfRecordIds.add(file.Id);
            }
            //update to aws pi  sushanhu 20220301 end
             PIHelper.confirmFileTrans('NFM502',1,JSON.serialize(sfRecordIds),transId,token,transUrl);
            // if (!confirm) {
            //     //回滚
            // }
            rowData.NFM501_Web_Annex_Count__c = 0;
        } catch (Exception ex) {
            // Database.rollback(sp);
            // System.debug(Logginglevel.ERROR, 'QLMData_' + rowData.MessageGroupNumber__c + ':' + ex.getMessage());
            // System.debug(Logginglevel.ERROR, 'QLMData_' + rowData.MessageGroupNumber__c + ':' + ex.getStackTraceString());
            // logstr += '\n' + ex.getMessage();
            //add 事务确认 sushanhu 20220302 satrt
             PIHelper.confirmFileTrans('NFM502',0,'',transId,token,transUrl);
            //add 事务确认 sushanhu 20220302 end
            iflog502.ErrorLog__c = '502抛出异常:' + ex.getMessage() + '\n'
                                   + ex.getStackTraceString() + '\n' + iflog502.ErrorLog__c;
            if (!Manual_execution502) {
force-app/main/default/classes/NFM503InfoFileBatch.cls
@@ -1,8 +1,18 @@
global class NFM503InfoFileBatch implements Database.Batchable<sObject>, Database.AllowsCallouts, Database.Stateful {
    public String TenId;
    public String bidInfoFileID;
    //add staic sushanhu 20220302 start
    public static String transUrl;
    public static String transId;
    public static String token;
    //add staic sushanhu 20220302 end
    Boolean IsNeedExecute = false;  //2021-06-28 mzy  WLIG-BYHD79  SFDC环境batch合并调查  是否符合执行条件
    //add nfm 503 aws response start sushanhu 20220301
    global class File{
        public String key;
        public String name;
    }
    //add nfm 503 aws response sushanhu 20220301 end
    //2021-06-28  mzy update  千里马-Batch start
    global NFM503InfoFileBatch() {
        this.IsNeedExecute = true;
@@ -33,9 +43,12 @@
    global void execute(Database.BatchableContext BC, list<bidInfoFile__c> bidInfoFileList) {
        Savepoint sp;
        bidInfoFile__c bidInfoFile = bidInfoFileList[0];
        List<String> queryfileList = new List<String>();
        queryfileList.add(bidInfoFile.infoAddress__c);
        try {
            String token;
           //update 同staic 20220302 satrt
            // String token;
            //update 同staic 20220302 end
            Datetime oldTime;
            // 从转换表中获取token
            BatchIF_Transfer__c token503 = [Select ID, NFM501_Token__c
@@ -56,7 +69,9 @@
            }
            // System.debug('++++1++++' + token + '  : ' + timeslot);
            if (string.isblank(token) || timeslot > 1800000) {
                NFMUtil.response response = NFMUtil.receiveToken();
                //UP TO AWAS TOKEN 20220225 SUSHANHU START
                NFMUtil.response response = NFMUtil.getAWSToken();
                //UP TO AWAS TOKEN 20220225 SUSHANHU END
                if (String.isBlank(response.responseBody)) {
                    bidInfoFile.ErrorMessage__c = '503token:' + response.status;
                }
@@ -65,53 +80,133 @@
                token503.NFM501_Token__c = token;
                oldTime503.NFM501_Gain_End_Time__c = oldTime;
            }
            // 存放超过12M的附件
            List<Attachment> TenOtherAttList = new List<Attachment>();
            // 存放所有附件
            List<String> FileList = new List<String>();
            // 如果文件大小超过12M更新
            List< Tender_information__c> updateTenderList = new  List< Tender_information__c>();
            // 获取接口3中数据
            NFMUtil.response503 response = NFMUtil.getFileData(token, bidInfoFile.infoAddress__c);
            // 文件大小超过12M
            if (response.Name.equals('文件大小超过12M')) {
                id tendID = bidInfoFile.Tender_information__c;
                Tender_information__c tempTender = new Tender_information__c();
                tempTender.id = tendID;
                tempTender.File_Surpass_12M__c = true;
                if (String.isBlank(tempTender.Overstep_12M_infofile__c)) {
                    tempTender.Overstep_12M_infofile__c = bidInfoFile.infoAddress__c;
                } else {
                    if (!tempTender.Overstep_12M_infofile__c.contains(bidInfoFile.infoAddress__c)) {
                        // List<String> urlList = singleFile.split(',');
                        tempTender.Overstep_12M_infofile__c += bidInfoFile.infoAddress__c + ',';
                    }
                }
                updateTenderList.add(tempTender);
            // // 存放超过12M的附件
            // List<Attachment> TenOtherAttList = new List<Attachment>();
            // // 存放所有附件
            // List<String> FileList = new List<String>();
            // // 如果文件大小超过12M更新
            // List< Tender_information__c> updateTenderList = new  List< Tender_information__c>();
            // // 获取接口3中数据
            // NFMUtil.response503 response = NFMUtil.getFileData(token, bidInfoFile.infoAddress__c);
            //UP TO NEW  AWS method sushanhu start 20220301
            // List< Tender_information__c> updateTenderList = new  List< Tender_information__c>();
            List<FileAddress__c> fileList = new List<FileAddress__c>();
            PIHelper.piIntegration pi =PIHelper.getPIIntegrationInfo('NFM503');
            transUrl =pi.searchUrl;
            NFMUtil.response response = NFMUtil.getAWSQLMData(pi.newUrl ,JSON.serialize(queryfileList), token);
            system.debug('aws result'+response.responseBody);
            Map<String, Object> result = (Map<String, Object>)JSON.deserializeUntyped(response.responseBody);
            system.debug('NFM503 aws result--'+response.responseBody+'status'+response.status);
            transId =(String)result.get('txId');
            //UP TO NEW  AWS method sushanhu start 20220301
            // 新得存储 不需要判断文件超过12m
            // // 文件大小超过12M
            // if (response.Name.equals('文件大小超过12M')) {
            //     id tendID = bidInfoFile.Tender_information__c;
            //     Tender_information__c tempTender = new Tender_information__c();
            //     tempTender.id = tendID;
            //     tempTender.File_Surpass_12M__c = true;
            //     if (String.isBlank(tempTender.Overstep_12M_infofile__c)) {
            //         tempTender.Overstep_12M_infofile__c = bidInfoFile.infoAddress__c;
            //     } else {
            //         if (!tempTender.Overstep_12M_infofile__c.contains(bidInfoFile.infoAddress__c)) {
            //             // List<String> urlList = singleFile.split(',');
            //             tempTender.Overstep_12M_infofile__c += bidInfoFile.infoAddress__c + ',';
            //         }
            //     }
            //     updateTenderList.add(tempTender);
            // }
            // // 将获取到的数据存成附件
            // Attachment WebAtt = new Attachment();
            // WebAtt.ParentId = bidInfoFile.Tender_information__c;
            // WebAtt.Body = response.responseBody;
            // WebAtt.Name = bidInfoFile.Tender_information__r.InfoType__c + ':' + response.Name;
            // if (!response.Name.equals('文件大小超过12M')) {
            //     TenOtherAttList.add(WebAtt);
            // }
            // sp = Database.setSavepoint();
            // if (updateTenderList.size() > 0) {
            //     update updateTenderList;
            // }
            // System.debug('----1----' + TenOtherAttList);
            // if (TenOtherAttList.size() > 0 ) {
            //     upsert TenOtherAttList;
            // }
            // bidInfoFileList[0].isProcessed__c = true;
            // bidInfoFileList[0].ErrorMessage__c = '';
            // update bidInfoFileList;
            // if (System.Test.isRunningTest()) {
            //     throw new ControllerUtil.myException('aaa');
            // }
            // return;
            String statusCode =String.valueOf(result.get('status')) ;
            system.debug('statuscode aws-- '+statusCode);
            if (!'0'.equals(statusCode)) {
                System.debug('response.responseBody:' + response.responseBody);
                return;
            }
            // 将获取到的数据存成附件
            Attachment WebAtt = new Attachment();
            WebAtt.ParentId = bidInfoFile.Tender_information__c;
            WebAtt.Body = response.responseBody;
            WebAtt.Name = bidInfoFile.Tender_information__r.InfoType__c + ':' + response.Name;
            if (!response.Name.equals('文件大小超过12M')) {
                TenOtherAttList.add(WebAtt);
            }
            Map<String, Object> fileMap = (Map<String, Object >)result.get('object');
            system.debug('fileMap'+fileMap.toString());
            Map<String, Object> fileVO =(Map<String, Object>)fileMap.get(bidInfoFile.infoAddress__c);
            String Name =(String)fileVO.get('name');
            // if (Name.equals('文件大小超过12M')) {
            //     id tendID = bidInfoFile.Tender_information__c;
            //     Tender_information__c tempTender = new Tender_information__c();
            //     tempTender.id = tendID;
            //     tempTender.File_Surpass_12M__c = true;
            //     if (String.isBlank(tempTender.Overstep_12M_infofile__c)) {
            //         tempTender.Overstep_12M_infofile__c = bidInfoFile.infoAddress__c;
            //     } else {
            //         if (!tempTender.Overstep_12M_infofile__c.contains(bidInfoFile.infoAddress__c)) {
            //             // List<String> urlList = singleFile.split(',');
            //             tempTender.Overstep_12M_infofile__c += bidInfoFile.infoAddress__c + ',';
            //         }
            //     }
            //     updateTenderList.add(tempTender);
            // }
            //将获取的AWS文件地址存储
            FileAddress__c file = new FileAddress__c();
            file.ParentRecordId__c = bidInfoFile.Tender_information__c;
            file.FileName__c = bidInfoFile.Tender_information__r.InfoType__c + ':' + Name;
            file.DownloadLink__c =pi.undeleteUrl+(String)fileVO.get('key')+'&fileName='+file.FileName__c;
            file.ViewLink__c = pi.queryUrl+(String)fileVO.get('key');
            file.AWS_File_Key__c =(String)fileVO.get('key');
            fileList.add(file);
            sp = Database.setSavepoint();
            if (updateTenderList.size() > 0) {
                update updateTenderList;
            }
            System.debug('----1----' + TenOtherAttList);
            if (TenOtherAttList.size() > 0 ) {
                upsert TenOtherAttList;
            System.debug('----1----' + fileList);
            if (fileList.size() > 0 ) {
                upsert fileList;
            }
            bidInfoFileList[0].isProcessed__c = true;
            bidInfoFileList[0].ErrorMessage__c = '';
            update bidInfoFileList;
            // add 确认事务 sushanhu 20220302 start
            List<String> sfRecordIds = new List<String>();
            for (FileAddress__c fileAddress : fileList) {
                sfRecordIds.add(fileAddress.Id);
                system.debug('fileAddress.Id---'+fileAddress.Id);
            }
            system.debug('成功的token'+token);
             PIHelper.confirmFileTrans('NFM503',1,JSON.serialize(sfRecordIds),transId,token,transUrl);
            // if (!confirm) {
            //     //回滚
            //     if (sp != null) {
            //         Database.rollback(sp);
            //     }
            // }
            // add 确认事务 sushanhu 20220302 end
            if (System.Test.isRunningTest()) {
                throw new ControllerUtil.myException('aaa');
            }
@@ -120,7 +215,12 @@
            if (sp != null) {
                Database.rollback(sp);
            }
            //add 确认事务 20220302 sushanhu start
            system.debug('失败的token'+token);
             PIHelper.confirmFileTrans('NFM503',0,'',transId,token,transUrl);
            //add 确认事务 20220302 sushanhu end
            bidInfoFile.ErrorMessage__c = '503抛出异常:' + ex.getMessage() + '\n' + ex.getStackTraceString();
            system.debug('ErrorMessage'+bidInfoFile.ErrorMessage__c);
        }
        update bidInfoFile;
    }
force-app/main/default/classes/NFM606Controller.cls
@@ -5,7 +5,10 @@
public without sharing class NFM606Controller {
    public static String logstr;
    public static String status;
    public static String status;
    //add aws respnse sushanhu 20220228 start
    public static String responseBody;
    //add aws respnse sushanhu 20220228 end
    private static final String LOG_TYPE = 'NFM606';
    private static final String API = '/admin/api/user/save';
    public class NFM606 {
@@ -33,6 +36,9 @@
        public String AgentCode; //经销商编码
        public String AgentUserType; //人员类型
        public String Email; //电子邮件
        //add aws pi start sushanhu 20220228
        public String DataId;//aws 存储凭据
        //add aws pi end sushanhu 20220228
    }
@@ -104,6 +110,7 @@
            Account.ParentId,
            Account.Parent.ParentId,
            UniqueNumber__c,
            AWS_Data_Id__c,
            Name, Email from Contact where id in: conIdList AND RecordTypeId != '01210000000QtkyAAC'
        ];
        String logstr = iflog.Log__c + ' ' + 'NumberOfRecord=' + conList.size() + '\n';
@@ -112,6 +119,9 @@
                String flag = '';
                GeData ged = new GeData();
                ged.ContactId = String.isBlank(con.UnifiedI_Contact_ID__c) ? '':con.UnifiedI_Contact_ID__c; //智慧医疗ID
                //update to AWS_UnifiedI_Contact_ID__c sushanhu 20220228 start
                //ged.ContactId = String.isBlank(con.) ? '':con.AWS_UnifiedI_Contact_ID__c; //AWS 智慧医疗ID
                ////update to AWS_UnifiedI_Contact_ID__c sushanhu 20220228 end
                ged.ServiceUserId = String.isBlank(con.ServicePlatformCode__c) ? '':con.ServicePlatformCode__c; //服务平台用户ID???
                ged.Mobile = String.isNotBlank(con.UniqueNumber__c) ? con.UniqueNumber__c:con.MobilePhone;//手机
                ged.PersonManagementCode = con.CManageCode__c; //人员管理编码
@@ -143,6 +153,7 @@
                    ged.AgentFlag = true;//经销商
                    ged.Email = con.Email;
                }
                ged.DataId =con.AWS_Data_Id__c;//add aws 存储凭据
                ged = getStateAndCity(ged,con);
                gds.GeData.add(ged);
@@ -259,17 +270,32 @@
        try {
            
            
            // 发往PO
            status = NFMUtil.sendToSapRet(rowDataStr, NFMUtil.NFM606_ENDPOINT);
            System.debug('NFM606Log--status->'+ status);
            // status = ''
            if ('Accepted'.equals(status)) {
            // // 发往PO
            // status = NFMUtil.sendToSapRet(rowDataStr, NFMUtil.NFM606_ENDPOINT);
            // System.debug('NFM606Log--status->'+ status);
            // // status = ''
            // if ('Accepted'.equals(status)) {
            //     logstr += status+'\n';
            //     rowDataSFDC.retry_cnt__c = 0;
            // }
            // else {
            //     rowDataSFDC = NFMUtil.LogAutoSend(rowDataSFDC, null, status);
            // }
            //update to aws 20220228 sushanhu satrt
            PIHelper.PIIntegration pi =PIHelper.getPIIntegrationInfo('NFM606');
            NFMUtil.response result =NFMUtil.sendToPiAWS(rowDataStr,pi.newUrl,pi.token);
            system.debug('aws result---'+result);
            responseBody=result.responseBody;
            //Map<String, Object> res = (Map<String, Object>)JSON.deserializeUntyped(responseBody);
            //status=(String)res.get(status);
            if ('202'.equals(result.status)) {
                logstr += status+'\n';
                rowDataSFDC.retry_cnt__c = 0;
            }
                     rowDataSFDC.retry_cnt__c = 0;
            }
            else {
                rowDataSFDC = NFMUtil.LogAutoSend(rowDataSFDC, null, status);
            }
            //update to aws 20220228 sushanhu end
        } catch (Exception ex) {
            // TODO IOException
             // 异常重发
force-app/main/default/classes/NFM607Rest.cls
@@ -3,7 +3,13 @@
 */
@RestResource(urlMapping = '/NFM607/*')
global with sharing class NFM607Rest {
    //add to AWS 回复 start sushanhu 20220225
    static Boolean SFStatus=true;
    static String SFMessage='';
   //add to AWS 回复 end sushanhu 20220225
    private static final String LOG_TYPE = 'NFM607';
    //add Response to aws 20220221 add sushanhu
    static NFMUtil.NFMResponse result = new NFMUtil.NFMResponse();
    global class GeData {
        public String mngCd; //  ASE管理编码
@@ -21,10 +27,20 @@
        public String activityStartTime; //活动开始时间
        public String activityEndTime; //活动结束时间
        public String workDesc; //工作描述
        //add             wangweipeng         2022/02/14      start
        // add 加密字段索引 add 20220210
        public String DataId; //加密字段索引
        //add 加密字段密文 20220210
        public String customerNmEncrypted;
           //add             wangweipeng         2022/02/14      start
        public String customerTel;//客户手机号码
        public String workPlace;//工作场所
        //add             wangweipeng         2022/02/14      end
           //add             wangweipeng         2022/02/14      end
        //add 20220216 sushanhu start
        public String customerTelEncrypted;
        public String workPlaceEncrypted;
        // add 20220216 sushanhu end
    }
    @HttpPost
@@ -32,7 +48,7 @@
        // 取得接口传输内容
        String strData = RestContext.request.requestBody.toString();
        List < GeData > ges = (List < GeData > ) JSON.deserializeStrict(strData, List < GeData > .class);
        system.debug('ges---'+ges);
        if (ges == null) {
            return;
        }
@@ -52,8 +68,16 @@
        RestResponse res = RestContext.response;
        res.addHeader('Content-Type', 'application/json');
        res.statusCode = 200;
        String jsonResponse = '{"status": "Success", "Message":"成功"}';
        res.responseBody = Blob.valueOf(jsonResponse);
        // String jsonResponse = '{"status": "Success", "Message":"成功"}';
        // res.responseBody = Blob.valueOf(jsonResponse);
        //updata response toAWS 20220225 sushanhu start
        NFMUtil.NFMResponse result = NFMUtil.getNFMResponse();
        result.SFStatus=SFStatus;
        result.SFMessage=SFMessage;
        String jsonResponse =JSON.serialize(result);
        system.debug('result---'+jsonResponse);
        res.responseBody = blob.valueOf(jsonResponse);
        //updata response toAWS 20220225 sushanhu end
        return;
    }
@@ -105,7 +129,7 @@
                if (String.isNotBlank(ged.departmentCd)) {
                    accountCodeList.add(ged.departmentCd);
                }
                system.debug('date---'+Date.valueOf(ged.activityDailyDate));
                dateCalendarMap.put(Date.valueOf(ged.activityDailyDate), null);
            }
@@ -166,11 +190,17 @@
                    ASEAct.VisitStaff__c = ged.customerNm;
                    ASEAct.ReporterASE__c = contactId;//报告者
                    ASEAct.DurationInMinutes__c =  getDurationInMinutes(ged);//持续时间分钟
                    activityIDStr += ged.activityID +'\n';
                    //add             wangweipeng         2022/02/14      start
                    ASEAct.CustomerTel__c = ged.customerTel;//客户手机号码
                    ASEAct.WorkPlace__c = ged.workPlace;//工作场所
                    //add             wangweipeng         2022/02/14      end
                    activityIDStr += ged.activityID +'\n';
                    ASEAct.AWS_Data_Id__c =ged.DataId;//加密索引 20220207
                    ASEAct.VisitStaffEncrypt__c=ged.customerNmEncrypted;//密文 20220207
                   //add sushanhu 2022/02/16 sart
                   ASEAct.CustomerTel_Encrypted__c=ged.customerTelEncrypted;
                   ASEAct.WorkPlace_Encrypted__c =ged.workPlaceEncrypted;
                    //add sushanhu 2022/02/16 end
                    upsertASEList.add(ASEAct);
                }
@@ -329,9 +359,17 @@
        if (String.isBlank(ged.visitDistinction) ) {
            result += 'DataError:  拜访区分 [ visitDistinction ] is null!\n';
        }
        // if (String.isBlank(ged.DataId) ) {
        //     result += 'DataError:  加密索引 [ DataId ] is null!\n';
        // }
        // if (String.isBlank(ged.customerNmEncrypted)) {
        //     result += 'DataError:  客户姓名密文 [ customerNmEncrypted ] is null!\n';
        // }
        if (String.isNotBlank(activityID) && String.isNotBlank(result)) {
            result = activityID + result;
        }
        return result;
    }
force-app/main/default/classes/NFM612Rest.cls
@@ -1,5 +1,9 @@
@RestResource(urlMapping = '/NFM612/*')
global with sharing class NFM612Rest {
    //add to AWS 回复 start sushanhu 20220225
    static Boolean SFStatus=true;
    static String SFMessage='';
   //add to AWS 回复 end sushanhu 20220225
    public static final String LOG_TYPE = 'NFM612';
    global class GeData {
        public RepairOderInfo repairOderInfo;
@@ -14,7 +18,10 @@
        public String departmentCd; //报修科室编码
        public String repairApplyPerson; //报修人用户编码
        public String repairApplicantName; //报修人姓名
        public String repairApplicantNameEncrypted; //报修人姓名密文 add20220214
        public String repairApplyPersonTel; //报修人联系人电话
        public String repairApplyPersonTelEncrypted;//保修人联系电话 密文 add 20220214
        public String DataId;//aws 存储凭证 add 20220214
        public String repairApplyType; // 报修人岗位
        public String equipmentCategory; //设备大类
        public String assetType; //设备类型
@@ -88,8 +95,16 @@
        res.addHeader('Content-Type', 'application/json');
        res.statusCode = 200;
        //String jsonResponse = '{"status": "Success", "Message":'  + gedata + '}';
        String jsonResponse = '{"status": "Success", "Message":"成功"}';
        res.responseBody = Blob.valueOf(jsonResponse);
        // String jsonResponse = '{"status": "Success", "Message":"成功"}';
        // res.responseBody = Blob.valueOf(jsonResponse);
         //updata response toAWS 20220225 sushanhu start
         NFMUtil.NFMResponse result = NFMUtil.getNFMResponse();
         result.SFStatus=SFStatus;
         result.SFMessage=SFMessage;
         String jsonResponse =JSON.serialize(result);
         system.debug('result---'+jsonResponse);
         res.responseBody = blob.valueOf(jsonResponse);
         //updata response toAWS 20220225 sushanhu end
        return;
    }
    @future(callout = true)
@@ -220,7 +235,9 @@
                    repair.EndTimeThird__c = NFMUtil.parseStr2DateTime(ged.repairOderInfo.endTimeThird); //三次上门结束时间
                    repair.FaultDescriptionThird__c = ged.repairOderInfo.faultDescriptionThird; //三次故障描述
                    repair.ApplicantType__c = ged.repairOderInfo.applicantType; //申请修理人类型
                    repair.RepairApplicantName_Encrypted__c =ged.repairOderInfo.repairApplicantNameEncrypted; //报修人姓名密文 add 20220214
                    repair.RepairApplicantTel_Encrypted__c = ged.repairOderInfo.repairApplyPersonTelEncrypted;//保修人联系电话密文 add 20220214
                    repair.AWS_Data_Id__c =ged.repairOderInfo.DataId;//AWS 存储凭证 add 20220214
                    // repair.Applicant__c = canidMap.get(ged.repairOderInfo.applicantId).Id; //申请修理人编号
                    repair.Applicanter__c = personMap.get(ged.repairOderInfo.applicantId);//申请修理人编号
                    repair.ApplicationTime__c = NFMUtil.parseStr2DateTime(ged.repairOderInfo.applyDate); //申请时间
@@ -230,6 +247,8 @@
                    repair.AirframeCodeEngineer__c = ged.applyRepairInfo.equipmentCd; //机身编码(工程师)
                    repair.ResponseResultDesc__c = ged.applyRepairInfo.responseResultDesc; //应对描述
                    repair.ProcessResult__c = ged.applyRepairInfo.processResult; //处理结果
                    if ('问题已解决'.equals(ged.applyRepairInfo.processResult)) {
                        repair.Status__c = '关闭';
                    } else {
@@ -308,7 +327,7 @@
                        SELECT id, CManageCode__c,Employee_No_manual__c 
                        FROM Contact 
                        WHERE CManageCode__c IN: rpersonList OR Employee_No_manual__c IN:rpersonList];
        Map < String, Id > contactMap = new Map < String, Id > ();
        Map < String, Id > contactMap = new Map < String, Id > ();
        for (Contact con: couList) {
            contactMap.put(con.CManageCode__c, con.Id);
            if (String.isNotBlank(con.Employee_No_manual__c)) {
force-app/main/default/classes/NFM620Rest.cls
@@ -10,7 +10,10 @@
@RestResource(urlMapping = '/NFM620/*')
global with sharing class NFM620Rest {
    //新增NFM620Rest 商品询问单接收数据接口 精琢技术 start
   //add to AWS 回复 start sushanhu 20220225
   static Boolean SFStatus=true;
   static String SFMessage='';
  //add to AWS 回复 end sushanhu 20220225
    global class GeDatas {
        public NFMUtil.Monitoring Monitoring;
        public  GeData[] GeData;
@@ -26,6 +29,9 @@
        public String Request;                   // 委托事项
        public String RequestDetail;             // 委托事项详细
        public String ApproverID;                // 审核人员员工编码
        public String ContactWayEncrypted;         //联系方式密文 for pi
        public String DataId;                      //AWS 加密凭据
        public Integer ContactType;                 //联系方式 1为邮箱 2为电话
    }
    @HttpPost
@@ -34,7 +40,7 @@
        // 取得接口传输内容
        String strData = RestContext.request.requestBody.toString();
        GeDatas ges = (GeDatas) JSON.deserializeStrict(strData, GeDatas.class);
        system.debug('rquest----'+strData);
        if (ges == null ) {
            return;
        }
@@ -53,8 +59,16 @@
        RestResponse res = RestContext.response;
        res.addHeader('Content-Type', 'application/json');
        res.statusCode = 200;
        String jsonResponse = '{"status": "Success", "Message":""}';
        // String jsonResponse = '{"status": "Success", "Message":""}';
        // res.responseBody = blob.valueOf(jsonResponse);
        //updata response toAWS 20220225 sushanhu start
        NFMUtil.NFMResponse result = NFMUtil.getNFMResponse();
        result.SFStatus=SFStatus;
        result.SFMessage=SFMessage;
        String jsonResponse =JSON.serialize(result);
        system.debug('result---'+jsonResponse);
        res.responseBody = blob.valueOf(jsonResponse);
        //updata response toAWS 20220225 sushanhu end
        return;
    }
@@ -128,7 +142,7 @@
                if (String.isNotBlank(geData.Campaign)) {
                    camNoList.add(geData.Campaign);
                }
                geDataListNew.add(geData);
            }
            //使用统一用户ID获取科室、战略科室分类、用户姓名并存入Map
@@ -177,12 +191,9 @@
                    }
                }
            }
            // 将XML各数据项更新到商品询问单对象中
            for (GeData geData : geDataListNew) {
                Inquiry_form__c inquiry = new Inquiry_form__c();
                inquiry.ComPlat_Name__c = geData.Name;                                       //询问单名称
@@ -194,24 +205,26 @@
                inquiry.ContactId__c = geData.ContactId;                          //统一用户ID
                if (String.isNotBlank(ownerMap.get(geData.ApproverID))){
                    inquiry.OwnerId = ownerMap.get(geData.ApproverID);            //所有人
                }
                }
                inquiry.AWS_Data_Id__c =geData.DataId;                              //AWS加密凭据 add 200220214
                
                //委托事项取值后拆分
                List<String> requestList = geData.Request.split(';');
                String request1 = '';
                for (String req11 : requestList) {
                    request1 += NFMUtil.getMapValue(transferMap, 'Request1__c', req11, iflog) + ';';
                }
                }
                inquiry.Request1__c = request1.substring(0, request1.length() - 1);  //委托事项
                //使用统一用户ID获取科室、战略科室、客户姓名
                if (conInfoMap.containsKey(geData.ContactId)) {
                    Contact contact = conInfoMap.get(geData.ContactId);
                    inquiry.Hospital_Name__c = contact.Account.Id;                    //科室名
                    //inquiry.Department_Class__c = contact.Strategic_dept_Class__c;    //战略科室分类
                    inquiry.Hospital_Name__c = contact.Account.Id;                    //科室名
                    // inquiry.Department_Class__c = contact.Strategic_dept_Class__c;    //战略科室分类
                    inquiry.Contact_Name__c = contact.Id;                             //客户姓名
                    //inquiry.OwnerId = contact.Strategic_dept_Class__r.OwnerId;        //所有人
                }
                    // inquiry.OwnerId = contact.Strategic_dept_Class__r.OwnerId;        //所有人
                }
                //使用市场活动编码获取市场活动ID
                if (String.isNotBlank(geData.Campaign)) {
                    if (String.isNotBlank(camInfoMap.get(geData.Campaign))) {
@@ -219,19 +232,24 @@
                        inquiry.LeadSource__c = '学会会议';                    //询问单来源
                    } else {
                        iflog.ErrorLog__c += geData.InquiryNo + ':市场活动编码不存在。\n';
                        continue;
                        continue;
                    }
                } else {
                    inquiry.LeadSource__c = '智慧医疗';                 //询问单来源
                }
                logstr += '咨询单来源:' + inquiry.LeadSource__c + '\n';
                logstr += '咨询单来源:' + inquiry.LeadSource__c + '\n';
                //联系方式的值是否包含@来判断是邮箱还是电话
                if (geData.ContactWay.contains('@')) {
                if (geData.ContactType==1) {
                    inquiry.Phone__c = '';                            //电话
                    inquiry.Phone_Encrypted__c='';                     //电话密文 add 20220214
                    inquiry.Email__c = geData.ContactWay;             //邮箱
                    inquiry.Email_Encrypted__c =geData.ContactWayEncrypted; //邮箱密文 add 20220214
                } else {
                    inquiry.Phone__c = geData.ContactWay;
                    inquiry.Email__c = '';
                    inquiry.Email_Encrypted__c = ''; //邮箱密文 add 20220214
                    inquiry.Phone_Encrypted__c=geData.ContactWayEncrypted;    //电话密文 add 20220214
                }
                if (String.isNotBlank(inqInfoMap.get(geData.InquiryNo))) {
force-app/main/default/classes/NFM623Rest.cls
@@ -9,6 +9,10 @@
*************************************************************************/
@RestResource(urlMapping = '/NFM623/*')
global with sharing class NFM623Rest {
     //add to AWS 回复 start sushanhu 20220225
     static Boolean SFStatus=true;
     static String SFMessage='';
    //add to AWS 回复 end sushanhu 20220225
    //新增NFM623Rest 学会·活动参加人员接收数据接口 精琢技术 start
    global class GeDatas {
@@ -19,14 +23,14 @@
    global class GeData {
        public String Num;                              // 活动编码
        public String Name;                             // 活动名称
        public ViewContactIdS[] ViewContactIdS;
        public ViewContactIdS[] ViewContactIdS;      //替换为aws存储凭据ID 20220225 sushanhu
        public LabelTypeS[] LabelTypeS;
    }
    global class ViewContactIdS {
        public String ViewContactId;                     // 直播观看统一用户ID  
    }
    global class LabelTypeS {
        public String LabelType;                         // 标签分类
        public String Label;                             // 标签内容 
@@ -34,7 +38,7 @@
    @HttpPost
    global static void execute() {
        // 取得接口传输内容
        String strData = RestContext.request.requestBody.toString();
        GeDatas ges = (GeDatas) JSON.deserializeStrict(strData, GeDatas.class);
@@ -57,8 +61,16 @@
        RestResponse res = RestContext.response;
        res.addHeader('Content-Type', 'application/json');
        res.statusCode = 200;
        String jsonResponse = '{"status": "Success", "Message":""}';
        // String jsonResponse = '{"status": "Success", "Message":""}';
        // res.responseBody = blob.valueOf(jsonResponse);
        //updata response toAWS 20220225 sushanhu start
        NFMUtil.NFMResponse result = NFMUtil.getNFMResponse();
        result.SFStatus=SFStatus;
        result.SFMessage=SFMessage;
        String jsonResponse =JSON.serialize(result);
        system.debug('result---'+jsonResponse);
        res.responseBody = blob.valueOf(jsonResponse);
        //updata response toAWS 20220225 sushanhu end
        return;
    }
@@ -119,7 +131,7 @@
            //使用统一用户ID获取客户人员ID、客户人员姓名、医院科室存入Map
            Map<String, Contact> contactMap = new Map<String, Contact>();
            List<String> conIDList = new List<String>();
            if (conIDMapNew.size() > 0) {
            if (conIDMapNew.size() > 0) {
                List<Contact> contactList = [select Id,Name,UnifiedI_Contact_ID__c,
                                            AccountId,Account.Name 
                                            from Contact where UnifiedI_Contact_ID__c in :conIDListNew];
@@ -130,6 +142,18 @@
                        conIDList.add(conInfo.Id);
                    }
                } 
                //update to 通过aws存储的unified查询 start 20220225
                // List<Contact> contactList = [select Id,Name,AWS_UnifiedI_Contact_ID__c,
                //                             AccountId,Account.Name
                //                             from Contact where AWS_UnifiedI_Contact_ID__c in :conIDListNew];
                // if (contactList.size() > 0) {
                //     //客户人员ID获取成功
                //     for (Contact conInfo : contactList) {
                //         contactMap.put(conInfo.AWS_UnifiedI_Contact_ID__c, conInfo);
                //         conIDList.add(conInfo.Id);
                //     }
                // }
                //update to 通过aws存储的unified查询 20220225 end
            }
            //使用市场活动编码获取市场活动ID和活动名称存入Map
            List<String> camIDList = new List<String>();
@@ -155,7 +179,20 @@
                    camViewContactMap.put(cm.ViewContactId__c, cm.Campaign__r.Num__c);
                }
            }
            //update to 获取aws 统一凭据关联 sushanhu 20220225 satrt
            // List<CampaignMember__c>  camMemberList = [select Id,Contact_ID__c,AWS_ViewContact_Id__c,
            //                                             Campaign__c,Campaign__r.Num__c
            //                                             from CampaignMember__c where Campaign__c in : camIDList];
            // Map<String, String> camContactMap = new Map<String, String>();
            // Map<String, String> camViewContactMap = new Map<String, String>();
            // if (camMemberList.size() > 0 ) {
            //     for (CampaignMember__c cm : camMemberList) {
            //         camContactMap.put(cm.Contact_ID__c, cm.Campaign__r.Num__c);
            //         camViewContactMap.put(cm.AWS_ViewContact_Id__c, cm.Campaign__r.Num__c);
            //     }
            // }
             //update to 获取aws 统一凭据关联 sushanhu 20220225 end
            //将原有活动标签对象中市场活动ID和标签活动名称存入Map中
            List<CampaignLable__c> camLabInfoList = [select id,name,Campaign__c,Lable__c,LableType__c from CampaignLable__c where  Campaign__c in : camIDList];
            Map<String, String> camLabInfoMap = new Map<String, String>();
force-app/main/default/classes/NFM624Rest.cls
@@ -10,6 +10,10 @@
@RestResource(urlMapping = '/NFM624/*')
global with sharing class NFM624Rest {
    //add to AWS 回复 start sushanhu 20220225
    static Boolean SFStatus=true;
    static String SFMessage='';
   //add to AWS 回复 end sushanhu 20220225
    private static final String LOG_TYPE = 'NFM624';
    // global class GeDatasRest {
    //     public GeDatas GeDatas;
@@ -21,13 +25,15 @@
    }
    global class GeData {
        public String ContactId; //统一平台ID
        public String ContactId; //统一平台ID//Update to aws 存储的AWSContactId 20220225 SUSHANHU
        public String ServiceUserId; //服务平台用户ID
        public String PersonManagementCode; //人员管理编码 
        public String HospitalManagementCode2; //医院平台编码  平台编码 PlatformCode__c
        public String DepartmentManagementCode2; //科室平台编码  平台编码 PlatformCode__c
        public String Name; //姓名
        public String NameEncrypted;//姓名密文 add 20220215
        public String Mobile; //手机号码
        public String MobileEncrypted;//手机号码密文 add 20220215
        public String State; //单位所在省份
        public String City; //市
        public String AccountName; //医院名
@@ -37,10 +43,12 @@
        public String RelatedDepartment; //关联SFDC科室 客户管理编码(手写) AgentCode_Ext__c
        public String Type; //职种
        public String ContactAddress; //联系地址
        public Boolean ForbiddenStatus; //平台用户禁用标识
        public String ContactAddressEncrypted;//联系地址密文
        public Boolean ForbiddenStatus; //平台用户禁用标识
        public String RegSource; //注册平台来源
        public Boolean AgentFlag; //经销商标识
        public String ApproverID; //审核人员员工编码
        public String DataId;//aws存储凭据
    }
    @HttpPost
@@ -49,7 +57,7 @@
        // 取得接口传输内容
        String strData = RestContext.request.requestBody.toString();
        GeDatas ges = (GeDatas) JSON.deserializeStrict(strData, GeDatas.class);
        system.debug('ges---'+ges);
        if (ges == null) {
            return;
@@ -71,8 +79,16 @@
        RestResponse res = RestContext.response;
        res.addHeader('Content-Type', 'application/json');
        res.statusCode = 200;
        String jsonResponse = '{"status": "Success", "Message":""}';
        res.responseBody = blob.valueOf(jsonResponse);
        // String jsonResponse = '{"status": "Success", "Message":""}';
        // res.responseBody = blob.valueOf(jsonResponse);
         //updata response toAWS 20220225 sushanhu start
         NFMUtil.NFMResponse result = NFMUtil.getNFMResponse();
         result.SFStatus=SFStatus;
         result.SFMessage=SFMessage;
         String jsonResponse =JSON.serialize(result);
         system.debug('result---'+jsonResponse);
         res.responseBody = blob.valueOf(jsonResponse);
         //updata response toAWS 20220225 sushanhu end
        return;
    }
@@ -130,7 +146,11 @@
        try { //根据传过来的管理编码查询如果可以查询得到结果则更新,查询不到则新增
            List < Gedata > newGeDataList = new List < Gedata > ();
            for (Gedata gedata: GeDataList) {
                string dataComplete = verify(gedata);
                //for test
                gedata.AgentFlag=false;
                // string dataComplete = verify(gedata);
                string dataComplete =null;
                // test  end  for pi
                if (!String.isBlank(dataComplete)) {
                    logstr += dataComplete;
                    rowData.Is_Error__c = 1;
@@ -282,12 +302,18 @@
                    ct.MobilePhone = gedata.Mobile;
                    ct.RegSource__c = comefrom;
                    ct.UnifiedI_Contact_ID__c = gedata.ContactId; //统一平台Id
                    // //UPDATE TO AWS 存储的统一平台id
                    // ct.AWS_UnifiedI_Contact_ID__c=gedata.ContactId; //统一平台Id
                    ct.ServicePlatformCode__c = gedata.ServiceUserId; //服务平台用户Id
                    ct.Contact_address__c = gedata.ContactAddress;//联系地址
                    ct.Contact_address_Encrypted__c=gedata.ContactAddressEncrypted;//联系地址密文 add 20220215
                    ct.Platform_disabled_representation__c = gedata.ForbiddenStatus;//平台禁用标识
                    //ct.IsFromPlatform__c = true; //来自智慧医疗创建
                    ct.Ignore_Same_Name__c = true; //不是重复的客户名 
                    //ct.SendToComPlat__c = true;
                    ct.AWS_Data_Id__c =gedata.DataId;//add 20220215 aws存储凭证
                    ct.MobilePhone_Encrypted__c =gedata.MobileEncrypted;//add 20220215 手机密文
                    ct.LastName_Encrypted__c =gedata.NameEncrypted;//add 20220215 姓名密文
                    String personCode = gedata.PersonManagementCode;
@@ -518,11 +544,19 @@
        if (string.isblank(gda.Name)) {
            result += 'DataError:姓名为空\n';
        }
        if (string.isblank(gda.NameEncrypted)) {
            result += 'DataError:姓名密文为空\n';
        }
        if (string.isblank(gda.Mobile)) {
            result += 'DataError:手机号为空\n';
        }
        if (string.isblank(gda.MobileEncrypted)) {
            result += 'DataError:手机号密文为空\n';
        }
        if (string.isblank(gda.RegSource)) {
            result += 'DataError:注册平台来源为空\n';
        }if (string.isblank(gda.DataId)) {
            result += 'DataError:AWS加密凭据为空\n';
        }
        if (gda.AgentFlag) {
            if (string.isblank(gda.PersonManagementCode)) {
@@ -618,12 +652,11 @@
        List<Inquiry_form__c> InquiryList = [select Id,Inquiry_No__c,ContactId__c,Hospital_Name__c,Department_Class__c,Contact_Name__c from Inquiry_form__c where ContactId__c = :ContactId];
        system.debug('InquiryList'+InquiryList);
        //根据统一用户Id查询联系人
        //select Id,Name,UnifiedI_Contact_ID__c,AccountId,Account.Name from Contact
        List<Contact> contactList = [select Id,Name,UnifiedI_Contact_ID__c,Account.Id,Strategic_dept_Class__c,AccountId,Account.Name,Strategic_dept_Class__r.OwnerId from Contact where UnifiedI_Contact_ID__c = :ContactId];
        system.debug('contactList' + contactList);
        system.debug('contactList' + contactList);
        if(InquiryList.size()>0){
             //统一用户ID存入List、询问单ID存Map
            //统一用户ID存入List、询问单ID存Map
            Map<String, String> inquiryMap = new Map<String, String>();
            //List<String> contactIdList = new List<String>();
            for (Inquiry_form__c inquiryInfo : inquiryList) {
@@ -649,7 +682,8 @@
        //补充询问单部分 end
        
        //补充学会部分 start
        List<CampaignMember__c> capMemList = [select Id,Contact_ID__c,Campaign__c,Campaign__r.Num__c,ViewContactId__c from CampaignMember__c where ViewContactId__c = :ContactId];
        List<CampaignMember__c> campaignMemberList = new List<CampaignMember__c>();
        List<CampaignMember__c> capMemList = [select Id,Contact_ID__c,Campaign__c,Campaign__r.Num__c,ViewContactId__c from CampaignMember__c where Contact_ID__c = :ContactId];
        if(capMemList.size() > 0){
            system.debug('capMemList=================>'+capMemList);
            Map<String, String> capMemMap = new Map<String, String>(); 
force-app/main/default/classes/NFM702Controller.cls
@@ -39,6 +39,9 @@
        public String HcpNo;    //HPC编码
        public Boolean IsActive;    //是否有效
        public String UpdateStatus;     //操作类型
        // add by sushanhu 20220304 for pi satrt
        public String DataId;           //aws 存储凭据
        // add by sushanhu 20220304 for pi end
    }
    @future(callout = true)
@@ -72,7 +75,8 @@
                                        Phone,      //电话
                                        HcpNo__c,       //HCP编码
                                        Isactive__c,    //是否有效
                                        UpdateStatus__c            //操作类型
                                        UpdateStatus__c,            //操作类型
                                        AWS_Data_Id__c              //aws 存储凭据 add bysushanhu 20220304 for Pi
                                        from Contact WHERE Id IN:accIdList order by Id];  //AccountId
        String logstr = iflog.Log__c + ' ' + 'NumberOfRecord=' + conList.size() + '\n';
@@ -98,6 +102,7 @@
                ged.HcpNo = con.HcpNo__c;
                ged.IsActive = '有效'.equals(con.Isactive__c)? true:false;
                ged.UpdateStatus = con.UpdateStatus__c;
                ged.DataId  =   con.AWS_Data_Id__c;//add by sushanhu  for pi 20220304
                gds.GeData.add(ged);
            }
@@ -178,26 +183,56 @@
        }
        try {
            NFMUtil.response response = NFMUtil.sendToSapStatusAndBody(rowDataStr, NFMUtil.NFM702_ENDPOINT);
            System.debug('NFM702Log--status->'+ status);
            // NFMUtil.response response = NFMUtil.sendToSapStatusAndBody(rowDataStr, NFMUtil.NFM702_ENDPOINT);
            // System.debug('NFM702Log--status->'+ status);
            // status = response.status;
            // ResponseBody = response.responseBody;
            // Response resultList = ( Response ) JSON.deserializeStrict(ResponseBody, Response.class);
            // System.debug('NFM702Log--status->'+ ResponseBody);
            // Result = resultList.Result.Result;
            // if ('00'.equals(Result)) {
            //     logstr += ResponseBody+'\n';
            //     rowDataSFDC.retry_cnt__c = 0;
            //     //iflog.Log__c = 'ok';
            // }
            // else {
            //     //iflog.Log__c = 'ok2';
            //     rowDataSFDC = NFMUtil.LogAutoSend(rowDataSFDC, null, status);
            // }
            //update to AWS sushanhu FOR PI start 20220304
            PIHelper.PIIntegration pi =PIHelper.getPIIntegrationInfo('NFM702');
            NFMUtil.response response = NFMUtil.sendToPiAWS(rowDataStr, pi.newUrl,pi.token);
            status = response.status;
            System.debug('NFM702Log--status->'+ status);
            ResponseBody = response.responseBody;
            Response resultList = ( Response ) JSON.deserializeStrict(ResponseBody, Response.class);
            System.debug('NFM702Log--status->'+ ResponseBody);
            Result = resultList.Result.Result;
            if ('00'.equals(Result)) {
                logstr += ResponseBody+'\n';
                rowDataSFDC.retry_cnt__c = 0;
                //iflog.Log__c = 'ok';
            }
            else {
                //iflog.Log__c = 'ok2';
            System.debug('NFM702Log--responsebody->'+ ResponseBody);
            if ('200'.equals(status)) {
                //aws 正确响应
                // Response resultList = ( Response ) JSON.deserializeStrict(ResponseBody, Response.class);
                Map<String, Object> result = (Map<String, Object>)JSON.deserializeUntyped(ResponseBody);
                String statusCode =(String)result.get('status');
                if ('0'.equals(statusCode)) {
                    logstr += ResponseBody+'\n';
                    rowDataSFDC.retry_cnt__c = 0;
                    //iflog.Log__c = 'ok';
                } else {
                    //iflog.Log__c = 'ok2';
                rowDataSFDC = NFMUtil.LogAutoSend(rowDataSFDC, null, status);
                }
            }
            else {
                logstr=ResponseBody;
                iflog.ErrorLog__c=ResponseBody;
            }
            //update to AWS sushanhu FOR PI  20220304 end
        }catch ( Exception ex ) {
           //打印错误日志
           System.debug(Logginglevel.ERROR, LOG_TYPE + iflog.Name + ':' + ex.getMessage());
force-app/main/default/classes/NFM702ControllerHandler.cls
New file
@@ -0,0 +1,5 @@
public with sharing class NFM702ControllerHandler {
    public NFM702ControllerHandler() {
    }
}
force-app/main/default/classes/NFM702ControllerHandler.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>41.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/NFMUtil.cls
@@ -78,7 +78,8 @@
            //NFM007_ENDPOINT = 'http://wdp.olympus.com.cn:8089/RESTAdapter/NFM007';
            NFM007_ENDPOINT = 'https://wdp.olympus.com.cn:44301/RESTAdapter/NFM007';
            NFM008_ENDPOINT = 'https://owdc-test.olympus.co.jp/XISOAPAdapter/MessageServlet?senderParty=&senderService=OCM_SFDC_T&receiverParty=&receiverService=&interface=NFM008_Sync_BC2GPI&interfaceNamespace=http%3A%2F%2Folympus.co.jp%2Fgpi%2FNFM008';
            NFM103_ENDPOINT = 'http://wdp.olympus.com.cn:8089/RESTAdapter/NFM103';
            // NFM103_ENDPOINT = 'http://wdp.olympus.com.cn:8089/RESTAdapter/NFM103';
            NFM103_ENDPOINT = 'https://sfpi-mebg-test.olympuschina.com/api/nfm/103';//aws 103接口
            // NFM106_ENDPOINT = 'https://owdc-test.olympus.co.jp/XISOAPAdapter/MessageServlet?senderParty=&senderService=OCM_SFDC_T&receiverParty=&receiverService=&interface=NFM106_Sync_BC2GPI&interfaceNamespace=http%3A%2F%2Folympus.co.jp%2Fgpi%2FNFM106';
            NFM106_ENDPOINT = 'http://wdp.olympus.com.cn:8089/RESTAdapter/NFM106';
            //NFM106_ENDPOINT = 'https://sfdc-ocm-test.olympus.co.jp/XISOAPAdapter/MessageServlet?senderParty=&senderService=OCM_SFDC_T&receiverParty=&receiverService=&interface=NFM106_Sync_BC2GPI&interfaceNamespace=http%3A%2F%2Folympus.co.jp%2Fgpi%2FNFM106';
@@ -100,16 +101,16 @@
            NFM401_ENDPOINT = 'http://ec2-161-189-3-104.cn-northwest-1.compute.amazonaws.com.cn:8088/dojtest/dojInfo/recevie';
            NFM402_ENDPOINT = 'http://ec2-161-189-3-104.cn-northwest-1.compute.amazonaws.com.cn:8088/dojtest/dojInfo/getDojInfoByRefNo';
            NFM501_ENDPOINT = 'http://cusdata.qianlima.com/v1/info/page/';
            NFM502_ENDPOINT = 'http://cusdata.qianlima.com/v1/info/detailHtml?url=';
            NFM504_ENDPOINT = 'http://cusdata.qianlima.com/v1/customer/albs/feedback';
            // NFM501_ENDPOINT = 'http://cusdata.qianlima.com/test/v1/info/page/';
            NFM501_ENDPOINT = 'https://sfpi-mebg-test.olympuschina.com/api/nfm/501';
            NFM502_ENDPOINT = 'http://cusdata.qianlima.com/test/v1/info/detailHtml?url=';
            NFM504_ENDPOINT = 'http://cusdata.qianlima.com/test/v1/customer/albs/feedback';
            CBPR_Auth_Sap = 'Basic U0ZEQ19XU1VTRVI6cG9xMTIzNDU=';
            // LHJ 20180824 CBPR End
            //CBPR_Auth_Spo = 'http://cbpr.chinacloudsites.cn/sfdc/token';
            CBPR_Auth_Spo = 'http://cbpr.olympuschina.com/sfdc/token';
            QLM_Token = 'http://cusdata.qianlima.com/v1/token';
            // 智慧医疗&服务新系统通信 客户接口
            NFM601_ENDPOINT = 'https://wdp.olympus.com.cn:44301/RESTAdapter/NFM601';
@@ -127,11 +128,11 @@
            NFM115_ENDPOINT = 'https://wdp.olympus.com.cn:44301/RESTAdapter/NFM115';
            // 新服务系统 测试环境
            AWS_DOMAIN = 'https://olympus.bqbot.com';
            // 新服务系统 本地环境(临时)
             // 新服务系统 本地环境(临时)
            // AWS_DOMAIN = 'http://114.249.236.98:29990';
            // AWS_DOMAIN = 'http://jzbase.bqbot.com:29990';
            // AWS_DOMAIN = 'http://114.249.238.243:29990';
            requestURILMS = '/v1/uc/user/syncOlympusUnit';
            appSecretLMS = 'CAE1D68BE3EB4F7AB5FE97EBDD11B83E';
@@ -143,7 +144,7 @@
            NFM007_ENDPOINT = 'https://wdp.olympus.com.cn:44302/RESTAdapter/NFM007';
            NFM008_ENDPOINT = 'https://owdc.olympus.co.jp/XISOAPAdapter/MessageServlet?senderParty=&senderService=OCM_SFDC_P&receiverParty=&receiverService=&interface=NFM008_Sync_BC2GPI&interfaceNamespace=http%3A%2F%2Folympus.co.jp%2Fgpi%2FNFM008';
            //NFM103_ENDPOINT = 'https://owdc.olympus.co.jp/XISOAPAdapter/MessageServlet?senderParty=&senderService=OCM_SFDC_P&receiverParty=&receiverService=&interface=NFM103_Sync_BC2GPI&interfaceNamespace=http%3A%2F%2Folympus.co.jp%2Fgpi%2FNFM103';
            NFM103_ENDPOINT = 'https://wdp.olympus.com.cn:44302/RESTAdapter/NFM103';
            NFM103_ENDPOINT = 'https://wdp.olympus.com.cn:44302/RESTAdapter/NFM103';// 原saphost
            //NFM106_ENDPOINT = 'https://owdc.olympus.co.jp/XISOAPAdapter/MessageServlet?senderParty=&senderService=OCM_SFDC_P&receiverParty=&receiverService=&interface=NFM106_Sync_BC2GPI&interfaceNamespace=http%3A%2F%2Folympus.co.jp%2Fgpi%2FNFM106';
            NFM106_ENDPOINT = 'https://wdp.olympus.com.cn:44302/RESTAdapter/NFM106';
            // LHJ 20180824 CBPR Start
@@ -158,7 +159,8 @@
            NFM401_ENDPOINT = 'http://ec2-161-189-3-104.cn-northwest-1.compute.amazonaws.com.cn:8082/doj/dojInfo/recevie';
            NFM402_ENDPOINT = 'http://ec2-161-189-3-104.cn-northwest-1.compute.amazonaws.com.cn:8082/doj/dojInfo/getDojInfoByRefNo';
            NFM501_ENDPOINT = 'http://cusdata.qianlima.com/v1/info/page/';
            // NFM501_ENDPOINT = 'http://cusdata.qianlima.com/v1/info/page/';
            NFM501_ENDPOINT   ='https://sfpi-mebg-test.olympuschina.com/api/nfm/501';
            NFM502_ENDPOINT = 'http://cusdata.qianlima.com/v1/info/detailHtml?url=';
            NFM504_ENDPOINT = 'http://cusdata.qianlima.com/v1/customer/albs/feedback';
            CBPR_Auth_Sap = 'Basic U0ZEQ19XU1VTRVI6cG9wMTIzNDU=';
@@ -228,7 +230,25 @@
        webservice String timestamp;
        webservice String appKey;
    }
    global class NFMResponse{
        public Boolean SFStatus;
        public String SFMessage;
        public StaticResponse staticResponse;
    }
    global class StaticResponse{
        public string status;
        public String Message;
        public StaticResponse(){
            status='Success';
            Message='';
        }
    }
    public static NFMResponse getNFMResponse(){
        NFMResponse  result=new NFMResponse();
        result.staticResponse =new StaticResponse();
        return result;
    }
    /**
     * @return yyyyMMdd の日付文字列
     */
@@ -341,7 +361,7 @@
        return rtn;
    }
    /**
     /**
     * add       wangweipeng       2022/02/11
     * [formatDateTime2StrDateTime description]
     * @param  dt [日期/时间]
@@ -375,7 +395,7 @@
        return parseStr2Date(pDateTime.substring(0, 8));
    }
    /**
     /**
     * add    wangweipeng           2022/02/15
     * [parseStr2DateTime description]
     * @param  pDate [日期(不包括时间)]
@@ -416,13 +436,13 @@
                return null;
            }
            rtn = Datetime.newinstance(
                Integer.valueOf(pDate.substring(0, 4)),
                Integer.valueOf(pDate.substring(4, 6)),
                Integer.valueOf(pDate.substring(6, 8)),
                Integer.valueOf(pTime.substring(0, 2)),
                Integer.valueOf(pTime.substring(2, 4)),
                Integer.valueOf(pTime.substring(4, 6))
            );
                      Integer.valueOf(pDate.substring(0, 4)),
                      Integer.valueOf(pDate.substring(4, 6)),
                      Integer.valueOf(pDate.substring(6, 8)),
                      Integer.valueOf(pTime.substring(0, 2)),
                      Integer.valueOf(pTime.substring(2, 4)),
                      Integer.valueOf(pTime.substring(4, 6))
                  );
        } catch (Exception ex) {
            System.debug(Logginglevel.ERROR, 'NFMUtil#parseStr2DateTime(' + pDate + ', ' + pTime + ')' + ex.getMessage());
        }
@@ -452,10 +472,10 @@
                return null;
            }
            rtn = Date.newinstance(
                Integer.valueOf(pStr.substring(0, 4)),
                Integer.valueOf(pStr.substring(4, 6)),
                Integer.valueOf(pStr.substring(6, 8))
            );
                      Integer.valueOf(pStr.substring(0, 4)),
                      Integer.valueOf(pStr.substring(4, 6)),
                      Integer.valueOf(pStr.substring(6, 8))
                  );
        } catch (Exception ex) {
            System.debug(Logginglevel.ERROR, 'NFMUtil#parseStr2Date(' + pStr + ')' + ex.getMessage());
        }
@@ -601,32 +621,6 @@
        return rowData;
    }
    // public static BatchIF_Log__c makeRowDataToOnline(NFMUtil.MonitoringToOnline Monitoring, String NFMType, Object NFMData) {
    //     BatchIF_Log__c rowData = new BatchIF_Log__c();
    //     rowData.Type__c = NFMType;
    //     rowData.MessageGroupNumber__c = Monitoring.MessageGroupNumber;
    //     rowData.TransmissionDateTime__c = Monitoring.TransmissionDateTime;
    //     rowData.RowDataFlg__c = true;
    //     rowData.Log__c = '';
    //     rowData.ErrorLog__c = '';
    //     String rowDataStr = JSON.serialize(NFMData);
    //     if (rowDataStr.length() > 0) {
    //         Integer splitIdx = 1;
    //         while (rowDataStr.length() > 0) {
    //             if (splitIdx == 1) {
    //                 rowData.put('Log__c', rowDataStr.substring(0, (rowDataStr.length() > MaxLogColumnLength ? MaxLogColumnLength : rowDataStr.length())));
    //             } else if (splitIdx == 13) {
    //                 rowData.ErrorLog__c = rowDataStr;
    //                 break;
    //             } else {
    //                 rowData.put('Log' + splitIdx + '__c', rowDataStr.substring(0, (rowDataStr.length() > MaxLogColumnLength ? MaxLogColumnLength : rowDataStr.length())));
    //             }
    //             splitIdx++;
    //             rowDataStr = rowDataStr.substring((rowDataStr.length() > MaxLogColumnLength ? MaxLogColumnLength : rowDataStr.length()));
    //         }
    //     }
    //     return rowData;
    // }
    public static BatchIF_Log__c makeRowData(BatchIF_Log__c iflog, String NFMType, Object NFMData) {
        // TransmissionDateTimeの設定
        Datetime nowDT = Datetime.now();
@@ -868,13 +862,36 @@
        system.debug('ress:' + ress);
        return new response(ress, resb);
    }
    // send to aws to sap sushuanhu 20220222
    public static response sendToPiAWS(String rowDataStr, String endpoint,String awsToken) {
        Http http = new Http();
        HttpRequest req = new HttpRequest();
        HTTPResponse res;
        String resb;
        req.setTimeout(120000);
        req.setEndpoint(endpoint);
        req.setMethod('POST');
        req.setHeader('Content-Type', 'application/json');
        req.setHeader('pi-token', awsToken);
        req.setBody(rowDataStr);
        res = http.send(req);
        string ress =String.valueof(res.getStatusCode());
        resb = res.getBody();
        system.debug('ress:' + ress);
        return new response(ress, resb);
    }
    // 获取aws token sushanhu 20220222
    public static response getAwsToken(){
        String responseBody = AWSServiceTool.getAWSToken();
        return new response('success', responseBody);
    }
    public class response {
        public string status;
        public string responseBody;
        public response(string status, string responseBody) {
            this.status = status;
            this.responseBody = responseBody;
        public response(string status, string responseBody ) {
            this.status         = status;
            this.responseBody   = responseBody;
        }
    }
    // WLIG-BXQBH6 end
@@ -906,10 +923,10 @@
            return null;
        }
        return Time.newInstance(
            Integer.valueOf(timeStr.substring(0, 2)),
            Integer.valueOf(timeStr.substring(2, 4)),
            Integer.valueOf(timeStr.substring(4, 6)),
            0);
                   Integer.valueOf(timeStr.substring(0, 2)),
                   Integer.valueOf(timeStr.substring(2, 4)),
                   Integer.valueOf(timeStr.substring(4, 6)),
                   0);
    }
    //insert by rentongxiao 2020-10-12 end
@@ -930,8 +947,8 @@
        //1、 获取token:
        Http http = new Http();
        HttpRequest req = new HttpRequest();
        String content = 'appKey=' + EncodingUtil.urlEncode(appKey, 'UTF-8') +
            '&appSecret=' + EncodingUtil.urlEncode(appSecret, 'UTF-8');
        String content = 'appKey=' + EncodingUtil.urlEncode(appKey, 'UTF-8') +
                         '&appSecret=' + EncodingUtil.urlEncode(appSecret, 'UTF-8');
        //请求路径
        req.setEndpoint(QLM_Token);
        req.setHeader('Content-Type', QLM_NFM501_Point);
@@ -989,6 +1006,51 @@
        //正常执行
        return new response(ress, response.getBody());
    }
    // NEW QLM AWS 501  接口 sushanhu 20220223
    public static response getAWSQLMData(String endpoint, String token) {
        //2、获取招标信息:记得使用1中获取的token
        Http http = new Http();
        HttpRequest req = new HttpRequest();
        req.setHeader('Content-Type', 'application/json');
        req.setHeader('pi-token',  token);
        req.setTimeout(120000);
        req.setEndpoint(endpoint);
        req.setMethod('GET');
        HTTPResponse response = http.send(req);
        String statusCode = response.getStatus();
        System.debug('response:' + response);
        //http:状态和code
        //如果状态不通过 , 则将状态及空的的数据 , 返回
        if (String.isNotBlank(statusCode)) {
            return new response(statusCode, null);
        }
        System.debug('=====2======' + response.getBody());
        //正常执行
        return new response(statusCode, response.getBody());
    }
    // NEW QLM AWS 502 503接口 sushanhu 20220223
    public static response getAWSQLMData(String endpoint,String jsonStr,  String token) {
        //2、获取招标信息:记得使用1中获取的token
        Http http = new Http();
        HttpRequest req = new HttpRequest();
        req.setHeader('Content-Type', 'application/json');
        req.setHeader('pi-token',  token);
        req.setTimeout(120000);
        req.setEndpoint(endpoint);
        req.setMethod('POST');
        req.setBody(jsonStr);
        HTTPResponse response = http.send(req);
        String statusCode = response.getStatus();
        System.debug('response:' + response);
        //http:状态和code
        //如果状态不通过 , 则将状态及空的的数据 , 返回
        if (String.isNotBlank(statusCode)) {
            return new response(statusCode, null);
        }
        System.debug('=====2======' + response.getBody());
        //正常执行
        return new response(statusCode, response.getBody());
    }
    //接口3,获取其他附件
    public static response503 getFileData(String token503, String endpoint) {
@@ -1035,7 +1097,7 @@
    public static String sendTenInfo(String token504, String jsonStr, String endpoint) {
        Http http = new Http();
        HttpRequest req = new HttpRequest();
        req.setEndpoint('http://cusdata.qianlima.com/test/v1/customer/albs/feedback');
        req.setEndpoint(endpoint);
        req.setHeader('open-authorization', 'Bearer' + token504);
        req.setHeader('Content-Type', 'application/x-www-form-urlencoded');
        req.setMethod('POST');
@@ -1153,8 +1215,10 @@
        system.debug('resb:' + resb);
        return resb;
    }
    //发送给共通平台 精琢技术 thh 2021-09-22 end
    
    //发送给共通平台 精琢技术 thh 2021-09-22 end
    public static Integer ControllerUtil() {
        Integer i = 0;
        i++;
force-app/main/default/classes/NewAgencyContactController.cls
New file
@@ -0,0 +1,124 @@
public class NewAgencyContactController {
    static string sobjectType = 'Agency_Contact__c';
    @AuraEnabled
    public static ControllerResponse Init(string rid,Id pid, string record_type_id){
        system.debug('rid='+rid+',length='+(rid==null?'null':rid.length()+''));
        system.debug('record_type_id='+record_type_id+',length='+(record_type_id==null?'null':record_type_id.length()+''));
        ControllerResponse res = new ControllerResponse();
        Map<string,object> data = new Map<string,object>();
        res.Data = data;
        Agency_Contact__c ac = null;
        List<Metadata.LayoutSection> layout = null;
        if(string.isBlank(rid)){
            layout = MetaDataUtility.GetRecordTypePageLayout(record_type_id, sobjectType);
            data.put('layout', Json.serialize(layout));
        }else{
            ac = [select RecordTypeId from Agency_Contact__c where id = :rid];
            if(ac == null){
                res.Message = 'id不存在';
                return res;
            }
            record_type_id = ac.RecordTypeId;
            system.debug('record_type_id is fresh ='+ac.RecordTypeId);
            layout = MetaDataUtility.GetRecordTypePageLayout(record_type_id, sobjectType);
            data.put('layout', Json.serialize(layout));
            List<String> fieldApiList = new List<String>();
            /*
            for (LayoutDescriberHelper.LayoutSection ls : layout.layoutSections) {
                for (LayoutDescriberHelper.LayoutField lf : ls.layoutFields) {
                    if (lf.fieldAPI != '') {
                        System.debug('lf.fieldAPI='+lf.fieldAPI+' fieldType='+lf.fieldType);
                        fieldApiList.add(lf.fieldAPI);
                    }
                }
            }
            */
            for( Metadata.LayoutSection s: layout){
               system.debug(s);
                for( Metadata.LayoutColumn c: s.layoutColumns){
                   system.debug(c);
                    if(c.layoutItems != null){
                        for( Metadata.layoutItem item: c.layoutItems){
                           system.debug(item);
                            fieldApiList.add(item.field);
                        }
                    }
                }
            }
            system.debug(fieldApiList);
            ac = database.query(SoqlHelper.DistinctQueryFields('select id, AWS_Data_Id__c , ' + string.join(fieldApiList, ',') + ' from ' + sobjectType + ' where id = :rid'));
            data.put('data', ac);
        }
        if(!string.isBlank(pid)){
            data.put('pidType',pid.getSObjectType().getDescribe().getName());
        }
        data.put('fields', SObjectHelper.GetFieldInfos(sobjectType));
        data.put('staticResource', Json.serialize(PIHelper.getPIIntegrationInfo(sobjectType)));
        res.IsSuccess = true;
        return res;
    }
    @AuraEnabled
    public static ControllerResponse Save(Map<string,object> data,string transId){
        system.debug('data='+data);
        system.debug(!data.containsKey('Id') );
        system.debug( data.get('Id') == null);
        //NewAndEditBaseController.Response response = NewAndEditBaseController.save(new Agency_Contact__c(),Json.serialize(data),transId, !data.containsKey('Id') || data.get('Id') == null );
        //ControllerResponse r = new ControllerResponse();
        Sobject sobj = new Agency_Contact__c();
        ControllerResponse r = SaveCore(sobj, data, transId);
        if (r.IsSuccess) {
            r.Data = new Map<string,object>{
                'recordId'=> sobj.Id
            };
        }
        return r;
    }
    public static ControllerResponse SaveCore(Sobject sobj, Map<string,object> data,string transId ) {
        string sobjectTypeValue = sobj.getSObjectType().getDescribe().getName();
        System.debug('sobjectTypeValue:'+sobjectTypeValue+' Info:' + JSON.serialize(data));
        //1. Prepare the payload for  Lead
        Map<String, Schema.SObjectField> fieldAPIToTypeMap = SobjectHelper.GetFieldMap(sobjectTypeValue);
        ControllerResponse r = new ControllerResponse();
        //2. Save Record Process
        String awsDataId = string.valueOf(data.get('AWS_Data_Id__c'));
        Savepoint sp = Database.setSavepoint();
        try{
            for(string field : fieldAPIToTypeMap.keySet()){
                if(data.containsKey(field)){
                    sobj.put(field, data.get(field));
                }
            }
            upsert sobj;
            PIHelper.saveTransLog(sobjectTypeValue,awsDataId,sobj.Id,transId, Json.serialize(data) ,'success','');
            //System.debug('respzhj = ' + resp);
            r.IsSuccess = true;
            return r;
        } catch(Exception e) {
            System.debug('into catch'+e.getMessage());
            Database.rollback(sp);
            r.IsSuccess = false;
            r.message = e.getMessage()+e.getStackTraceString();
            PIHelper.saveTransLog(sobjectTypeValue,awsDataId,sobj.Id,transId, Json.serialize(data) ,'failed',r.message);
            return r;
        }
    }
}
force-app/main/default/classes/NewAgencyContactController.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/NewAndEditASEActivityController.cls
New file
@@ -0,0 +1,49 @@
/*
 * Author: Yanan Chen
 * Created Date: 02/14/2022
 * Purpose: Utility class for describe layouts
 * Test Class: NewAndEditASEActivityController
 * History:
 *      02/14/2022 - Yanan Chen - Initial Code.
 *
 * */
global class NewAndEditASEActivityController extends NewAndEditBaseController
{
    // public String contactsInfo {set;get;}//key sfid;value awsid
    public String PIPL_Input_Account_Error_Msg{set;get;}
    public String contactId{set;get;}//For Lookup field
    public String contactAWS{set;get;}
    public String staticResourceContact {get; set;}
    public NewAndEditASEActivityController(ApexPages.StandardController controller) {
        List<String> fieldList = new List<String>(Schema.getGlobalDescribe().get('ASEActivity__c').getDescribe().fields.getMap().keyset());
        // Add fields to controller. This is to avoid the SOQL error in visualforce page
        controller.addFields(fieldList);
        LookUpOverrideFields.add('ReporterASE__c');
        Init(controller.getRecord());
        //添加项
        PIPL_Input_Account_Error_Msg = label.PIPL_Input_Account_Error_Msg;
        SObject obj = controller.getRecord();
        if(obj.Id == null){
            //初始化加载值
            obj.put('OwnerId',UserInfo.getUserId());
        }
        //获取contact 加密ID
        // contactsInfo = LookUpOverrideFieldsMapJson;
        //contact信息(搜索查询query url用)
        ASEActivity__c aseActivity = [Select Id, ReporterASE__c From ASEActivity__c Where Id = : obj.Id];
        if(aseActivity.ReporterASE__c != null){
            Contact contact = [Select Id, AWS_Data_Id__c From Contact Where Id = : aseActivity.ReporterASE__c];
            System.debug('contact : ' + contact );
            contactAWS = contact.AWS_Data_Id__c;
            System.debug('contactAWS : ' + contactAWS );
        }
        staticResourceContact = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));
    }
    @RemoteAction
    global static Response saveASEActivity(String leadJson,String transId,Boolean isNew) {
        return save(new ASEActivity__c(),leadJson,transId,isNew);
    }
}
force-app/main/default/classes/NewAndEditASEActivityController.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/NewAndEditAddressController.cls
@@ -1,13 +1,13 @@
/*
 * Author: Bubba Li
 * Author: Yanan Chen
 * Created Date: 02/08/2022
 * Purpose: Utility class for describe layouts
 * Test Class: NewAndEditAddressController
 * History: 
 *      02/08/2022 - Bubba Li - Initial Code.
 *      02/08/2022 - Yanan Chen - Initial Code.
 * 
 * */
public without sharing class NewAndEditAddressController {
global without sharing class NewAndEditAddressController {
    public List <LayoutDescriberHelper.LayoutSection > layoutSections{set;get;}
    public String awsToken{set;get;}
    public static Map<String, Schema.SObjectType> schemaMap = Schema.getGlobalDescribe();
@@ -15,50 +15,75 @@
    public Boolean isNewMode{set;get;}
    public String rtTypeId {get; set;}
    public String AWSDataId{set;get;}
    //fieldLabel fieldAPI
    public String fieldApiListStr {get; set;}
    public String contactId{set;get;}//For Lookup field
    public List<String> encryptedAPIList{set;get;}
    public String staticResource {get; set;}
    public String staticResourceContact {get; set;}
    public String requiredFieldAPIListStr {get; set;}
    public String fieldAPIToLabelMapStr {get; set;}
    public String Input_Required_Field_Msg{set;get;}
    public String PIPL_Name_Label{set;get;}
    public String PIPL_Input_Account_Error_Msg{set;get;}
    public String sobjectPrefix{set;get;}
    public String sobjecttypeForFrontEnd{set;get;}
    public String contactsInfo {set;get;}//key sfid;value awsid
    public NewAndEditAddressController(ApexPages.StandardController controller) {
        isNewMode = true;
        Input_Required_Field_Msg = Label.Input_Required_Field_Msg;
        PIPL_Name_Label = Label.PIPL_Name_Label;
        PIPL_Input_Account_Error_Msg = label.PIPL_Input_Account_Error_Msg;
        sobjecttypeForFrontEnd = sobjectTypeValue;
        //获取所有字段
        List<String> fieldList = new List<String>(Schema.getGlobalDescribe().get('Address__c').getDescribe().fields.getMap().keyset());  
        // Add fields to controller. This is to avoid the SOQL error in visualforce page
        controller.addFields(fieldList);
        SObject obj = controller.getRecord();
        rtTypeId = ApexPages.currentPage().getParameters().get('RecordType');
        rtTypeId = '0121m000000kiMxAAI';//For testing
        layoutSections = LayoutDescriberHelper.describeSectionWithFields(rtTypeId, 'Address__c','classic');
        SObject obj = controller.getRecord();
        if(obj.Id != null){
            //更新
            isNewMode = false;
            Address__c addressData = [select Id, RecordTypeId, AWS_Data_Id__c from Address__c where id =: obj.Id];
            Address__c addressData = [select Id, RecordTypeId, AWS_Data_Id__c, Contacts__r.Id, Contacts__r.AWS_Data_Id__c from Address__c where id =: obj.Id];
            rtTypeId = addressData.RecordTypeId;
            AWSDataId = addressData.AWS_Data_Id__c;
            Map<String,String> sfIdToAWSIdMap = new Map<String,String>();
            // if(addressData.Contacts__r.Id != null){
            //     sfIdToAWSIdMap.put(String.valueof(addressData.Contacts__r.Id).subString(0,15),addressData.Contacts__r.AWS_Data_Id__c);
            // }
            sfIdToAWSIdMap.put(String.valueof(addressData.Contacts__r.Id).subString(0,15),addressData.Contacts__r.AWS_Data_Id__c);
            contactsInfo = JSON.serialize(sfIdToAWSIdMap);
        }else{
            //新建
            rtTypeId = ApexPages.currentPage().getParameters().get('RecordType');
        }
        List<String> fieldApiList = new List<String>();
        for (LayoutDescriberHelper.LayoutSection ls : layoutSections) {
            for (LayoutDescriberHelper.LayoutField lf : ls.layoutFields) {
                if (lf.fieldAPI != '') {
                    fieldApiList.add(lf.fieldAPI);
                }
            }
        }
        fieldApiListStr = JSON.serialize(fieldApiList);
        awsToken = AWSServiceTool.getAWSToken();
        LayoutDescriberHelper.LayoutWrapper LayoutWrapperValue = LayoutDescriberHelper.describeSectionWithFieldsWrapper(rtTypeId, 'Address__c','classic');
        layoutSections = LayoutWrapperValue.layoutSections;
        List<String> requiredFieldAPIList = LayoutWrapperValue.requiredFieldAPIList;
        Map<String,String> fieldAPIToLabelMap = LayoutWrapperValue.fieldAPIToLabelMap;
        requiredFieldAPIListStr = JSON.serialize(requiredFieldAPIList);
        fieldAPIToLabelMapStr = JSON.serialize(fieldAPIToLabelMap);
        PIHelper.PIIntegration piIntegration = PIHelper.getPIIntegrationInfo('Address__c');
        staticResource = JSON.serialize(piIntegration);
        staticResourceContact = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));
        encryptedAPIList = piIntegration.PIFields;
        sobjectPrefix = piIntegration.sobjectPrefix;
    }
    public class Response{
    global class Response{
        public String recordId{set;get;}
        public String message{set;get;}
        public String status{set;get;}
    }
    @RemoteAction
    public static Response saveAddress(String addressJson,String transId,Boolean isNew) {
    global static Response saveAddress(String addressJson,String transId,Boolean isNew) {
        System.debug('Address Info:' + JSON.serialize(addressJson));
        //1. Prepare the payload for  Address
        Schema.SObjectType addressSchema = schemaMap.get(sobjectTypeValue);
        Map<String, Schema.SObjectField> fieldAPIToTypeMap = addressSchema.getDescribe().fields.getMap();
        Map<String,Object> fieldValueMap = (Map<String,Object>)JSON.deserializeUntyped(addressJson);
        Address__c addressInfo = new Address__c();
        //自定义格式转换
        for (String fieldAPI: fieldValueMap.keySet()) {
            system.debug('field API'+fieldAPI);
            Schema.DisplayType fielddataType = fieldAPIToTypeMap.get(fieldAPI).getDescribe().getType();  
            String fieldValue = String.valueOf(fieldValueMap.get(fieldAPI)); 
            if(String.isBlank(fieldValue)){
@@ -75,44 +100,45 @@
            }else if(String.valueOf(fielddataType)=='Number'||String.valueOf(fielddataType)=='DOUBLE' ){
                addressInfo.put(fieldAPI, Decimal.valueOf(String.valueOf(fieldValueMap.get(fieldAPI))));
            } else if(String.valueof(fielddataType)=='BOOLEAN'){
                addressInfo.put(fieldAPI, Boolean.valueOf(fieldValueMap.get(fieldAPI)));
                addressInfo.put(fieldAPI, fieldValueMap.get(fieldAPI));
            }else {
                addressInfo.put(fieldAPI, String.valueOf(fieldValueMap.get(fieldAPI)));
            }                  
        }
        //2. Save Record Process
        String status = 'success';    
        Response resp = new Response();
        Savepoint sp = Database.setSavepoint();
        String rid = '';
        try{
            System.debug('abcde');
            if(isNew){
                System.debug('addressInfoNancy = ' + addressInfo);
                insert addressInfo;
            }else{
                //Id addressIdValue = [select id from Address where AWS_Data_Id__c =:awsId];
                addressInfo.put('Id','a4R1m000000KGxSEAW');//For testing;
                System.debug('into update');
                String awsDataId = (String)addressInfo.get('AWS_Data_Id__c');
                System.debug('awsDataId = ' + awsDataId);
                Address__c[] addresses = [select id from Address__c where AWS_Data_Id__c =:awsDataId];
                System.debug('addresses[0].id = ' + addresses[0].id);
                addressInfo.put('Id',addresses[0].id);//For testing;
                update addressInfo;
            }
            // //saveTransLog(transId, addressInfo.AWS_Data_Id__c, status, '');
            // Transaction_Log__c traLog = new Transaction_Log__c();
            // // AWS_Data_Id__c=AWSDataId,TransId__c=transId,JsonContent__c=addressJson,Status__c=status
            // traLog.AWS_Data_Id__c = AWSDataId;
            // traLog.TransId__c = transId;
            // traLog.JsonContent__c = addressJson;
            // traLog.Status__c = status;
            // insert traLog;
            rid=addressInfo.Id;
            PIHelper.saveTransLog(sobjectTypeValue,(String)addressInfo.get('AWS_Data_Id__c'),rid,transId,addressJson ,status,'');
            resp.recordId = addressInfo.Id;
            // resp.message = 'success saveAddress';
            resp.message = '';
            resp.status = status;
            System.debug('resp from sfdx back-end' + resp);
            return resp;
        } catch(Exception e) {
            System.debug('into catch'+e.getMessage());
            Database.rollback(sp);
            // status = 'fail';
            // //saveTransLog(transId, addressInfo.AWS_Data_Id__c, status, '');
            // system.System.debug(e.getMessage() + '-' + e.getStackTraceString() + '-' + e.getLineNumber());
            // resp.message = e.getMessage();
            // resp.recordId = 'fail saveAddress';
            status = 'fail';
            PIHelper.saveTransLog(sobjectTypeValue,(String)addressInfo.get('AWS_Data_Id__c'),rid,transId,addressJson,status,e.getMessage());
            resp.message = e.getMessage();
            resp.status = status;
            return resp;
        }
force-app/main/default/classes/NewAndEditAgencyContactController.cls
New file
@@ -0,0 +1,20 @@
global without sharing class NewAndEditAgencyContactController extends NewAndEditBaseController
{
    public string staticResourceContact{get;private set;}
    global NewAndEditAgencyContactController(ApexPages.StandardController controller) {
        List<String> fieldList = new List<String>(Schema.getGlobalDescribe().get('Agency_Contact__c').getDescribe().fields.getMap().keyset());
        // Add fields to controller. This is to avoid the SOQL error in visualforce page
        controller.addFields(fieldList);
        LookUpOverrideFields.add('Contact__c');
        Init(controller.getRecord());
        PIHelper.PIIntegration piIntegration = PIHelper.getPIIntegrationInfo('Contact');
        staticResourceContact = JSON.serialize(piIntegration);
    }
    @RemoteAction
    global static Response saveContact(String leadJson,String transId,Boolean isNew) {
        return save(new Agency_Contact__c(),leadJson,transId,isNew);
    }
}
force-app/main/default/classes/NewAndEditAgencyContactController.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>52.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/NewAndEditBaseController.cls
New file
@@ -0,0 +1,260 @@
global abstract class NewAndEditBaseController {
    public List <LayoutDescriberHelper.LayoutSection > layoutSections{set;get;}
    public String awsToken{set;get;}
    public static Map<String, Schema.SObjectType> schemaMap = Schema.getGlobalDescribe();
    public String sobjectTypeValue {private set; get;}
    public Boolean isNewMode{set;get;}
    public String rtTypeId {get; set;}
    public String AWSDataId{set;get;}
    // 当前对象所有的加密字段集合
    public List<String> encryptedAPIList{private set;get;}
    // 当前页面中的加密字段集合
    public List<String> layoutEncryptedAPIList{private set;get;}
    //fieldLabel fieldAPI
    public String requiredFieldAPIListStr {get;private set;}
    public String fieldApiListStr {get;private set;}
    public String fieldAPIToLabelMapStr {get;private set;}
    public String staticResource {get; set;}
    public string SobjectName{get{return sobjectTypeValue;}}
    public string SobjectLabel{get;private set;}
    public Map<string,string> AWSToSobjectMap{
        get{
            Map<string,string> temp = new Map<string,string>();
            temp.putAll(AWSToSobjectNonEncryptedMap);
            temp.putAll(AWSToSobjectEncryptedMap);
            return temp;
        }
    }
    public string AWSToSobjectMapJson{get{return JSON.serialize(AWSToSobjectMap);}}
    public Map<string,string> AWSToSobjectNonEncryptedMap{get;private set;}
    public string AWSToSobjectNonEncryptedMapJson{get{return JSON.serialize(AWSToSobjectNonEncryptedMap);}}
    public string AWSToSobjectNonEncryptedMapKeySet{get{return JSON.serialize(new List<string>(AWSToSobjectNonEncryptedMap.keySet()));}}
    public Map<string,string> AWSToSobjectEncryptedMap{get;private set;}
    public string AWSToSobjectEncryptedMapJson{get{return JSON.serialize(AWSToSobjectMap);}}
    public final string ApiPrefix{get;private set;}
    public String sobjectPrefix{get;private set;}
    public String SaveAndNewButtonUrl{get;private set;}
    public List<String> VLookUpFields{get;private set;}
    public String VLookUpFieldsJson{get{return Json.serialize(VLookUpFields);}}
    public List<String> LookUpOverrideFields{get;private set;}
    public string LookUpOverrideFieldsMapJson{get;private set;}
    public NewAndEditBaseController(){
        ApiPrefix = 'PIBackApi';
        AWSToSobjectNonEncryptedMap = new Map<string,string>();
        AWSToSobjectEncryptedMap = new Map<string,string>();
        VLookUpFields = new List<String>();
        layoutEncryptedAPIList = new List<String>();
        LookUpOverrideFields = new List<String>();
    }
    protected virtual void Init(SObject obj){
        sobjectTypeValue = obj.getSObjectType().getDescribe().getName();
        SobjectLabel = obj.getSObjectType().getDescribe().getLabel();
        system.debug('obj='+sobjectTypeValue);
        isNewMode = true;
        List<Sobject> lso = Database.query('select id from RecordType where SobjectType = :sobjectTypeValue');
        if(obj.Id != null){
            isNewMode = false;
            string sql = 'select Id';
            if (lso.size()>0) {
                sql += ',RecordTypeId';
            }
            sql += GenerateReferenceSql()+',AWS_Data_Id__c from '+sobjectTypeValue+' where id =\''+obj.Id+'\' ';
            System.debug('sql='+sql);
            Sobject leadData = Database.query(sql);
            if (lso.size()>0){
                rtTypeId = (String)leadData.get('RecordTypeId');
            }
            AWSDataId = (String)leadData.get('AWS_Data_Id__c');
            Map<String,String> sfIdToAWSIdMap = new Map<String,String>();
            for (string f : LookUpOverrideFields) {
                object o = leadData.get(f);
                System.debug('leadData.get('+f+')='+o);
                if (!String.isBlank(String.valueOf(o))) {
                    sfIdToAWSIdMap.put(String.valueOf(o).subString(0,15), String.valueOf(leadData.getSobject(GetReferenceField(f)).get('AWS_Data_Id__c')));
                }
            }
            LookUpOverrideFieldsMapJson = JSON.serialize(sfIdToAWSIdMap);
        }else{
            rtTypeId = ApexPages.currentPage().getParameters().get('RecordType');
        }
        PIHelper.PIIntegration piIntegration = PIHelper.getPIIntegrationInfo(sobjectTypeValue);
        layoutEncryptedAPIList = piIntegration.PIFields;
        encryptedAPIList = piIntegration.PIFields;
        staticResource = JSON.serialize(piIntegration);
        sobjectPrefix = piIntegration.sobjectPrefix;
        SaveAndNewButtonUrl = string.format('/{0}/e', new string[]{sobjectPrefix});
        if (lso.size() > 1) {
            SaveAndNewButtonUrl = String.format('/setup/ui/recordtypeselect.jsp?ent={0}&retURL=/{1}/o&save_new_url=/{1}/e?retURL=%2F{1}%2Fo', new String[]{sobjectTypeValue,sobjectPrefix});
        }
        for (PI_Field_Policy_Detail__c PIDetail : piIntegration.PIDetails) {
            AWSToSobjectNonEncryptedMap.put(PIDetail.AWS_Field_API__c, PIDetail.SF_Field_API_Name__c);
            AWSToSobjectEncryptedMap.put(PIDetail.AWS_Encrypted_Field_API__c, PIDetail.SF_Field_Encrypted_API__c);
        }
        System.debug(new List<string>(AWSToSobjectNonEncryptedMap.keySet()));
        system.debug('AWSToSobjectNonEncryptedMapJson=');
        system.debug(AWSToSobjectNonEncryptedMapJson);
        try{
            LayoutDescriberHelper.LayoutWrapper LayoutWrapperValue = LayoutDescriberHelper.describeSectionWithFieldsWrapper(rtTypeId, sobjectTypeValue,'classic');
            layoutSections = LayoutWrapperValue.layoutSections;
            List<String> requiredFieldAPIList = LayoutWrapperValue.requiredFieldAPIList;
            Map<String,String> fieldAPIToLabelMap = LayoutWrapperValue.fieldAPIToLabelMap;
            List<String> fieldApiList = new List<String>();
            for (LayoutDescriberHelper.LayoutSection ls : layoutSections) {
                for (LayoutDescriberHelper.LayoutField lf : ls.layoutFields) {
                    if (lf.fieldAPI != '') {
                        System.debug('lf.fieldAPI='+lf.fieldAPI+' fieldType='+lf.fieldType);
                        fieldApiList.add(lf.fieldAPI);
                        if (lf.fieldType == 'reference') {
                            VLookUpFields.add(lf.fieldAPI);
                        }
                        //在view解密section中只需显示当前layout中的加密字段
                        // if (encryptedAPIList.contains(lf.fieldAPI)) {
                        //     layoutEncryptedAPIList.add(lf.fieldAPI);
                        // }
                    }
                }
            }
            fieldApiListStr = JSON.serialize(fieldApiList);
            fieldAPIToLabelMapStr = JSON.serialize(fieldAPIToLabelMap);
            requiredFieldAPIListStr = JSON.serialize(requiredFieldAPIList);
            //awsToken = AWSServiceTool.getAWSToken();
        }catch(Exception e){
            system.debug('Exception from get layout service:'+e.getmessage());
        }
    }
    public static string GetReferenceField(string f){
        if (f.endsWith('__c')) {
            return f.substring(0,f.length()-1)+'r';
        }
        else if(f.endsWith('Id') || f.endsWith('id') || f.endsWith('ID')) {
            return f.substring(0, f.length()-2);
        }
        else{
            return f;
        }
    }
    public string GenerateReferenceSql(){
        string res ='';
        for (string f : LookUpOverrideFields) {
            res += ','+f+','+GetReferenceField(f)+'.AWS_Data_Id__c';
        }
        return res;
    }
    global class Response{
        public String recordId{set;get;}
        public String message{set;get;}
        public String status{set;get;}
    }
    @RemoteAction
    global static Response save(Sobject sobj, String leadJson,String transId,Boolean isNew) {
        string sobjectTypeValue = sobj.getSObjectType().getDescribe().getName();
        System.debug('sobjectTypeValue:'+sobjectTypeValue+' Info:' + JSON.serialize(leadJson));
        System.debug('json length='+leadJson.length());
        //1. Prepare the payload for  Lead
        Schema.SObjectType leadSchema = schemaMap.get(sobjectTypeValue);
        Map<String, Schema.SObjectField> fieldAPIToTypeMap = leadSchema.getDescribe().fields.getMap();
        Map<String,Object> fieldValueMap = (Map<String,Object>)JSON.deserializeUntyped(leadJson);
        Sobject leadInfo = sobj;
        for (String fieldAPI: fieldValueMap.keySet()) {
            system.debug('field API='+fieldAPI);
            Schema.DisplayType fielddataType = fieldAPIToTypeMap.get(fieldAPI).getDescribe().getType();
            String fieldValue = String.valueOf(fieldValueMap.get(fieldAPI));
            system.debug('Field Type:'+fielddataType+' field Value='+fieldValue);
            if(String.valueOf(fielddataType)=='DATE'){
                leadInfo.put(fieldAPI,(String.isBlank(fieldValue)||String.isEmpty(fieldValue))? null:Date.valueOf(fieldValue.replace('/', '-')));
            }else if(String.valueOf(fielddataType)=='DATETIME'){
                if(String.isNotBlank(fieldValue)&&fieldValue.contains('T')){
                    fieldValue = fieldValue.replace('T',' ');
                    leadInfo.put(fieldAPI, Datetime.valueOfGmt(fieldValue));
                }else{
                    leadInfo.put(fieldAPI, null);
                }
            }else if(String.valueof(fielddataType)=='CURRENCY'|| String.valueof(fielddataType)=='PERCENT'||String.valueOf(fielddataType)=='Number'||String.valueOf(fielddataType)=='DOUBLE' ){
                leadInfo.put(fieldAPI, (String.isBlank(fieldValue)||String.isEmpty(fieldValue))?0:Decimal.valueOf(fieldValue));
            } else if(String.valueof(fielddataType)=='BOOLEAN'){
                leadInfo.put(fieldAPI, fieldValueMap.get(fieldAPI));
            }else {
                leadInfo.put(fieldAPI,fieldValue);
            }
        }
        system.debug('for (String fieldAPI: fieldValueMap.keySet()) end');
        //2. Save Record Process
        String status = 'success';
        Response resp = new Response();
        String awsDataId = '';
        Savepoint sp = Database.setSavepoint();
        try{
            System.debug('abcde');
            if(isNew){
                System.debug('leadInfozhj = ' + leadInfo);
                insert leadInfo;
            }else{
                System.debug('into update');
                awsDataId = (String)leadInfo.get('AWS_Data_Id__c');
                if (string.isBlank(awsDataId)) {
                    throw new DMLException('更新时AWS_Data_Id__c不能为空');
                }
                System.debug('awsDataId = ' + awsDataId);
                Sobject[] leads = Database.query('select id from '+sobjectTypeValue+' where AWS_Data_Id__c =:awsDataId');
                System.debug('leads[0].id = ' + leads[0].id);
                leadInfo.put('Id',leads[0].id);//For testing;
                update leadInfo;
            }
            // //saveTransLog(transId, leadInfo.AWS_Data_Id__c, status, '');
            // Transaction_Log__c traLog = new Transaction_Log__c();
            // // AWS_Data_Id__c=AWSDataId,TransId__c=transId,JsonContent__c=leadJson,Status__c=status
            // traLog.AWS_Data_Id__c = AWSDataId;
            // traLog.TransId__c = transId;
            // traLog.JsonContent__c = leadJson;
            // traLog.Status__c = status;
            // insert traLog;
            resp.recordId = leadInfo.Id;
            // resp.message = 'success saveLead';
            resp.status = status;
            PIHelper.saveTransLog(sobjectTypeValue,awsDataId,leadInfo.Id,transId, leadJson ,status,'');
            // (String module,String awsDataId,String sfId, String transId,String content,String status,String respMsg)
            System.debug('respzhj = ' + resp);
            return resp;
        } catch(Exception e) {
            System.debug('into catch'+e.getMessage());
            Database.rollback(sp);
            resp.status = 'Exception';
            resp.message = e.getMessage()+e.getStackTraceString();
            PIHelper.saveTransLog(sobjectTypeValue,awsDataId,leadInfo.Id,transId, leadJson ,status,resp.message);
            // PIHelper.saveTransLog(sobjectTypeValue,(String)leadInfo.get('AWS_Data_Id__c'),transId, leadJson,status,e.getStackTraceString());
            return resp;
        }
    }
}
force-app/main/default/classes/NewAndEditBaseController.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>53.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/NewAndEditCampaignMemberController.cls
New file
@@ -0,0 +1,18 @@
global class NewAndEditCampaignMemberController extends NewAndEditBaseController
{
    public String staticResourceContact {get; set;}
    public NewAndEditCampaignMemberController(ApexPages.StandardController controller) {
        List<String> fieldList = new List<String>(Schema.getGlobalDescribe().get('CampaignMember').getDescribe().fields.getMap().keyset());
        // Add fields to controller. This is to avoid the SOQL error in visualforce page
        //controller.addFields(fieldList);
        //Init(controller.getRecord());
        staticResourceContact = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));
    }
    @RemoteAction
    global static Response saveCampaignMember(String leadJson,String transId,Boolean isNew) {
        return save(new CampaignMember(),leadJson,transId,isNew);
    }
}
force-app/main/default/classes/NewAndEditCampaignMemberController.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>52.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/NewAndEditCaseController.cls
New file
@@ -0,0 +1,146 @@
/*
 * Author: Mingjie Yin
 * Created Date: 02/07/2022
 * Purpose: Utility class for describe layouts
 * Test Class: NewAndEditCaseController
 * History:
 *      02/07/2022 - Mingjie Yin - Initial Code.
 *
 * */
global without sharing class NewAndEditCaseController {
    public List <LayoutDescriberHelper.LayoutSection > layoutSections{set;get;}
    public String awsToken{set;get;}
    public static Map<String, Schema.SObjectType> schemaMap = Schema.getGlobalDescribe();
    public static String sobjectTypeValue = 'Case';
    public Boolean isNewMode{set;get;}
    public String rtTypeId {get; set;}
    public String AWSDataId{set;get;}
    public String contactId{set;get;}//For Lookup field
    public List<String> encryptedAPIList{set;get;}
    public String staticResource {get; set;}
    public String staticResourceContact {get; set;}
    public String requiredFieldAPIListStr {get; set;}
    public String fieldAPIToLabelMapStr {get; set;}
    public String Input_Required_Field_Msg{set;get;}
    public String PIPL_Name_Label{set;get;}
    public String PIPL_Input_Account_Error_Msg{set;get;}
    public String sobjectPrefix{set;get;}
    public String sobjecttypeForFrontEnd{set;get;}
    public String contactsInfo {set;get;}//key sfid;value awsid
    public NewAndEditCaseController(ApexPages.StandardController controller) {
        isNewMode = true;
        Input_Required_Field_Msg = Label.Input_Required_Field_Msg;
        PIPL_Name_Label = Label.PIPL_Name_Label;
        PIPL_Input_Account_Error_Msg = label.PIPL_Input_Account_Error_Msg;
        sobjecttypeForFrontEnd = sobjectTypeValue;
        //获取所有字段
        List<String> fieldList = new List<String>(Schema.getGlobalDescribe().get('Case').getDescribe().fields.getMap().keyset());
        // Add fields to controller. This is to avoid the SOQL error in visualforce page
        controller.addFields(fieldList);
        SObject obj = controller.getRecord();
        if(obj.Id != null){
            //更新
            isNewMode = false;
            Case caseData = [select Id,RecordTypeId,AWS_Data_Id__c,ContactId,Contact.AWS_Data_Id__c from Case where id =: obj.Id];
            rtTypeId = caseData.RecordTypeId;
            AWSDataId = caseData.AWS_Data_Id__c;
            System.debug('AWSDataId=' + AWSDataId);
            Map<String,String> sfIdToAWSIdMap = new Map<String,String>();
            if(caseData.ContactId != null){
                sfIdToAWSIdMap.put(String.valueof(caseData.ContactId).subString(0,15),caseData.Contact.AWS_Data_Id__c);
            }
            // sfIdToAWSIdMap.put(String.valueof(caseData.ContactId).subString(0,15),caseData.Contact.AWS_Data_Id__c);
            contactsInfo = JSON.serialize(sfIdToAWSIdMap);
        }else{
            //新建
            rtTypeId = ApexPages.currentPage().getParameters().get('RecordType');
            obj.put('OwnerId',UserInfo.getUserId());
        }
        LayoutDescriberHelper.LayoutWrapper LayoutWrapperValue = LayoutDescriberHelper.describeSectionWithFieldsWrapper(rtTypeId, 'Case','classic');
        layoutSections = LayoutWrapperValue.layoutSections;
        List<String> requiredFieldAPIList = LayoutWrapperValue.requiredFieldAPIList;
        Map<String,String> fieldAPIToLabelMap = LayoutWrapperValue.fieldAPIToLabelMap;
        requiredFieldAPIListStr = JSON.serialize(requiredFieldAPIList);
        fieldAPIToLabelMapStr = JSON.serialize(fieldAPIToLabelMap);
        PIHelper.PIIntegration piIntegration = PIHelper.getPIIntegrationInfo('Case');
        staticResource = JSON.serialize(piIntegration);
        staticResourceContact = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));
        encryptedAPIList = piIntegration.PIFields;
        sobjectPrefix = piIntegration.sobjectPrefix;
    }
    global class Response{
        public String recordId{set;get;}
        public String message{set;get;}
        public String status{set;get;}
    }
    @RemoteAction
    global static Response saveCase(String caseJson,String transId,Boolean isNew) {
        System.debug('Case Info:' + JSON.serialize(caseJson));
        //1. Prepare the payload for  Case
        Schema.SObjectType caseSchema = schemaMap.get(sobjectTypeValue);
        Map<String, Schema.SObjectField> fieldAPIToTypeMap = caseSchema.getDescribe().fields.getMap();
        Map<String,Object> fieldValueMap = (Map<String,Object>)JSON.deserializeUntyped(caseJson);
        Case caseInfo = new Case();
        //自定义格式转换
        for (String fieldAPI: fieldValueMap.keySet()) {
            system.debug('field API'+fieldAPI);
            Schema.DisplayType fielddataType = fieldAPIToTypeMap.get(fieldAPI).getDescribe().getType();
            String fieldValue = String.valueOf(fieldValueMap.get(fieldAPI));
            if(String.isBlank(fieldValue)){
                continue;
            }
            if(String.valueOf(fielddataType)=='DATE'){
                caseInfo.put(fieldAPI, Date.valueOf(String.valueOf(fieldValueMap.get(fieldAPI)).replace('/', '-')));
            }else if(String.valueOf(fielddataType)=='DATETIME'){
                String dt = String.valueOf(fieldValueMap.get(fieldAPI));
                if(String.isNotBlank(dt)&&dt.contains('T')){
                    dt = dt.replace('T',' ');
                    caseInfo.put(fieldAPI, Datetime.valueOfGmt(dt));
                }
            }else if(String.valueOf(fielddataType)=='Number'||String.valueOf(fielddataType)=='DOUBLE' ){
                caseInfo.put(fieldAPI, Decimal.valueOf(String.valueOf(fieldValueMap.get(fieldAPI))));
            } else if(String.valueof(fielddataType)=='BOOLEAN'){
                caseInfo.put(fieldAPI, fieldValueMap.get(fieldAPI));
            }else {
                caseInfo.put(fieldAPI, String.valueOf(fieldValueMap.get(fieldAPI)));
            }
        }
        //2. Save Record Process
        String status = 'success';
        Response resp = new Response();
        Savepoint sp = Database.setSavepoint();
        String rid = '';
        try{
            System.debug('abcde');
            if(isNew){
                System.debug('caseInfozhj = ' + caseInfo);
                insert caseInfo;
            }else{
                System.debug('into update');
                String awsDataId = (String)caseInfo.get('AWS_Data_Id__c');
                System.debug('awsDataId = ' + awsDataId);
                Case[] cases = [select id from Case where AWS_Data_Id__c =:awsDataId];
                System.debug('Cases[0].id = ' + cases[0].id);
                caseInfo.put('Id',cases[0].id);//For testing;
                update caseInfo;
            }
            rid=caseInfo.Id;
            PIHelper.saveTransLog(sobjectTypeValue,(String)caseInfo.get('AWS_Data_Id__c'),rid,transId,caseJson ,status,'');
            resp.recordId = caseInfo.Id;
            resp.message = '';
            resp.status = status;
            System.debug('resp from sfdx back-end' + resp);
            return resp;
        } catch(Exception e) {
            System.debug('into catch'+e.getMessage());
            Database.rollback(sp);
            status = 'fail';
            PIHelper.saveTransLog(sobjectTypeValue,(String)caseInfo.get('AWS_Data_Id__c'),rid,transId,caseJson,status,e.getMessage());
            resp.message = e.getMessage();
            resp.status = status;
            return resp;
        }
    }
}
force-app/main/default/classes/NewAndEditCaseController.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>52.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/NewAndEditContactController.cls
New file
@@ -0,0 +1,52 @@
global class NewAndEditContactController extends NewAndEditBaseController
{
    public String unifiedIContactID{set;get;}
    public NewAndEditContactController(ApexPages.StandardController controller) {
        List<String> fieldList = new List<String>(Schema.getGlobalDescribe().get('Contact').getDescribe().fields.getMap().keyset());
        // Add fields to controller. This is to avoid the SOQL error in visualforce page
        controller.addFields(fieldList);
        Init(controller.getRecord());
        String contactId = controller.getRecord().Id;
        if(contactId != null){
            Contact c = [select UnifiedI_Contact_ID__c from Contact where Id =:contactId ];
            system.debug('Contact c = '+c);
            unifiedIContactID = c.UnifiedI_Contact_ID__c;
        }
        // AWSToSobjectNonEncryptedMap.put('lastName', 'LastName');
        // AWSToSobjectNonEncryptedMap.put('phone', 'Phone');
        // AWSToSobjectNonEncryptedMap.put('email', 'Email');
        // AWSToSobjectNonEncryptedMap.put('medicalStaffFullName', 'MedicalStaff_Full_name__c');
        // AWSToSobjectNonEncryptedMap.put('mobilePhone', 'MobilePhone');
        // AWSToSobjectNonEncryptedMap.put('title', 'Title');
        // AWSToSobjectNonEncryptedMap.put('olyAssistantType', 'OLY_Assistant_Type__c');
        // AWSToSobjectNonEncryptedMap.put('jobCategoryPicklist', 'Job_Category_picklist__c');
        // AWSToSobjectNonEncryptedMap.put('type', 'Type__c');
        // AWSToSobjectNonEncryptedMap.put('contactAddress', 'Contact_address__c');
        // AWSToSobjectNonEncryptedMap.put('contactType', 'ContactType__c');
        // AWSToSobjectNonEncryptedMap.put('doctorDivision1', 'Doctor_Division1__c');
        // AWSToSobjectNonEncryptedMap.put('uniqueNumber', 'UniqueNumber__c');
        // AWSToSobjectEncryptedMap.put('lastNameEncrypt', 'LastName_Encrypted__c');
        // AWSToSobjectEncryptedMap.put('phoneEncrypt', 'Phone_Encrypted__c');
        // AWSToSobjectEncryptedMap.put('emailEncrypt', 'Email_Encrypted__c');
        // AWSToSobjectEncryptedMap.put('medicalStaffFullNameEncrypt', 'MedicalStaff_Full_name_Encrypted__c');
        // AWSToSobjectEncryptedMap.put('mobilePhoneEncrypt', 'MobilePhone_Encrypted__c');
        // AWSToSobjectEncryptedMap.put('titleEncrypt', 'Title_Encrypted__c');
        // AWSToSobjectEncryptedMap.put('olyAssistantTypeEncrypt', 'OLY_Assistant_Type_Encrypted__c');
        // AWSToSobjectEncryptedMap.put('jobCategoryPicklistEncrypt', 'Job_Category_picklist_Encrypted__c');
        // AWSToSobjectEncryptedMap.put('typeEncrypt', 'Type_Encrypted__c');
        // AWSToSobjectEncryptedMap.put('contactAddressEncrypt', 'Contact_address_Encrypted__c');
        // AWSToSobjectEncryptedMap.put('contactTypeEncrypt', 'ContactType_Encrypted__c');
        // AWSToSobjectEncryptedMap.put('doctorDivision1Encrypt', 'Doctor_Division1_Encrypted__c');
        // AWSToSobjectEncryptedMap.put('uniqueNumberEncrypt', 'UniqueNumber_Encrypted__c');
    }
    @RemoteAction
    global static Response saveContact(String leadJson,String transId,Boolean isNew) {
        return save(new Contact(),leadJson,transId,isNew);
    }
}
force-app/main/default/classes/NewAndEditContactController.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>53.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/NewAndEditEventController.cls
New file
@@ -0,0 +1,44 @@
/*
 * Author: Yanan Chen
 * Created Date: 02/15/2022
 * Purpose: Utility class for describe layouts
 * Test Class: NewAndEditEventController
 * History:
 *      02/15/2022 - Yanan Chen - Initial Code.
 *
 * */
global class NewAndEditEventController extends NewAndEditBaseController {
    public String contactAWSIds{set;get;}
    public String staticResources {get; set;}
    public NewAndEditEventController (ApexPages.StandardController controller) {
        List<String> fieldList = new List<String>(Schema.getGlobalDescribe().get('Event').getDescribe().fields.getMap().keyset());
        // Add fields to controller. This is to avoid the SOQL error in visualforce page
        controller.addFields(fieldList);
        Init(controller.getRecord());
        //1. get 访问对象ID
        //query event by controller.getRecord().Id;
        Event event = [SELECT  Id, Visitor1_ID__c, Visitor2_ID__c,  Visitor3_ID__c, Visitor4_ID__c, Visitor5_ID__c FROM Event WHERE Id =:controller.getRecord().Id];
        System.debug('event: ' + event);
        Set<String> contactIds = new Set<String>();
        List<String> conAWSIds = new List<String>();
        contactIds.add(event.Visitor1_ID__c);
        contactIds.add(event.Visitor2_ID__c);
        contactIds.add(event.Visitor3_ID__c);
        contactIds.add(event.Visitor4_ID__c);
        contactIds.add(event.Visitor5_ID__c);
        List<Contact> conListForReport = new List<Contact>([select id,AWS_Data_Id__c from Contact where id in:contactIds and AWS_Data_Id__c!='']);
        for(Contact con:conListForReport){
            conAWSIds.add(con.AWS_Data_Id__c);
        }
        contactAWSIds = JSON.serialize(conAWSIds);
        system.debug('Contact AWSIDs:'+contactAWSIds);
        staticResources = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));
    }
    // @RemoteAction
    // global static Response saveEvent(String leadJson,String transId,Boolean isNew) {
    //     return save(new Event(),leadJson,transId,isNew);
    // }
}
force-app/main/default/classes/NewAndEditEventController.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/NewAndEditInquiryFormController.cls
New file
@@ -0,0 +1,36 @@
global class NewAndEditInquiryFormController extends NewAndEditBaseController
{
    // public String contactsInfo {set;get;}//key sfid;value awsid
    // public String leadsInfo {set;get;}//key sfid;value awsid
    public String PIPL_Input_Account_Error_Msg{set;get;}
    public String contactId{set;get;}//For Lookup field
    public String leadId{set;get;}//For Lead Lookup
    public String staticResourceContact {get; set;}
    public String staticResourceLead {get; set;}
    public NewAndEditInquiryFormController(ApexPages.StandardController controller) {
        List<String> fieldList = new List<String>(Schema.getGlobalDescribe().get('Inquiry_form__c').getDescribe().fields.getMap().keyset());
        // Add fields to controller. This is to avoid the SOQL error in visualforce page
        controller.addFields(fieldList);
        // contact lookup
        LookUpOverrideFields.add('Contact_Name__c');
        LookUpOverrideFields.add('Lead_link__c');
        Init(controller.getRecord());
        //添加项
        PIPL_Input_Account_Error_Msg = label.PIPL_Input_Account_Error_Msg;
        SObject obj = controller.getRecord();
        if(obj.Id == null){
            //初始化加载值
            obj.put('OwnerId',UserInfo.getUserId());
        }
        //contact信息(搜索查询query url用)
        staticResourceContact = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));
        //Lead信息(搜索查询query url用)
        staticResourceLead = JSON.serialize(PIHelper.getPIIntegrationInfo('Lead'));
    }
    @RemoteAction
    global static Response saveInquiryForm(String leadJson,String transId,Boolean isNew) {
        return save(new Inquiry_form__c(),leadJson,transId,isNew);
    }
}
force-app/main/default/classes/NewAndEditInquiryFormController.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>52.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/NewAndEditInspectionReportController.cls
New file
@@ -0,0 +1,25 @@
global class NewAndEditInspectionReportController extends NewAndEditBaseController
{
    public NewAndEditInspectionReportController(ApexPages.StandardController controller) {
        List<String> fieldList = new List<String>(Schema.getGlobalDescribe().get('Inspection_Report__c').getDescribe().fields.getMap().keyset());
        // Add fields to controller. This is to avoid the SOQL error in visualforce page
        controller.addFields(fieldList);
        Init(controller.getRecord());
        //AWSToSobjectNonEncryptedMap.put('responsiblePersonHP', 'Responsible_Person__c');
        //AWSToSobjectNonEncryptedMap.put('technicianHP', 'Technician_HP__c');
        //AWSToSobjectNonEncryptedMap.put('callerPhone', 'phone__c');
        //AWSToSobjectEncryptedMap.put('responsiblePersonHPEncrypt', 'Responsible_Person_Encrypted__c');
        //AWSToSobjectEncryptedMap.put('technicianHPEncrypt', 'Technician_HP_Encrypted__c');
        //AWSToSobjectEncryptedMap.put('callerPhoneEncrypt', 'phone_Encrypted__c');
        //system.debug('layoutEncryptedAPIList');
    }
    @RemoteAction
    global static Response saveInspectionReport(String leadJson,String transId,Boolean isNew) {
        return save(new Inspection_Report__c(),leadJson,transId,isNew);
    }
}
force-app/main/default/classes/NewAndEditInspectionReportController.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>53.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/NewAndEditLeadController.cls
@@ -7,7 +7,7 @@
 *      01/19/2022 - Bubba Li - Initial Code.
 * 
 * */
public without sharing class NewAndEditLeadController {
global without sharing class NewAndEditLeadController {
    public List <LayoutDescriberHelper.LayoutSection > layoutSections{set;get;}
    public String awsToken{set;get;}
    public static Map<String, Schema.SObjectType> schemaMap = Schema.getGlobalDescribe();
@@ -15,69 +15,93 @@
    public Boolean isNewMode{set;get;}
    public String rtTypeId {get; set;}
    public String AWSDataId{set;get;}
    //fieldLabel fieldAPI
    public String fieldApiListStr {get; set;}
    public String contactId{set;get;}//For Lookup field
    public List<String> encryptedAPIList{set;get;}
    public String staticResource {get; set;}
    public String staticResourceContact {get; set;}
    public String requiredFieldAPIListStr {get; set;}
    public String fieldAPIToLabelMapStr {get; set;}
    public String Input_Required_Field_Msg{set;get;}
    public String PIPL_Name_Label{set;get;}
    public String PIPL_Input_Account_Error_Msg{set;get;}
    public String sobjectPrefix{set;get;}
    public String sobjecttypeForFrontEnd{set;get;}
    public String contactsInfo {set;get;}//key sfid;value awsid
    public NewAndEditLeadController(ApexPages.StandardController controller) {
        isNewMode = true;
        Input_Required_Field_Msg = Label.Input_Required_Field_Msg;
        PIPL_Name_Label = Label.PIPL_Name_Label;
        PIPL_Input_Account_Error_Msg = label.PIPL_Input_Account_Error_Msg;
        sobjecttypeForFrontEnd = sobjectTypeValue;
        //获取所有字段
        List<String> fieldList = new List<String>(Schema.getGlobalDescribe().get('Lead').getDescribe().fields.getMap().keyset());  
        // Add fields to controller. This is to avoid the SOQL error in visualforce page
        controller.addFields(fieldList);
        SObject obj = controller.getRecord();
        //rtTypeId = ApexPages.currentPage().getParameters().get('RecordType');
        rtTypeId = '01210000000QiRa';//For testing
        layoutSections = LayoutDescriberHelper.describeSectionWithFields(rtTypeId, 'Lead','classic');
        controller.addFields(fieldList);
        SObject obj = controller.getRecord();
        if(obj.Id != null){
            //更新
            isNewMode = false;
            Lead leadData = [select Id,RecordTypeId,AWS_Data_Id__c from Lead where id =: obj.Id];
            Lead leadData = [select Id,RecordTypeId,AWS_Data_Id__c,Contact_Name__r.Id,Contact_Name__r.AWS_Data_Id__c from Lead where id =: obj.Id];
            rtTypeId = leadData.RecordTypeId;
            AWSDataId = leadData.AWS_Data_Id__c;
        }
        List<String> fieldApiList = new List<String>();
        for (LayoutDescriberHelper.LayoutSection ls : layoutSections) {
            for (LayoutDescriberHelper.LayoutField lf : ls.layoutFields) {
                if (lf.fieldAPI != '') {
                    fieldApiList.add(lf.fieldAPI);
                }
            Map<String,String> sfIdToAWSIdMap = new Map<String,String>();
            if(leadData.Contact_Name__r.Id != null){
                sfIdToAWSIdMap.put(String.valueof(leadData.Contact_Name__r.Id).subString(0,15),leadData.Contact_Name__r.AWS_Data_Id__c);
            }
            contactsInfo = JSON.serialize(sfIdToAWSIdMap);
        }else{
            //新建
            rtTypeId = ApexPages.currentPage().getParameters().get('RecordType');
            obj.put('OwnerId',UserInfo.getUserId());
        }
        fieldApiListStr = JSON.serialize(fieldApiList);
        //awsToken = AWSServiceTool.getAWSToken();
        LayoutDescriberHelper.LayoutWrapper LayoutWrapperValue = LayoutDescriberHelper.describeSectionWithFieldsWrapper(rtTypeId, 'Lead','classic');
        layoutSections = LayoutWrapperValue.layoutSections;
        List<String> requiredFieldAPIList = LayoutWrapperValue.requiredFieldAPIList;
        Map<String,String> fieldAPIToLabelMap = LayoutWrapperValue.fieldAPIToLabelMap;
        requiredFieldAPIListStr = JSON.serialize(requiredFieldAPIList);
        fieldAPIToLabelMapStr = JSON.serialize(fieldAPIToLabelMap);
        PIHelper.PIIntegration piIntegration = PIHelper.getPIIntegrationInfo('Lead');
        staticResource = JSON.serialize(piIntegration);
        staticResourceContact = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));
        encryptedAPIList = piIntegration.PIFields;
        sobjectPrefix = piIntegration.sobjectPrefix;
    }
    public class Response{
    global class Response{
        public String recordId{set;get;}
        public String message{set;get;}
        public String status{set;get;}
    }
    @RemoteAction
    public static Response saveLead(String leadJson,String transId,Boolean isNew) {
    global static Response saveLead(String leadJson,String transId,Boolean isNew) {
        System.debug('Lead Info:' + JSON.serialize(leadJson));
        //1. Prepare the payload for  Lead
        Schema.SObjectType leadSchema = schemaMap.get(sobjectTypeValue);
        Map<String, Schema.SObjectField> fieldAPIToTypeMap = leadSchema.getDescribe().fields.getMap();
        Map<String,Object> fieldValueMap = (Map<String,Object>)JSON.deserializeUntyped(leadJson);
        Lead leadInfo = new Lead();
        //自定义格式转换
        for (String fieldAPI: fieldValueMap.keySet()) {
            system.debug('field API='+fieldAPI);
            Schema.DisplayType fielddataType = fieldAPIToTypeMap.get(fieldAPI).getDescribe().getType();  
            String fieldValue = String.valueOf(fieldValueMap.get(fieldAPI)); 
            if(String.isBlank(fieldValue)){
                continue;
            }
            system.debug('Field Type:'+fielddataType+' field Value='+fieldValue);
            if(String.valueOf(fielddataType)=='DATE'){
                leadInfo.put(fieldAPI, Date.valueOf(String.valueOf(fieldValueMap.get(fieldAPI)).replace('/', '-')));
                leadInfo.put(fieldAPI,(String.isBlank(fieldValue)||String.isEmpty(fieldValue))? null:Date.valueOf(fieldValue.replace('/', '-')));
            }else if(String.valueOf(fielddataType)=='DATETIME'){
                String dt = String.valueOf(fieldValueMap.get(fieldAPI));
                if(String.isNotBlank(dt)&&dt.contains('T')){
                    dt = dt.replace('T',' ');
                    leadInfo.put(fieldAPI, Datetime.valueOfGmt(dt));
                }
            }else if(String.valueOf(fielddataType)=='Number'||String.valueOf(fielddataType)=='DOUBLE' ){
                leadInfo.put(fieldAPI, Decimal.valueOf(String.valueOf(fieldValueMap.get(fieldAPI))));
                if(String.isNotBlank(fieldValue)&&fieldValue.contains('T')){
                    fieldValue = fieldValue.replace('T',' ');
                    leadInfo.put(fieldAPI, Datetime.valueOfGmt(fieldValue));
                }else{
                    leadInfo.put(fieldAPI, null);
                }
            }else if(String.valueof(fielddataType)=='CURRENCY'|| String.valueof(fielddataType)=='PERCENT'||String.valueOf(fielddataType)=='Number'||String.valueOf(fielddataType)=='DOUBLE' ){
                leadInfo.put(fieldAPI, (String.isBlank(fieldValue)||String.isEmpty(fieldValue))?0:Decimal.valueOf(fieldValue));
            } else if(String.valueof(fielddataType)=='BOOLEAN'){
                leadInfo.put(fieldAPI, Boolean.valueOf(fieldValueMap.get(fieldAPI)));
                leadInfo.put(fieldAPI, fieldValueMap.get(fieldAPI));
            }else {
                leadInfo.put(fieldAPI, String.valueOf(fieldValueMap.get(fieldAPI)));
                leadInfo.put(fieldAPI,fieldValue);
            }                  
        }
        
@@ -85,34 +109,35 @@
        String status = 'success';    
        Response resp = new Response();
        Savepoint sp = Database.setSavepoint();
        String rid = '';
        try{
            System.debug('abcde');
            if(isNew){
                System.debug('leadInfozhj = ' + leadInfo);
                insert leadInfo;
            }else{
                //Id leadIdValue = [select id from Lead where AWS_Data_Id__c =:awsId];
                leadInfo.put('Id','00Q1m000001lVY8');//For testing;
                System.debug('into update');
                String awsDataId = (String)leadInfo.get('AWS_Data_Id__c');
                System.debug('awsDataId = ' + awsDataId);
                Lead[] leads = [select id from Lead where AWS_Data_Id__c =:awsDataId];
                System.debug('leads[0].id = ' + leads[0].id);
                leadInfo.put('Id',leads[0].id);//For testing;
                update leadInfo;
            }
            // //saveTransLog(transId, leadInfo.AWS_Data_Id__c, status, '');
            // Transaction_Log__c traLog = new Transaction_Log__c();
            // // AWS_Data_Id__c=AWSDataId,TransId__c=transId,JsonContent__c=leadJson,Status__c=status
            // traLog.AWS_Data_Id__c = AWSDataId;
            // traLog.TransId__c = transId;
            // traLog.JsonContent__c = leadJson;
            // traLog.Status__c = status;
            // insert traLog;
            rid=leadInfo.Id;
            PIHelper.saveTransLog(sobjectTypeValue,(String)leadInfo.get('AWS_Data_Id__c'),rid,transId,leadJson ,status,'');
            resp.recordId = leadInfo.Id;
            // resp.message = 'success saveLead';
            resp.message = '';
            resp.status = status;
            System.debug('resp from sfdx back-end' + resp);
            return resp;
        } catch(Exception e) {
            System.debug('into catch'+e.getMessage());
            Database.rollback(sp);
            // status = 'fail';
            // //saveTransLog(transId, leadInfo.AWS_Data_Id__c, status, '');
            // system.System.debug(e.getMessage() + '-' + e.getStackTraceString() + '-' + e.getLineNumber());
            // resp.message = e.getMessage();
            // resp.recordId = 'fail saveLead';
            status = 'fail';
            PIHelper.saveTransLog(sobjectTypeValue,(String)leadInfo.get('AWS_Data_Id__c'),rid,transId,leadJson,status,e.getMessage());
            resp.message = e.getMessage();
            resp.status = status;
            return resp;
        }
force-app/main/default/classes/NewAndEditQISController.cls
New file
@@ -0,0 +1,12 @@
global with sharing class NewAndEditQISController extends NewAndEditBaseController{
    public NewAndEditQISController(ApexPages.StandardController controller) {
        List<String> fieldList = new List<String>(Schema.getGlobalDescribe().get('QIS_Report__c').getDescribe().fields.getMap().keyset());
        controller.addFields(fieldList);
        Init(controller.getRecord());
    }
    @RemoteAction
    global static Response saveQISReport(String leadJson,String transId,Boolean isNew) {
        return save(new QIS_Report__c(),leadJson,transId,isNew);
    }
}
force-app/main/default/classes/NewAndEditQISController.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>52.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/NewAndEditRepairSubOrderController.cls
New file
@@ -0,0 +1,40 @@
/*
 * Author: Yanan Chen
 * Created Date: 02/14/2022
 * Purpose: Utility class for describe layouts
 * Test Class: NewAndEditRepairSubOrderController
 * History:
 *      02/14/2022 - Yanan Chen - Initial Code.
 *
 * */
global class NewAndEditRepairSubOrderController extends NewAndEditBaseController
{
    public String contactsInfo {set;get;}//key sfid;value awsid
    public String PIPL_Input_Account_Error_Msg{set;get;}
    public String contactId{set;get;}//For Lookup field
    public String staticResourceContact {get; set;}
    public NewAndEditRepairSubOrderController(ApexPages.StandardController controller) {
        List<String> fieldList = new List<String>(Schema.getGlobalDescribe().get('RepairSubOrder__c').getDescribe().fields.getMap().keyset());
        // Add fields to controller. This is to avoid the SOQL error in visualforce page
        controller.addFields(fieldList);
        LookUpOverrideFields.add('Receiver__c');
        LookUpOverrideFields.add('Applicanter__c');
        //contactId = LookUpOverrideFieldsMapJson;
        Init(controller.getRecord());
        //添加项
        PIPL_Input_Account_Error_Msg = label.PIPL_Input_Account_Error_Msg;
        SObject obj = controller.getRecord();
        if(obj.Id == null){
            //初始化加载值
            obj.put('OwnerId',UserInfo.getUserId());
        }
        staticResourceContact = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));
    }
    @RemoteAction
    global static Response saveRepairSubOrder(String leadJson,String transId,Boolean isNew) {
        return save(new RepairSubOrder__c(),leadJson,transId,isNew);
    }
}
force-app/main/default/classes/NewAndEditRepairSubOrderController.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>52.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/NewAndEditReportController.cls
New file
@@ -0,0 +1,160 @@
global without sharing class NewAndEditReportController {
    public List <LayoutDescriberHelper.LayoutSection > layoutSections{set;get;}
    public static Map<String, Schema.SObjectType> schemaMap = Schema.getGlobalDescribe();
    public static String sobjectTypeValue = 'Report__c';
    public Boolean isNewMode{set;get;}
    public String rtTypeId {get; set;}
    public String AWSDataId{set;get;}
    public String contactId{set;get;}//For Lookup field
    public List<String> encryptedAPIList{set;get;}
    public String staticResource {get; set;}
    public String staticResourceContact {get; set;}
    public String requiredFieldAPIListStr {get; set;}
    public String fieldAPIToLabelMapStr {get; set;}
    public String requiredErrorMsg{set;get;}
    public String contactsInfo {set;get;}
    public String PIPL_Input_Account_Error_Msg{set;get;}
    public String SaveAndNewButtonUrl{get;private set;}
    public String sobjectPrefix{get;private set;}
    public String sobjecttypeForFrontEnd{set;get;}
    public String sobjectId{set;get;}
    public NewAndEditReportController(ApexPages.StandardController controller) {
        sobjectId = [SELECT CustomObjectId,CustomObjectName  FROM CustomObjectUserLicenseMetrics   where CustomObjectName ='Report' limit 1].CustomObjectId;
        isNewMode = true;
        requiredErrorMsg = Label.Input_Required_Field_Msg;
        PIPL_Input_Account_Error_Msg = label.PIPL_Input_Account_Error_Msg;
        sobjecttypeForFrontEnd = sobjectTypeValue;
        //获取所有字段
        List<String> fieldList = new List<String>(Schema.getGlobalDescribe().get('Report__c').getDescribe().fields.getMap().keyset());
        // Add fields to controller. This is to avoid the SOQL error in visualforce page
        controller.addFields(fieldList);
        SObject obj = controller.getRecord();
        if(obj.Id != null){
            //更新
            isNewMode = false;
            Report__c ReportData = [select Id,RecordTypeId,AWS_Data_Id__c,Practitioner1__c,Practitioner1__r.AWS_Data_Id__c,
            Practitioner2__c,Practitioner2__r.AWS_Data_Id__c,Practitioner3__c,Practitioner3__r.AWS_Data_Id__c,
            Practitioner4__c,Practitioner4__r.AWS_Data_Id__c,Practitioner5__c,Practitioner5__r.AWS_Data_Id__c,
            Person_In_Charge__c,Person_In_Charge__r.AWS_Data_Id__c
            from Report__c where id =: obj.Id];
            system.debug('ReportData = ' + ReportData);
            rtTypeId = ReportData.RecordTypeId;
            AWSDataId = ReportData.AWS_Data_Id__c;
            Map<String,String> sfIdToAWSIdMap = new Map<String,String>();
            if(ReportData.Practitioner1__r.Id != null && ReportData.Practitioner1__r.AWS_Data_Id__c!=null){
                sfIdToAWSIdMap.put(String.valueof(ReportData.Practitioner1__r.Id).subString(0,15),ReportData.Practitioner1__r.AWS_Data_Id__c);
            }
            if(ReportData.Practitioner2__r.Id != null && ReportData.Practitioner2__r.AWS_Data_Id__c!=null){
                sfIdToAWSIdMap.put(String.valueof(ReportData.Practitioner2__r.Id).subString(0,15),ReportData.Practitioner2__r.AWS_Data_Id__c);
            }
            if(ReportData.Practitioner3__r.Id != null && ReportData.Practitioner3__r.AWS_Data_Id__c!=null){
                sfIdToAWSIdMap.put(String.valueof(ReportData.Practitioner3__r.Id).subString(0,15),ReportData.Practitioner3__r.AWS_Data_Id__c);
            }
            if(ReportData.Practitioner4__r.Id != null && ReportData.Practitioner4__r.AWS_Data_Id__c!=null){
                sfIdToAWSIdMap.put(String.valueof(ReportData.Practitioner4__r.Id).subString(0,15),ReportData.Practitioner4__r.AWS_Data_Id__c);
            }
            if(ReportData.Practitioner5__r.Id != null && ReportData.Practitioner5__r.AWS_Data_Id__c!=null){
                sfIdToAWSIdMap.put(String.valueof(ReportData.Practitioner5__r.Id).subString(0,15),ReportData.Practitioner5__r.AWS_Data_Id__c);
            }
            if(ReportData.Person_In_Charge__r.Id != null && ReportData.Person_In_Charge__r.AWS_Data_Id__c!=null){
                sfIdToAWSIdMap.put(String.valueof(ReportData.Person_In_Charge__r.Id).subString(0,15),ReportData.Person_In_Charge__r.AWS_Data_Id__c);
            }
            contactsInfo = JSON.serialize(sfIdToAWSIdMap);
        }else{
            //新建
            rtTypeId = ApexPages.currentPage().getParameters().get('RecordType');
            obj.put('OwnerId',UserInfo.getUserId());
        }
        LayoutDescriberHelper.LayoutWrapper LayoutWrapperValue = LayoutDescriberHelper.describeSectionWithFieldsWrapper(rtTypeId, 'Report__c','classic');
        layoutSections = LayoutWrapperValue.layoutSections;
        List<String> requiredFieldAPIList = LayoutWrapperValue.requiredFieldAPIList;
        Map<String,String> fieldAPIToLabelMap = LayoutWrapperValue.fieldAPIToLabelMap;
        requiredFieldAPIListStr = JSON.serialize(requiredFieldAPIList);
        fieldAPIToLabelMapStr = JSON.serialize(fieldAPIToLabelMap);
        PIHelper.PIIntegration piIntegration = PIHelper.getPIIntegrationInfo('Report__c');
        staticResource = JSON.serialize(piIntegration);
        encryptedAPIList = piIntegration.PIFields;
        staticResourceContact = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));
        sobjectPrefix = piIntegration.sobjectPrefix;
    }
    global class Response{
        public String recordId{set;get;}
        public String message{set;get;}
        public String status{set;get;}
    }
    @RemoteAction
    global static Response saveReport(String reportJson,String transId,Boolean isNew) {
        System.debug('report Info:' + JSON.serialize(reportJson));
        //System.debug('rtTypeId: ' + rtTypeId);
        //1. Prepare the payload for  report
        Schema.SObjectType reportSchema = schemaMap.get(sobjectTypeValue);
        Map<String, Schema.SObjectField> fieldAPIToTypeMap = reportSchema.getDescribe().fields.getMap();
        Map<String,Object> fieldValueMap = (Map<String,Object>)JSON.deserializeUntyped(reportJson);
        Report__c reportInfo = new Report__c();
        System.debug('自定义格式转换开始');
        //自定义格式转换
        for (String fieldAPI: fieldValueMap.keySet()) {
            System.debug('field API'+fieldAPI);
            Schema.DisplayType fielddataType = fieldAPIToTypeMap.get(fieldAPI).getDescribe().getType();
            String fieldValue = String.valueOf(fieldValueMap.get(fieldAPI));
            if(String.isBlank(fieldValue)){
                continue;
            }
            if(String.valueOf(fielddataType)=='DATE'){
                reportInfo.put(fieldAPI, Date.valueOf(String.valueOf(fieldValueMap.get(fieldAPI)).replace('/', '-')));
            }else if(String.valueOf(fielddataType)=='DATETIME'){
                String dt = String.valueOf(fieldValueMap.get(fieldAPI));
                if(String.isNotBlank(dt)&&dt.contains('T')){
                    dt = dt.replace('T',' ');
                    reportInfo.put(fieldAPI, Datetime.valueOfGmt(dt));
                }
            }else if(String.valueOf(fielddataType)=='Number'||String.valueOf(fielddataType)=='DOUBLE' ){
                reportInfo.put(fieldAPI, Decimal.valueOf(String.valueOf(fieldValueMap.get(fieldAPI))));
            } else if(String.valueof(fielddataType)=='BOOLEAN'){
                reportInfo.put(fieldAPI, fieldValueMap.get(fieldAPI));
            }else {
                reportInfo.put(fieldAPI, String.valueOf(fieldValueMap.get(fieldAPI)));
            }
        }
        System.debug('自定义格式转换结束');
        //2. Save Record Process
        String status = 'success';
        Response resp = new Response();
        Savepoint sp = Database.setSavepoint();
        String rid = '';
        try{
            if(isNew){
                System.debug('reportInfo = ' + reportInfo);
                insert reportInfo;
            }else{
                System.debug('into update');
                String awsDataId = (String)reportInfo.get('AWS_Data_Id__c');
                System.debug('awsDataId = ' + awsDataId);
                report__c[] reports = [select id from report__c where AWS_Data_Id__c =:awsDataId];
                System.debug('reports[0].id = ' + reports[0].id);
                reportInfo.put('Id',reports[0].id);//For testing;
                update reportInfo;
            }
            rid=reportInfo.Id;
            PIHelper.saveTransLog(sobjectTypeValue,(String)reportInfo.get('AWS_Data_Id__c'),rid,transId,reportJson ,status,'');
            resp.recordId = reportInfo.Id;
            // resp.message = 'success savereport';
            resp.status = status;
            return resp;
        } catch(Exception e) {
            System.debug('into catch'+e.getMessage());
            Database.rollback(sp);
            status = 'fail';
            PIHelper.saveTransLog(sobjectTypeValue,(String)reportInfo.get('AWS_Data_Id__c'),rid,transId,reportJson,status,e.getMessage());
            resp.message = e.getMessage();
            resp.status = status;
            return resp;
        }
    }
}
force-app/main/default/classes/NewAndEditReportController.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>52.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/NewAndEditTenderinformationController.cls
New file
@@ -0,0 +1,45 @@
global class NewAndEditTenderinformationController extends NewAndEditBaseController
{
    public NewAndEditTenderinformationController(ApexPages.StandardController controller) {
        List<String> fieldList = new List<String>(Schema.getGlobalDescribe().get('Tender_information__c').getDescribe().fields.getMap().keyset());
        // Add fields to controller. This is to avoid the SOQL error in visualforce page
        controller.addFields(fieldList);
        Init(controller.getRecord());
        // AWSToSobjectNonEncryptedMap.put('lastName', 'LastName');
        // AWSToSobjectNonEncryptedMap.put('phone', 'Phone');
        // AWSToSobjectNonEncryptedMap.put('email', 'Email');
        // AWSToSobjectNonEncryptedMap.put('medicalStaffFullName', 'MedicalStaff_Full_name__c');
        // AWSToSobjectNonEncryptedMap.put('mobilePhone', 'MobilePhone');
        // AWSToSobjectNonEncryptedMap.put('title', 'Title');
        // AWSToSobjectNonEncryptedMap.put('olyAssistantType', 'OLY_Assistant_Type__c');
        // AWSToSobjectNonEncryptedMap.put('jobCategoryPicklist', 'Job_Category_picklist__c');
        // AWSToSobjectNonEncryptedMap.put('type', 'Type__c');
        // AWSToSobjectNonEncryptedMap.put('contactAddress', 'Contact_address__c');
        // AWSToSobjectNonEncryptedMap.put('contactType', 'ContactType__c');
        // AWSToSobjectNonEncryptedMap.put('doctorDivision1', 'Doctor_Division1__c');
        // AWSToSobjectNonEncryptedMap.put('uniqueNumber', 'UniqueNumber__c');
        // AWSToSobjectEncryptedMap.put('lastNameEncrypt', 'LastName_Encrypted__c');
        // AWSToSobjectEncryptedMap.put('phoneEncrypt', 'Phone_Encrypted__c');
        // AWSToSobjectEncryptedMap.put('emailEncrypt', 'Email_Encrypted__c');
        // AWSToSobjectEncryptedMap.put('medicalStaffFullNameEncrypt', 'MedicalStaff_Full_name_Encrypted__c');
        // AWSToSobjectEncryptedMap.put('mobilePhoneEncrypt', 'MobilePhone_Encrypted__c');
        // AWSToSobjectEncryptedMap.put('titleEncrypt', 'Title_Encrypted__c');
        // AWSToSobjectEncryptedMap.put('olyAssistantTypeEncrypt', 'OLY_Assistant_Type_Encrypted__c');
        // AWSToSobjectEncryptedMap.put('jobCategoryPicklistEncrypt', 'Job_Category_picklist_Encrypted__c');
        // AWSToSobjectEncryptedMap.put('typeEncrypt', 'Type_Encrypted__c');
        // AWSToSobjectEncryptedMap.put('contactAddressEncrypt', 'Contact_address_Encrypted__c');
        // AWSToSobjectEncryptedMap.put('contactTypeEncrypt', 'ContactType_Encrypted__c');
        // AWSToSobjectEncryptedMap.put('doctorDivision1Encrypt', 'Doctor_Division1_Encrypted__c');
        // AWSToSobjectEncryptedMap.put('uniqueNumberEncrypt', 'UniqueNumber_Encrypted__c');
    }
    @RemoteAction
    global static Response saveTenderinformation(String leadJson,String transId,Boolean isNew) {
        return save(new Tender_information__c(),leadJson,transId,isNew);
    }
}
force-app/main/default/classes/NewAndEditTenderinformationController.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/NewConsumApplyController.cls
New file
@@ -0,0 +1,139 @@
/**
 * @description       :
 * @author            : ChangeMeIn@UserSettingsUnder.SFDoc
 * @group             :
 * @last modified on  : 03-10-2022
 * @last modified by  : ChangeMeIn@UserSettingsUnder.SFDoc
**/
global without sharing class NewConsumApplyController {
    public List <LayoutDescriberHelper.LayoutSection > layoutSections{set;get;}
    public String awsToken{set;get;}
    public static Map<String, Schema.SObjectType> schemaMap = Schema.getGlobalDescribe();
    public static String sobjectTypeValue = 'Consum_Apply__c';
    public Boolean isNewMode{set;get;}
    public String rtTypeId {get; set;}
    public String AWSDataId{set;get;}
    public List<String> encryptedAPIList{set;get;}
    public String staticResource {get; set;}
    public String staticResourceContact {get; set;}
    public String requiredFieldAPIListStr {get; set;}
    public String fieldAPIToLabelMapStr {get; set;}
    public String Input_Required_Field_Msg{set;get;}
    public String requiredErrorMsg{set;get;}
    public String contactsInfo {set;get;}
    public String contactId{set;get;}
    public String PIPL_Input_Account_Error_Msg{set;get;}
    public NewConsumApplyController(ApexPages.StandardController controller) {
        isNewMode = true;
        Input_Required_Field_Msg = Label.Input_Required_Field_Msg;
        PIPL_Input_Account_Error_Msg = label.PIPL_Input_Account_Error_Msg;
        //获取所有字段
        List<String> fieldList = new List<String>(Schema.getGlobalDescribe().get('Consum_Apply__c').getDescribe().fields.getMap().keyset());
        controller.addFields(fieldList);
        SObject obj = controller.getRecord();
        if(obj.Id != null){
            //更新
            isNewMode = false;
            Consum_Apply__c consumApplyData = [select Id,RecordTypeId,AWS_Data_Id__c,Loaner_medical_Staff__c,Loaner_medical_Staff__r.AWS_Data_Id__c from Consum_Apply__c where id =: obj.Id];
            rtTypeId = consumApplyData.RecordTypeId;
            AWSDataId = consumApplyData.AWS_Data_Id__c;
            Map<String,String> sfIdToAWSIdMap = new Map<String,String>();
            // if(consumApplyData.Loaner_medical_Staff__c != null && consumApplyData.Loaner_medical_Staff__c != '') {
            if(consumApplyData.Loaner_medical_Staff__r.Id != null){
                sfIdToAWSIdMap.put(String.valueof(consumApplyData.Loaner_medical_Staff__r.Id).subString(0,15),consumApplyData.Loaner_medical_Staff__r.AWS_Data_Id__c);
            }
            // sfIdToAWSIdMap.put(String.valueof(consumApplyData.Contact_Name__r.Id).subString(0,15),consumApplyData.Loaner_medical_Staff__r.AWS_Data_Id__c);
            contactsInfo = JSON.serialize(sfIdToAWSIdMap);
        }else{
            //新建
            rtTypeId = ApexPages.currentPage().getParameters().get('RecordType');
            obj.put('OwnerId',UserInfo.getUserId());
        }
        LayoutDescriberHelper.LayoutWrapper LayoutWrapperValue = LayoutDescriberHelper.describeSectionWithFieldsWrapper(rtTypeId, 'Consum_Apply__c','classic');
        layoutSections = LayoutWrapperValue.layoutSections;
        List<String> requiredFieldAPIList = LayoutWrapperValue.requiredFieldAPIList;
        Map<String,String> fieldAPIToLabelMap = LayoutWrapperValue.fieldAPIToLabelMap;
        requiredFieldAPIListStr = JSON.serialize(requiredFieldAPIList);
        fieldAPIToLabelMapStr = JSON.serialize(fieldAPIToLabelMap);
        staticResource = JSON.serialize(PIHelper.getPIIntegrationInfo('Consum_Apply__c'));
        encryptedAPIList = PIHelper.getPIIntegrationInfo('Consum_Apply__c').PIFields;
        staticResourceContact = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));
    }
    global class Response{
        public String recordId{set;get;}
        public String message{set;get;}
        public String status{set;get;}
    }
    @RemoteAction
    global static Response saveConsumApply(String consumApplyJson,String transId,Boolean isNew) {
        System.debug('Consum_Apply__c Info:' + JSON.serialize(consumApplyJson));
        //1. Prepare the payload for  Consum_Apply__c
        Schema.SObjectType consumApplySchema = schemaMap.get(sobjectTypeValue);
        Map<String, Schema.SObjectField> fieldAPIToTypeMap = consumApplySchema.getDescribe().fields.getMap();
        system.debug(fieldAPIToTypeMap);
        Map<String,Object> fieldValueMap = (Map<String,Object>)JSON.deserializeUntyped(consumApplyJson);
        Consum_Apply__c consumApplyInfo = new Consum_Apply__c();
        //自定义格式转换
        for (String fieldAPI: fieldValueMap.keySet()) {
            system.debug('field API='+fieldAPI);
            Schema.DisplayType fielddataType = fieldAPIToTypeMap.get(fieldAPI).getDescribe().getType();
            String fieldValue = String.valueOf(fieldValueMap.get(fieldAPI));
            system.debug('Field Type:'+fielddataType+' field Value='+fieldValue);
            if(String.valueOf(fielddataType)=='DATE'){
                consumApplyInfo.put(fieldAPI,(String.isBlank(fieldValue)||String.isEmpty(fieldValue))? null:Date.valueOf(fieldValue.replace('/', '-')));
            }else if(String.valueOf(fielddataType)=='DATETIME'){
                if(String.isNotBlank(fieldValue)&&fieldValue.contains('T')){
                    fieldValue = fieldValue.replace('T',' ');
                    consumApplyInfo.put(fieldAPI, Datetime.valueOfGmt(fieldValue));
                }else{
                    consumApplyInfo.put(fieldAPI, null);
                }
            }else if(String.valueof(fielddataType)=='CURRENCY'|| String.valueof(fielddataType)=='PERCENT'||String.valueOf(fielddataType)=='Number'||String.valueOf(fielddataType)=='DOUBLE' ){
                consumApplyInfo.put(fieldAPI, (String.isBlank(fieldValue)||String.isEmpty(fieldValue))?0:Decimal.valueOf(fieldValue));
            } else if(String.valueof(fielddataType)=='BOOLEAN'){
                consumApplyInfo.put(fieldAPI, fieldValueMap.get(fieldAPI));
            }else {
                consumApplyInfo.put(fieldAPI,fieldValue);
            }
        }
        //2. Save Record Process
        String status = 'success';
        Response resp = new Response();
        Savepoint sp = Database.setSavepoint();
        String rid = '';
        try{
            System.debug('abcde');
            if(isNew){
                System.debug('consumApplyInfozhj = ' + consumApplyInfo);
                insert consumApplyInfo;
                System.debug('consumApplyInfo.Id' + consumApplyInfo.Id);
            }else{
                System.debug('into update');
                String awsDataId = (String)consumApplyInfo.get('AWS_Data_Id__c');
                System.debug('awsDataId = ' + awsDataId);
                Consum_Apply__c[] ConsumApplys = [select id from Consum_Apply__c where AWS_Data_Id__c =:awsDataId];
                System.debug('ConsumApplys[0].id = ' + ConsumApplys[0].id);
                consumApplyInfo.put('Id',ConsumApplys[0].id);//For testing;
                update consumApplyInfo;
            }
            rid=consumApplyInfo.Id;
            PIHelper.saveTransLog(sobjectTypeValue,rid,transId, (String)consumApplyInfo.get('AWS_Data_Id__c'),consumApplyJson ,status,'');
            resp.recordId = consumApplyInfo.Id;
            resp.message = '';
            resp.status = status;
            System.debug('resp from sfdx back-end' + resp);
            return resp;
        } catch(Exception e) {
            System.debug('into catch'+e.getMessage());
            Database.rollback(sp);
            status = 'fail';
            PIHelper.saveTransLog(sobjectTypeValue,rid,transId, (String)consumApplyInfo.get('AWS_Data_Id__c'),consumApplyJson,status,e.getMessage());
            resp.message = e.getMessage();
            resp.status = status;
            return resp;
        }
    }
}
force-app/main/default/classes/NewConsumApplyController.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>53.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/NewConsumApplyEquipSetDetailController.cls
New file
@@ -0,0 +1,125 @@
global without sharing class NewConsumApplyEquipSetDetailController {
    public List <LayoutDescriberHelper.LayoutSection > layoutSections{set;get;}
    public String awsToken{set;get;}
    public static Map<String, Schema.SObjectType> schemaMap = Schema.getGlobalDescribe();
    public static String sobjectTypeValue = 'Consum_Apply_Equipment_Set_Detail__c';
    public Boolean isNewMode{set;get;}
    public String rtTypeId {get; set;}
    public String AWSDataId{set;get;}
    public List<String> encryptedAPIList{set;get;}
    public String staticResource {get; set;}
    public String requiredFieldAPIListStr {get; set;}
    public String fieldAPIToLabelMapStr {get; set;}
    public String Input_Required_Field_Msg{set;get;}
    public String requiredErrorMsg{set;get;}
    public String sobjecttypeForFrontEnd{set;get;}
    public String sobjectPrefix{set;get;}
    public NewConsumApplyEquipSetDetailController(ApexPages.StandardController controller) {
        isNewMode = true;
        Input_Required_Field_Msg = Label.Input_Required_Field_Msg;
        sobjecttypeForFrontEnd = sobjectTypeValue;
        //获取所有字段
        List<String> fieldList = new List<String>(Schema.getGlobalDescribe().get('Consum_Apply_Equipment_Set_Detail__c').getDescribe().fields.getMap().keyset());
        controller.addFields(fieldList);
        SObject obj = controller.getRecord();
        if(obj.Id != null){
            //更新
            isNewMode = false;
            Consum_Apply_Equipment_Set_Detail__c consumApplyData = [select Id,AWS_Data_Id__c from Consum_Apply_Equipment_Set_Detail__c where id =: obj.Id];
            AWSDataId = consumApplyData.AWS_Data_Id__c;
        }else{
            //新建
            rtTypeId = ApexPages.currentPage().getParameters().get('RecordType');
        }
        LayoutDescriberHelper.LayoutWrapper LayoutWrapperValue = LayoutDescriberHelper.describeSectionWithFieldsWrapper(rtTypeId, 'Consum_Apply_Equipment_Set_Detail__c','classic');
        layoutSections = LayoutWrapperValue.layoutSections;
        List<String> requiredFieldAPIList = LayoutWrapperValue.requiredFieldAPIList;
        Map<String,String> fieldAPIToLabelMap = LayoutWrapperValue.fieldAPIToLabelMap;
        requiredFieldAPIListStr = JSON.serialize(requiredFieldAPIList);
        fieldAPIToLabelMapStr = JSON.serialize(fieldAPIToLabelMap);
        PIHelper.PIIntegration piIntegration =PIHelper.getPIIntegrationInfo('Consum_Apply_Equipment_Set_Detail__c');
        staticResource = JSON.serialize(piIntegration);
        encryptedAPIList = piIntegration.PIFields;
        sobjectPrefix = piIntegration.sobjectPrefix;
    }
    global class Response{
        public String recordId{set;get;}
        public String message{set;get;}
        public String status{set;get;}
    }
    @RemoteAction
    global static Response saveConsumApply(String consumApplyJson,String transId,Boolean isNew) {
        System.debug('Consum_Apply_Equipment_Set_Detail__c Info:' + JSON.serialize(consumApplyJson));
        //1. Prepare the payload for  Consum_Apply_Equipment_Set_Detail__c
        Schema.SObjectType consumApplySchema = schemaMap.get(sobjectTypeValue);
        Map<String, Schema.SObjectField> fieldAPIToTypeMap = consumApplySchema.getDescribe().fields.getMap();
        system.debug(fieldAPIToTypeMap);
        Map<String,Object> fieldValueMap = (Map<String,Object>)JSON.deserializeUntyped(consumApplyJson);
        Consum_Apply_Equipment_Set_Detail__c consumApplyInfo = new Consum_Apply_Equipment_Set_Detail__c();
        //自定义格式转换
        for (String fieldAPI: fieldValueMap.keySet()) {
            system.debug('field API'+fieldAPI);
            String fieldValue = String.valueOf(fieldAPIToTypeMap.get(fieldAPI));
            if(String.isBlank(fieldValue)){
                continue;
            }
            Schema.DescribeFieldResult fielddataType = fieldAPIToTypeMap.get(fieldAPI).getDescribe();
            Schema.DisplayType fieldDatas = fielddataType.getType();
            if(String.valueOf(fielddatas)=='DATE'){
                consumApplyInfo.put(fieldAPI, Date.valueOf(String.valueOf(fieldValueMap.get(fieldAPI)).replace('/', '-')));
            }else if(String.valueOf(fielddatas)=='DATETIME'){
                String dt = String.valueOf(fieldValueMap.get(fieldAPI));
                if(String.isNotBlank(dt)&&dt.contains('T')){
                    dt = dt.replace('T',' ');
                    consumApplyInfo.put(fieldAPI, Datetime.valueOfGmt(dt));
                }
            }else if(String.valueOf(fielddatas)=='Number'||String.valueOf(fielddatas)=='DOUBLE'){
                // ||String.valueOf(fielddatas)=='Decimal'
                consumApplyInfo.put(fieldAPI, Decimal.valueOf(String.valueOf(fieldValueMap.get(fieldAPI))));
            } else if(String.valueof(fielddatas)=='BOOLEAN'){
                consumApplyInfo.put(fieldAPI, fieldValueMap.get(fieldAPI));
            }else {
                consumApplyInfo.put(fieldAPI, String.valueOf(fieldValueMap.get(fieldAPI)));
            }
        }
        //2. Save Record Process
        String status = 'success';
        Response resp = new Response();
        Savepoint sp = Database.setSavepoint();
        String rid = '';
        try{
            System.debug('abcde');
            if(isNew){
                System.debug('consumApplyInfozhj = ' + consumApplyInfo);
                insert consumApplyInfo;
                System.debug('consumApplyInfo.Id' + consumApplyInfo.Id);
            }else{
                System.debug('into update');
                String awsDataId = (String)consumApplyInfo.get('AWS_Data_Id__c');
                System.debug('awsDataId = ' + awsDataId);
                Consum_Apply_Equipment_Set_Detail__c[] ConsumApplys = [select id from Consum_Apply_Equipment_Set_Detail__c where AWS_Data_Id__c =:awsDataId];
                System.debug('ConsumApplys[0].id = ' + ConsumApplys[0].id);
                consumApplyInfo.put('Id',ConsumApplys[0].id);//For testing;
                update consumApplyInfo;
            }
            rid=consumApplyInfo.Id;
            PIHelper.saveTransLog(sobjectTypeValue,(String)consumApplyInfo.get('AWS_Data_Id__c'),rid,transId,consumApplyJson,status,'');
            resp.recordId = consumApplyInfo.Id;
            resp.message = 'success saveConsumApply';
            resp.status = status;
            System.debug('respzhj = ' + resp);
            return resp;
        } catch(Exception e) {
            System.debug('into catch'+e.getMessage());
            Database.rollback(sp);
            status = 'fail';
            PIHelper.saveTransLog(sobjectTypeValue,(String)consumApplyInfo.get('AWS_Data_Id__c'),rid,transId,consumApplyJson,status,e.getMessage());
            resp.message = e.getMessage();
            resp.status = status;
            return resp;
        }
    }
}
force-app/main/default/classes/NewConsumApplyEquipSetDetailController.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/NewListOfConsumablesController.cls
New file
@@ -0,0 +1,3 @@
public class NewListOfConsumablesController {
}
force-app/main/default/classes/NewListOfConsumablesController.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/NewRepairController.cls
New file
@@ -0,0 +1,148 @@
/*
 *@Description:
 *@Author: Dennis Rodman
 *@Date: 2022-03-10 10:26:47
*/
global without sharing class NewRepairController {
    public List <LayoutDescriberHelper.LayoutSection > layoutSections{set;get;}
    public String awsToken{set;get;}
    public static Map<String, Schema.SObjectType> schemaMap = Schema.getGlobalDescribe();
    public static String sobjectTypeValue = 'Repair__c';
    public Boolean isNewMode{set;get;}
    public String rtTypeId {get; set;}
    public String AWSDataId{set;get;}
    public String DecryptAWSDataId{set;get;}
    public String ContactAWSDataId{set;get;}
    public List<String> encryptedAPIList{set;get;}
    public String staticResource {get; set;}
    public String staticResourceContact {get; set;}
    public String staticResourceAddress {get; set;}
    public String requiredFieldAPIListStr {get; set;}
    public String fieldAPIToLabelMapStr {get; set;}
    public String Input_Required_Field_Msg{set;get;}
    public String PIPL_Name_Label{set;get;}
    public String PIPL_Input_Account_Error_Msg{set;get;}
    public String sobjectPrefix{set;get;}
    public String sobjecttypeForFrontEnd{set;get;}
    public String sobjectId{set;get;}
    public NewRepairController(ApexPages.StandardController controller) {
        sobjectId = [SELECT CustomObjectId,CustomObjectName  FROM CustomObjectUserLicenseMetrics   where CustomObjectName ='Repair' limit 1].CustomObjectId;
        isNewMode = true;
        Input_Required_Field_Msg = Label.Input_Required_Field_Msg;
        PIPL_Name_Label = Label.PIPL_Name_Label;
        PIPL_Input_Account_Error_Msg = label.PIPL_Input_Account_Error_Msg;
        sobjecttypeForFrontEnd = sobjectTypeValue;
        //获取所有字段
        List<String> fieldList = new List<String>(Schema.getGlobalDescribe().get('Repair__c').getDescribe().fields.getMap().keyset());
        // Add fields to controller. This is to avoid the SOQL error in visualforce page
        controller.addFields(fieldList);
        SObject obj = controller.getRecord();
        if(obj.Id != null){
            //更新
            isNewMode = false;
            Repair__c repairData = [select Id,RecordTypeId,AWS_Data_Id__c,Address_AWS_Data_Id__c,Contact_AWS_Data_Id__c,Address_Contacts_Encrypt__c,Address_Contacts_Name_Encrypt__c,Address_Telephone_Encrypt__c,Address_ZipCode_Encrypt__c,Detailed_Address_Encrypt__c from Repair__c where id =: obj.Id];
            rtTypeId = repairData.RecordTypeId;
            AWSDataId = repairData.AWS_Data_Id__c;
            DecryptAWSDataId = String.valueOf(repairData.Address_AWS_Data_Id__c);
            ContactAWSDataId = String.valueOf(repairData.Contact_AWS_Data_Id__c);
        }else{
            //新建
            rtTypeId = ApexPages.currentPage().getParameters().get('RecordType');
            if(String.isBlank(rtTypeId)||String.isEmpty(rtTypeId)){
                List<RecordType> rtList = new List<RecordType>([select Id,DeveloperName from RecordType  where SobjectType ='Repair__c' and DeveloperName ='Repair']);
                rtTypeId = rtList[0].Id;
            }
        }
        LayoutDescriberHelper.LayoutWrapper LayoutWrapperValue = LayoutDescriberHelper.describeSectionWithFieldsWrapper(rtTypeId, 'Repair__c','classic');
        layoutSections = LayoutWrapperValue.layoutSections;
        List<String> requiredFieldAPIList = LayoutWrapperValue.requiredFieldAPIList;
        Map<String,String> fieldAPIToLabelMap = LayoutWrapperValue.fieldAPIToLabelMap;
        requiredFieldAPIListStr = JSON.serialize(requiredFieldAPIList);
        fieldAPIToLabelMapStr = JSON.serialize(fieldAPIToLabelMap);
        PIHelper.PIIntegration piIntegration = PIHelper.getPIIntegrationInfo('Repair__c');
        PIHelper.PIIntegration piIntegrationAddress = PIHelper.getPIIntegrationInfo('Address__c');
        PIHelper.PIIntegration piIntegrationContact = PIHelper.getPIIntegrationInfo('Contact');
        staticResource = JSON.serialize(piIntegration);
        staticResourceAddress = JSON.serialize(piIntegrationAddress);
        staticResourceContact = JSON.serialize(piIntegrationContact);
        encryptedAPIList = piIntegration.PIFields;
        sobjectPrefix = piIntegration.sobjectPrefix;
    }
    global class Response{
        public String recordId{set;get;}
        public String message{set;get;}
        public String status{set;get;}
    }
    @RemoteAction
    global static Response saveRepair(String repairJson,String transId,Boolean isNew) {
        System.debug('Repair__c Info:' + JSON.serialize(repairJson));
        //1. Prepare the payload for  Repair__c
        Schema.SObjectType repairSchema = schemaMap.get(sobjectTypeValue);
        Map<String, Schema.SObjectField> fieldAPIToTypeMap = repairSchema.getDescribe().fields.getMap();
        Map<String,Object> fieldValueMap = (Map<String,Object>)JSON.deserializeUntyped(repairJson);
        Repair__c repairInfo = new Repair__c();
        //自定义格式转换
        for (String fieldAPI: fieldValueMap.keySet()) {
            system.debug('field API'+fieldAPI);
            Schema.DisplayType fielddataType = fieldAPIToTypeMap.get(fieldAPI).getDescribe().getType();
            String fieldValue = String.valueOf(fieldValueMap.get(fieldAPI));
            if(String.isBlank(fieldValue)){
                continue;
            }
            if(String.valueOf(fielddataType)=='DATE'){
                repairInfo.put(fieldAPI, Date.valueOf(String.valueOf(fieldValueMap.get(fieldAPI)).replace('/', '-')));
            }else if(String.valueOf(fielddataType)=='DATETIME'){
                String dt = String.valueOf(fieldValueMap.get(fieldAPI));
                if(String.isNotBlank(dt)&&dt.contains('T')){
                    dt = dt.replace('T',' ');
                    repairInfo.put(fieldAPI, Datetime.valueOfGmt(dt));
                }
            }else if(String.valueOf(fielddataType)=='PERCENT'||String.valueOf(fielddataType)=='CURRENCY'||String.valueOf(fielddataType)=='Number'||String.valueOf(fielddataType)=='DOUBLE' ){
                repairInfo.put(fieldAPI, Decimal.valueOf(String.valueOf(fieldValueMap.get(fieldAPI))));
            } else if(String.valueof(fielddataType)=='BOOLEAN'){
                repairInfo.put(fieldAPI, fieldValueMap.get(fieldAPI));
            }else {
                repairInfo.put(fieldAPI, String.valueOf(fieldValueMap.get(fieldAPI)));
            }
        }
        //2. Save Record Process
        String status = 'success';
        Response resp = new Response();
        Savepoint sp = Database.setSavepoint();
        String rid = '';
        try{
            System.debug('abcde');
            if(isNew){
                System.debug('repairInfozhj = ' + repairInfo);
                insert repairInfo;
            }else{
                System.debug('into update');
                String awsDataId = (String)repairInfo.get('AWS_Data_Id__c');
                System.debug('awsDataId = ' + awsDataId);
                Repair__c[] repairs = [select id from Repair__c where AWS_Data_Id__c =:awsDataId];
                System.debug('repairs[0].id = ' + repairs[0].id);
                repairInfo.put('Id',repairs[0].id);//For testing;
                update repairInfo;
            }
            rid=repairInfo.Id;
            PIHelper.saveTransLog(sobjectTypeValue,rid,transId, (String)repairInfo.get('AWS_Data_Id__c'),repairJson ,status,'');
            resp.recordId = repairInfo.Id;
            resp.message = '';
            resp.status = status;
            System.debug('resp from sfdx back-end' + resp);
            return resp;
        } catch(Exception e) {
            System.debug('into catch'+e.getMessage());
            Database.rollback(sp);
            status = 'fail';
            PIHelper.saveTransLog(sobjectTypeValue,rid,transId, (String)repairInfo.get('AWS_Data_Id__c'),repairJson,status,e.getMessage());
            resp.message = e.getMessage();
            resp.status = status;
            return resp;
        }
    }
}
force-app/main/default/classes/NewRepairController.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/OFSInsReportLayoutController.cls
@@ -28,7 +28,7 @@
    private String oldHospital;
    private String oldStatus;
    private Boolean isPDF;
    public Boolean isPDF{get;private set;}
    private Boolean isUpDown;
    private Boolean isSubmit;
    public String alertMessage {
@@ -247,18 +247,23 @@
            oirSettingMap.put(oir.recordType_devName__c, oir);
        }
    }
    public string staticResource { get; private set; }
    //public boolean IsAddmessage { get; private set; }
    /**
    * Visaulforceから呼ばれるコンストラクタ
    */
    public OFSInsReportLayoutController(ApexPages.StandardController controller) {
        staticResource = JSON.serialize(PIHelper.getPIIntegrationInfo('Inspection_Report__c'));
}
    public OFSInsReportLayoutController() {
        countorder = 1;
        nowAssetcount = 1;
        runCount = 0;
        isUpDown = true;
        staticResource = JSON.serialize(PIHelper.getPIIntegrationInfo('Inspection_Report__c'));
    }
    // TODO 全部画面リフレッシュにする
@@ -335,7 +340,7 @@
                pReportId = iis[0].Inspection_ReportId__c;
            }
            List < Inspection_Report__c > queryIrs = [select Id, RecordType.DeveloperName, RecordType.Name, Name, Status__c, Inspection_StartTime__c, Inspection_EndTime__c from Inspection_Report__c where Id = :pReportId];
            List < Inspection_Report__c > queryIrs = [select Id, RecordType.DeveloperName, RecordType.Name, Name, Status__c, Inspection_StartTime__c, Inspection_EndTime__c,Responsible_Person_Encrypted__c,phone_Encrypted__c,AWS_Data_Id__c from Inspection_Report__c where Id = :pReportId];
            if (queryIrs.size() <= 0) {
                initFlag = false;
                ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR, '无法找到点检报告书'));
@@ -401,7 +406,7 @@
            }
        }
        this.settingSoql = 'select Id, Name, Name_Manual__c, Next_StartHour_Page__c, Next_StartMinute_Page__c, Next_EndHour_Page__c, Next_EndMinute_Page__c '
        this.settingSoql = 'select Id, Name, Name_Manual__c, Next_StartHour_Page__c, Next_StartMinute_Page__c, Next_EndHour_Page__c, Next_EndMinute_Page__c,Responsible_Person_Encrypted__c,phone_Encrypted__c,AWS_Data_Id__c '
        // fxk 2021/8/4 新加 Start
        + ' , Remarks__c, CleaningFluid__c,SterilizationMethod__c,Disinfectant__c,UsedMachine__c,Used_ET__c ,Mode__c';
        // fxk 2021/8/4 新加 End
@@ -785,14 +790,19 @@
            // }
        }
        if (isError) {
            system.debug('795'+ir.AWS_Data_Id__c);
            return null;
        }
        system.debug('798'+ir.AWS_Data_Id__c);
        //add by rentx 20210630
        if (timeCheck() != true) {
            system.debug('800');
            return null;
        }
        system.debug('804');
        if (isPDF) {
            ir.Status__c = 'PDF';
        }
@@ -801,6 +811,7 @@
            ir.Status__c = '填写完毕';
        }
        system.debug('813');
        Savepoint sp = Database.setSavepoint();
        try {
            // 部长经理总监
@@ -815,9 +826,11 @@
            OFSInsReportAssetHistoryController.upsertInspection_Report(ir);
        } catch(Exception e) {
            clearIrId(sp, e, isIrNew);
            system.debug('829');
            return null;
        }
        system.debug('832');
        // 日報からくる場合、保存時、EventCに書き戻す
        if (String.isBlank(pEventCId) == false) {
            try {
@@ -825,10 +838,11 @@
                update ec;
            } catch(Exception e) {
                clearIrId(sp, e, isIrNew);
                system.debug('840');
                return null;
            }
        }
        system.debug('844');
        //List<Inspection_Item__c> toUpsertAhs = new List<Inspection_Item__c>();
        List < Inspection_Item__c > toDeleteAhs = new List < Inspection_Item__c > ();
        List < Inspection_Item__c > manualDeleteAhs = new List < Inspection_Item__c > ();
@@ -868,14 +882,17 @@
        // SWAG-AREBA8 end
        toDeleteAhs = [select Id, AssetId__c from Inspection_Item__c where AssetId__c in :unCheckedAssetIds and Inspection_ReportId__c = :ir.Id];
        system.debug('884');
        try {
            if (manualDeleteAhs.size() > 0) toDeleteAhs.addAll(manualDeleteAhs);
            OFSInsReportAssetHistoryController.deleteInspection_Item(ir, toDeleteAhs);
        } catch(Exception e) {
            clearIrId(sp, e, isIrNew);
            system.debug('890');
            return null;
        }
        system.debug('894');
        try {
            //OFSInsReportAssetHistoryController.upsertInspection_Item(ir, toUpsertAhs);
            OFSInsReportAssetHistoryController.upsertInspection_Item(ir, new List < Inspection_Item__c > (toUpsertAhsMap.keySet()));
@@ -884,9 +901,11 @@
            for (Inspection_Item__c ah: toUpsertAhsMap.keySet()) {
                if (toUpsertAhsMap.get(ah).isNew == true) ah.Id = null;
            }
            system.debug('903');
            return null;
        }
        system.debug('905');
        saveOK = true;
        this.init();
        return null;
@@ -896,6 +915,7 @@
        if (isIrNew) ir.Id = null;
        Database.rollback(sp);
        ApexPages.addMessages(e);
        //IsAddmessage = true;
    }
    private Boolean checkHpChange() {
force-app/main/default/classes/OnCallController.cls
New file
@@ -0,0 +1,129 @@
global without sharing class OnCallController {
    public List <LayoutDescriberHelper.LayoutSection > layoutSections{set;get;}
    public String awsToken{set;get;}
    public static Map<String, Schema.SObjectType> schemaMap = Schema.getGlobalDescribe();
    public static String sobjectTypeValue = 'On_Call__c';
    public Boolean isNewMode{set;get;}
    public String rtTypeId {get; set;}
    public String AWSDataId{set;get;}
    public List<String> encryptedAPIList{set;get;}
    public String staticResource {get; set;}
    public String staticResourceContact {get; set;}
    public String requiredFieldAPIListStr {get; set;}
    public String fieldAPIToLabelMapStr {get; set;}
    public String Input_Required_Field_Msg{set;get;}
    public String PIPL_Name_Label{set;get;}
    public String PIPL_Input_Account_Error_Msg{set;get;}
    public String sobjectPrefix{set;get;}
    public String sobjecttypeForFrontEnd{set;get;}
    // public String sobjectId{set;get;}
    public OnCallController(ApexPages.StandardController controller) {
        // sobjectId = [SELECT CustomObjectId,CustomObjectName  FROM CustomObjectUserLicenseMetrics   where CustomObjectName ='OnCall' limit 1].CustomObjectId;
        isNewMode = true;
        Input_Required_Field_Msg = Label.Input_Required_Field_Msg;
        PIPL_Name_Label = Label.PIPL_Name_Label;
        PIPL_Input_Account_Error_Msg = label.PIPL_Input_Account_Error_Msg;
        sobjecttypeForFrontEnd = sobjectTypeValue;
        //获取所有字段
        List<String> fieldList = new List<String>(Schema.getGlobalDescribe().get('On_Call__c').getDescribe().fields.getMap().keyset());
        // Add fields to controller. This is to avoid the SOQL error in visualforce page
        controller.addFields(fieldList);
        SObject obj = controller.getRecord();
        if(obj.Id != null){
            //更新
            isNewMode = false;
            On_Call__c onCallData = [select Id,AWS_Data_Id__c from On_Call__c where id =: obj.Id];
            AWSDataId = onCallData.AWS_Data_Id__c;
        }else{
            //新建
            rtTypeId = null;
        }
        LayoutDescriberHelper.LayoutWrapper LayoutWrapperValue = LayoutDescriberHelper.describeSectionWithFieldsWrapper(rtTypeId, 'On_Call__c','classic');
        layoutSections = LayoutWrapperValue.layoutSections;
        List<String> requiredFieldAPIList = LayoutWrapperValue.requiredFieldAPIList;
        Map<String,String> fieldAPIToLabelMap = LayoutWrapperValue.fieldAPIToLabelMap;
        requiredFieldAPIListStr = JSON.serialize(requiredFieldAPIList);
        fieldAPIToLabelMapStr = JSON.serialize(fieldAPIToLabelMap);
        PIHelper.PIIntegration piIntegration = PIHelper.getPIIntegrationInfo('On_Call__c');
        staticResource = JSON.serialize(piIntegration);
        encryptedAPIList = piIntegration.PIFields;
        sobjectPrefix = piIntegration.sobjectPrefix;
    }
    global class Response{
        public String recordId{set;get;}
        public String message{set;get;}
        public String status{set;get;}
    }
    @RemoteAction
    global static Response saveOnCall(String onCallJson,String transId,Boolean isNew) {
        System.debug('On_Call__c Info:' + JSON.serialize(onCallJson));
        //1. Prepare the payload for  On_Call__c
        Schema.SObjectType onCallSchema = schemaMap.get(sobjectTypeValue);
        Map<String, Schema.SObjectField> fieldAPIToTypeMap = onCallSchema.getDescribe().fields.getMap();
        Map<String,Object> fieldValueMap = (Map<String,Object>)JSON.deserializeUntyped(onCallJson);
        On_Call__c onCallInfo = new On_Call__c();
        //自定义格式转换
        for (String fieldAPI: fieldValueMap.keySet()) {
            system.debug('field API'+fieldAPI);
            Schema.DisplayType fielddataType = fieldAPIToTypeMap.get(fieldAPI).getDescribe().getType();
            String fieldValue = String.valueOf(fieldValueMap.get(fieldAPI));
            if(String.isBlank(fieldValue)){
                continue;
            }
            if(String.valueOf(fielddataType)=='DATE'){
                onCallInfo.put(fieldAPI, Date.valueOf(String.valueOf(fieldValueMap.get(fieldAPI)).replace('/', '-')));
            }else if(String.valueOf(fielddataType)=='DATETIME'){
                String dt = String.valueOf(fieldValueMap.get(fieldAPI));
                if(String.isNotBlank(dt)&&dt.contains('T')){
                    dt = dt.replace('T',' ');
                    onCallInfo.put(fieldAPI, Datetime.valueOfGmt(dt));
                }
            }else if(String.valueOf(fielddataType)=='Number'||String.valueOf(fielddataType)=='DOUBLE' ){
                onCallInfo.put(fieldAPI, Decimal.valueOf(String.valueOf(fieldValueMap.get(fieldAPI))));
            } else if(String.valueof(fielddataType)=='BOOLEAN'){
                onCallInfo.put(fieldAPI, fieldValueMap.get(fieldAPI));
            }else {
                onCallInfo.put(fieldAPI, String.valueOf(fieldValueMap.get(fieldAPI)));
            }
        }
        //2. Save Record Process
        String status = 'success';
        Response resp = new Response();
        Savepoint sp = Database.setSavepoint();
        String rid = '';
        try{
            System.debug('abcde');
            if(isNew){
                System.debug('onCallInfozhj = ' + onCallInfo);
                insert onCallInfo;
            }else{
                System.debug('into update');
                String awsDataId = (String)onCallInfo.get('AWS_Data_Id__c');
                System.debug('awsDataId = ' + awsDataId);
                On_Call__c[] onCalls = [select id from On_Call__c where AWS_Data_Id__c =:awsDataId];
                System.debug('onCalls[0].id = ' + onCalls[0].id);
                onCallInfo.put('Id',onCalls[0].id);//For testing;
                update onCallInfo;
            }
            rid=onCallInfo.Id;
            PIHelper.saveTransLog(sobjectTypeValue,rid,transId, (String)onCallInfo.get('AWS_Data_Id__c'),onCallJson ,status,'');
            resp.recordId = onCallInfo.Id;
            resp.message = '';
            resp.status = status;
            System.debug('resp from sfdx back-end' + resp);
            return resp;
        } catch(Exception e) {
            System.debug('into catch'+e.getMessage());
            Database.rollback(sp);
            status = 'fail';
            PIHelper.saveTransLog(sobjectTypeValue,rid,transId, (String)onCallInfo.get('AWS_Data_Id__c'),onCallJson,status,e.getMessage());
            resp.message = e.getMessage();
            resp.status = status;
            return resp;
        }
    }
}
force-app/main/default/classes/OnCallController.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/Option.cls
New file
@@ -0,0 +1,5 @@
public class Option {
    @AuraEnabled public string label{get;set;}
    @AuraEnabled public string value{get;set;}
    @AuraEnabled public boolean Selected{get;set;}
}
force-app/main/default/classes/Option.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/PIHelper.cls
New file
@@ -0,0 +1,216 @@
/*
 * Author: Bubba Li
 * Created Date: 01/26/2022
 * Purpose: Utility class for PI
 * Test Class: PIHelper
 * History:
 *      01/26/2022 - Bubba Li - Initial Code.
 *
 * */
global without sharing class PIHelper {
    public static String getObjectKeyPrefix(String objName){
        try{
            schema.sObjectType sObjType = Schema.getGlobalDescribe().get(objName);
            return (sObjType.getDescribe().getKeyPrefix());
        }catch(Exception e){
            system.debug('Exception from get key prefix:'+e.getMessage());
            return '';
        }
    }
    // confirm file transaction
    @future(callout =true)
    public static void confirmFileTrans(String module,Integer isSuccess, String   sfRecordId ,String transId ,String token,String transUrl){
        Boolean result =false;
        Transaction_Log__c traLog = new Transaction_Log__c();
        traLog.Module__c = 'ConfirmFileTransaction '+module;
        traLog.Interface_URL__c = transUrl;
        traLog.TransId__c = transId;
        traLog.SFRecordId__c=sfRecordId;
        try {
            Http http = new Http();
            HttpRequest request = new HttpRequest();
            request.setEndpoint(transUrl);
            request.setMethod('POST');
            TransRequestBody requestBody =new TransRequestBody();
            requestBody.isSuccess=isSuccess;
            requestBody.sfRecordId=sfRecordId;
            requestBody.txId =transId;
            request.setBody(JSON.serialize(requestBody));
            system.debug('request---'+request.tostring());
            HttpResponse response = http.send(request);
            system.debug('token--'+token);
            system.debug('confirm result--'+response.getBody());
            Map<String, Object> results = (Map<String, Object>) JSON.deserializeUntyped(response.getBody());
            result = (Boolean)results.get('success');
            System.debug('result = ' + result);
            traLog.Status__c = 'success';
            traLog.Response__c=response.getBody();
        } catch (Exception e) {
            traLog.Status__c = 'fail';
            traLog.Response__c = e.getMessage();
        }
        insert traLog;
    }
     // confirm tx transaction
     public static void confirmTrans(String module,Integer isSuccess, String   sfRecordId ,String transId ,String token,String transUrl,List<idList> idList){
         Boolean result =false;
         Transaction_Log__c traLog = new Transaction_Log__c();
         traLog.Module__c = 'Confirm Transaction '+module;
         traLog.Interface_URL__c = transUrl;
         traLog.TransId__c = transId;
         if (!String.isEmpty(sfRecordId)) {
            traLog.SFRecordId__c=sfRecordId;
         }else {
            traLog.SFRecordId__c=JSON.serialize(idList);
         }
         try {
             Http http = new Http();
             HttpRequest request = new HttpRequest();
             request.setEndpoint(transUrl);
             request.setMethod('POST');
             TransactionRequestBody requestBody =new TransactionRequestBody();
             requestBody.isSuccess=isSuccess;
             requestBody.sfRecordId=sfRecordId;
             requestBody.idList=idList;
             requestBody.txId =transId;
             request.setBody(JSON.serialize(requestBody));
             system.debug('request---'+request.tostring());
             HttpResponse response = http.send(request);
             system.debug('confirm result--'+response.getBody());
             Map<String, Object> results = (Map<String, Object>) JSON.deserializeUntyped(response.getBody());
             result = (Boolean)results.get('success');
             System.debug('result = ' + result);
             traLog.Status__c = 'success';
             traLog.Response__c=response.getBody();
         } catch (Exception e) {
             traLog.Status__c = 'fail';
             traLog.Response__c = e.getMessage();
         }
         insert traLog;
     }
    // Use this log method
    public static void saveTransLog(String module,String awsDataId,String sfId, String transId,String content,String status,String respMsg){
        Transaction_Log__c traLog = new Transaction_Log__c();
        traLog.AWS_Data_Id__c = awsDataId;
        traLog.SFRecordId__c = sfId;
        traLog.Module__c = 'Upsert SF ' + module;
        traLog.TransId__c = transId;
        traLog.Request__c = content;
        traLog.Status__c = status;
        traLog.Response__c = respMsg;
        traLog.Interface_URL__c = traLog.Module__c;
        insert traLog;
    }
    public static PIIntegration getPIIntegrationInfo(String sobjectType){
        PIIntegration piIntegration = new PIIntegration();
        //查询url
        PI_Policy_Configuration__c config = [select Full_New_URL__c,Full_Search_URL__c,Full_Update_URL__c,Full_Undelete_URL__c,Full_Read_URL__c,Full_Delete_URL__c,Full_View_Unified_Contact_URL__c,TransactionURL__c from PI_Policy_Configuration__c where Sobject_Type__c =: sobjectType];
        System.debug('config = ' + config);
        //获取appid和appsecret
        AWS_Integration_Info__mdt awsConfiguration = [SELECT App_Id__c,Token_URL__c,App_Secret__c,Host_URL__c FROM AWS_Integration_Info__mdt  WHERE DeveloperName = 'AWS_Default_Configuration'];
        if (awsConfiguration == null) {
            System.debug('AWS_Integration_Info__mdt没配置');
            return null;
        }
        String awsAppId = awsConfiguration.App_Id__c;
        String awsAppSecret = awsConfiguration.App_Secret__c;
        System.debug('awsAppId = ' + awsAppId);
        System.debug('awsAppSecret = ' + awsAppSecret);
        System.debug('Host_URL__c = ' + awsConfiguration.Host_URL__c);
        System.debug('Token URL = ' + awsConfiguration.Token_URL__c);
        //获取token
        String token = '';
        try{
            Http http = new Http();
            HttpRequest request = new HttpRequest();
            String url = awsConfiguration.Token_URL__c;
            request.setEndpoint(url);
            request.setMethod('GET');
            HttpResponse response = http.send(request);
            Map<String, Object> results = (Map<String, Object>) JSON.deserializeUntyped(response.getBody());
            token = (String)results.get('object');
            System.debug('token = ' + token);
        }catch(Exception e){
            Transaction_Log__c traLog = new Transaction_Log__c();
            traLog.Module__c = 'Get Token';
            traLog.Status__c = 'fail';
            traLog.Response__c = e.getMessage();
            traLog.Interface_URL__c = awsConfiguration.Token_URL__c;
            insert traLog;
        }
        //Insert Get Token Log
        //获取敏感字段
        piIntegration.PIDetails = [select id,PI_Policy_Configuration__r.Full_New_URL__c, Enable_Encrypt__c, SF_Field_API_Name__c,SF_Field_Encrypted_API__c, AWS_Field_API__c,AWS_Encrypted_Field_API__c,Field_Type__c from PI_Field_Policy_Detail__c  where PI_Policy_Configuration_Name__c =:sobjectType and Enable_Encrypt__c=true];
        List<String> vLookUpFields = new List<String>();
        List<String> PIFields = new List<String>();
        for (PI_Field_Policy_Detail__c PIDetail : piIntegration.PIDetails) {
            if(PIDetail.Field_Type__c == 'Reference'){
                vLookUpFields.add(PIDetail.SF_Field_API_Name__c);
            }
            PIFields.add(PIDetail.SF_Field_API_Name__c);
        }
        System.debug('vLookUpFields = ' + vLookUpFields.toString());
        System.debug('PIFields = ' + PIFields.toString());
        //填充数据
        piIntegration.newUrl = config.Full_New_URL__c;
        piIntegration.updateUrl = config.Full_Update_URL__c;
        piIntegration.queryUrl = config.Full_Read_URL__c;
        piIntegration.deleteUrl = config.Full_Delete_URL__c;
        piIntegration.undeleteUrl = config.Full_Undelete_URL__c;
        piIntegration.viewUnifiedContactUrl = config.Full_View_Unified_Contact_URL__c;
        piIntegration.transactionURL = config.TransactionURL__c;
        piIntegration.hostUrl = awsConfiguration.Host_URL__c;
        piIntegration.searchUrl = config.Full_Search_URL__c;
        piIntegration.token = token;
        piIntegration.awsAppId = awsAppId;
        piIntegration.awsAppSecret = awsAppSecret;
        piIntegration.vLookUpFields = vLookUpFields;
        piIntegration.PIFields = PIFields;
        piIntegration.sobjectPrefix = getObjectKeyPrefix(sobjectType);
        System.debug('piIntegration' + piIntegration);
        return piIntegration;
    }
    global class PIIntegration{
        public String sobjectPrefix{set;get;}
        public String searchUrl{set;get;}
        public String newUrl{set;get;}
        public String updateUrl{set;get;}
        public String queryUrl{set;get;}
        public String deleteUrl{set;get;}
        public String undeleteUrl{set;get;}
        public String viewUnifiedContactUrl{set;get;}
        public String hostUrl{set;get;}
        public String token{set;get;}
        public String awsAppId{set;get;}
        public String awsAppSecret{set;get;}
        public String transactionUrl{set;get;}
        public List<String> vLookUpFields{set;get;}
        public List<String> PIFields{set;get;}
        public List<PI_Field_Policy_Detail__c > PIDetails{set;get;}
    }
    global class TransRequestBody{
        public Integer isSuccess{set;get;}
        public String sfRecordId{set;get;}
        public String txId{set;get;}
    }
    global class TransactionRequestBody{
        public Integer isSuccess{set;get;}
        public String sfRecordId{set;get;}
        public String txId{set;get;}
        public List<idList> idList{set;get;}
    }
    global class idList{
        public String awsId{set;get;}
        public String sfRecordId{set;get;}
    }
}
force-app/main/default/classes/PIHelper.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>52.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/QISPDFController.cls
@@ -2,6 +2,7 @@
    public QIS_Report__c qr { get; private set; }
    public User usr { get; private set; }
    public Boolean inGuarantee { get; private set; }
    public string staticResource { get; private set; }
    
    //  HWAG-BC68W3  故障发生日为空时, 它为真  start
    public Boolean outOfGuarantee { get; private set; }
@@ -10,6 +11,8 @@
        qr = new QIS_Report__c();
        usr = new User();
        inGuarantee = false;
        staticResource = JSON.serialize(PIHelper.getPIIntegrationInfo('QIS_Report__c'));
    }
    
    public void init() {
force-app/main/default/classes/RentalApplyController.cls
New file
@@ -0,0 +1,153 @@
global without sharing class RentalApplyController {
    public List <LayoutDescriberHelper.LayoutSection > layoutSections{set;get;}
    public String awsToken{set;get;}
    public static Map<String, Schema.SObjectType> schemaMap = Schema.getGlobalDescribe();
    public static String sobjectTypeValue = 'Rental_Apply__c';
    public Boolean isNewMode{set;get;}
    public String rtTypeId {get; set;}
    public String AWSDataId{set;get;}
    public List<String> encryptedAPIList{set;get;}
    public String staticResource {get; set;}
    public String staticResourceContact {get; set;}
    public String requiredFieldAPIListStr {get; set;}
    public String fieldAPIToLabelMapStr {get; set;}
    public String Input_Required_Field_Msg{set;get;}
    public String requiredErrorMsg{set;get;}
    public String contactsInfo {set;get;}
    public String contactId{set;get;}
    public String PIPL_Input_Account_Error_Msg{set;get;}
    public RentalApplyController(ApexPages.StandardController controller) {
        isNewMode = true;
        Input_Required_Field_Msg = Label.Input_Required_Field_Msg;
        PIPL_Input_Account_Error_Msg = label.PIPL_Input_Account_Error_Msg;
        //获取所有字段
        List<String> fieldList = new List<String>(Schema.getGlobalDescribe().get('Rental_Apply__c').getDescribe().fields.getMap().keyset());
        controller.addFields(fieldList);
        SObject obj = controller.getRecord();
        if(obj.Id != null){
            //更新
            isNewMode = false;
            Rental_Apply__c rentalApplyData = [select Id,RecordTypeId,AWS_Data_Id__c,Loaner_medical_Staff__c,Loaner_medical_Staff__r.AWS_Data_Id__c from Rental_Apply__c where id =: obj.Id];
            rtTypeId = rentalApplyData.RecordTypeId;
            AWSDataId = rentalApplyData.AWS_Data_Id__c;
            Map<String,String> sfIdToAWSIdMap = new Map<String,String>();
            sfIdToAWSIdMap.put(String.valueof(rentalApplyData.Loaner_medical_Staff__r.Id).subString(0,15),rentalApplyData.Loaner_medical_Staff__r.AWS_Data_Id__c);
            contactsInfo = JSON.serialize(sfIdToAWSIdMap);
        }else{
            //新建
            rtTypeId = ApexPages.currentPage().getParameters().get('RecordType');
        }
        LayoutDescriberHelper.LayoutWrapper LayoutWrapperValue = LayoutDescriberHelper.describeSectionWithFieldsWrapper(rtTypeId, 'Rental_Apply__c','classic');
        layoutSections = LayoutWrapperValue.layoutSections;
        List<String> requiredFieldAPIList = LayoutWrapperValue.requiredFieldAPIList;
        Map<String,String> fieldAPIToLabelMap = LayoutWrapperValue.fieldAPIToLabelMap;
        requiredFieldAPIListStr = JSON.serialize(requiredFieldAPIList);
        fieldAPIToLabelMapStr = JSON.serialize(fieldAPIToLabelMap);
        staticResource = JSON.serialize(PIHelper.getPIIntegrationInfo('Rental_Apply__c'));
        encryptedAPIList = PIHelper.getPIIntegrationInfo('Rental_Apply__c').PIFields;
        staticResourceContact = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));
    }
    global class Response{
        public String recordId{set;get;}
        public String message{set;get;}
        public String status{set;get;}
    }
    @RemoteAction
    global static Response saveRentalApply(String rentalApplyJson,String transId,Boolean isNew) {
        System.debug('Rental_Apply__c Info:' + JSON.serialize(rentalApplyJson));
        //1. Prepare the payload for  Rental_Apply__c
        Schema.SObjectType rentalApplySchema = schemaMap.get(sobjectTypeValue);
        Map<String, Schema.SObjectField> fieldAPIToTypeMap = rentalApplySchema.getDescribe().fields.getMap();
        system.debug(fieldAPIToTypeMap);
        Map<String,Object> fieldValueMap = (Map<String,Object>)JSON.deserializeUntyped(rentalApplyJson);
        Rental_Apply__c rentalApplyInfo = new Rental_Apply__c();
        //自定义格式转换
        for (String fieldAPI: fieldValueMap.keySet()) {
            system.debug('field API='+fieldAPI);
            Schema.DisplayType fielddataType = fieldAPIToTypeMap.get(fieldAPI).getDescribe().getType();
            String fieldValue = String.valueOf(fieldValueMap.get(fieldAPI));
            system.debug('Field Type:'+fielddataType+' field Value='+fieldValue);
            if(String.valueOf(fielddataType)=='DATE'){
                rentalApplyInfo.put(fieldAPI,(String.isBlank(fieldValue)||String.isEmpty(fieldValue))? null:Date.valueOf(fieldValue.replace('/', '-')));
            }else if(String.valueOf(fielddataType)=='DATETIME'){
                if(String.isNotBlank(fieldValue)&&fieldValue.contains('T')){
                    fieldValue = fieldValue.replace('T',' ');
                    rentalApplyInfo.put(fieldAPI, Datetime.valueOfGmt(fieldValue));
                }else{
                    rentalApplyInfo.put(fieldAPI, null);
                }
            }else if(String.valueof(fielddataType)=='CURRENCY'|| String.valueof(fielddataType)=='PERCENT'||String.valueOf(fielddataType)=='Number'||String.valueOf(fielddataType)=='DOUBLE' ){
                rentalApplyInfo.put(fieldAPI, (String.isBlank(fieldValue)||String.isEmpty(fieldValue))?0:Decimal.valueOf(fieldValue));
            } else if(String.valueof(fielddataType)=='BOOLEAN'){
                rentalApplyInfo.put(fieldAPI, fieldValueMap.get(fieldAPI));
            }else {
                rentalApplyInfo.put(fieldAPI,fieldValue);
            }
            // system.debug('field API'+fieldAPI);
            // String fieldValue = String.valueOf(fieldAPIToTypeMap.get(fieldAPI));
            // if(String.isBlank(fieldValue) || String.isEmpty(fieldValue)){
            //     continue;
            // }
            // Schema.DescribeFieldResult fielddataType = fieldAPIToTypeMap.get(fieldAPI).getDescribe();
            // Schema.DisplayType fieldDatas = fielddataType.getType();
            // system.debug('fieldValue='+fieldValue);
            // if(String.valueOf(fielddatas)=='DATE'){
            //     rentalApplyInfo.put(fieldAPI, Date.valueOf(String.valueOf(fieldValueMap.get(fieldAPI)).replace('/', '-')));
            // }else if(String.valueOf(fielddatas)=='DATETIME'){
            //     String dt = String.valueOf(fieldValueMap.get(fieldAPI));
            //     if(String.isNotBlank(dt)&&dt.contains('T')){
            //         dt = dt.replace('T',' ');
            //         rentalApplyInfo.put(fieldAPI, Datetime.valueOfGmt(dt));
            //     }
            // }else if(String.valueOf(fielddatas)=='Number'||String.valueOf(fielddatas)=='DOUBLE'){
            //     system.debug('decimal error:'+ String.valueOf(fieldValueMap.get(fieldAPI)));
            //     rentalApplyInfo.put(fieldAPI, decimal.valueOf(String.valueOf(fieldValueMap.get(fieldAPI))));
            // } else if(String.valueof(fielddatas)=='BOOLEAN'){
            //     rentalApplyInfo.put(fieldAPI, fieldValueMap.get(fieldAPI));
            // }else {
            //     rentalApplyInfo.put(fieldAPI, String.valueOf(fieldValueMap.get(fieldAPI)));
            // }
        }
        //2. Save Record Process
        String status = 'success';
        Response resp = new Response();
        Savepoint sp = Database.setSavepoint();
        String rid = '';
        try{
            System.debug('abcde');
            if(isNew){
                System.debug('rentalApplyInfozhj = ' + rentalApplyInfo);
                insert rentalApplyInfo;
                System.debug('rentalApplyInfo.Id' + rentalApplyInfo.Id);
            }else{
                System.debug('into update');
                String awsDataId = (String)rentalApplyInfo.get('AWS_Data_Id__c');
                System.debug('awsDataId = ' + awsDataId);
                Rental_Apply__c[] RentalApplys = [select id from Rental_Apply__c where AWS_Data_Id__c =:awsDataId];
                System.debug('RentalApplys[0].id = ' + RentalApplys[0].id);
                rentalApplyInfo.put('Id',RentalApplys[0].id);//For testing;
                update rentalApplyInfo;
            }
            rid=rentalApplyInfo.Id;
            // PIHelper.saveTransLog(sobjectTypeValue,transId, (String)rentalApplyInfo.get('AWS_Data_Id__c'),rentalApplyJson ,status,'');
            PIHelper.saveTransLog(sobjectTypeValue,(String)rentalApplyInfo.get('AWS_Data_Id__c'),rid,transId,rentalApplyJson,status,'');
            resp.recordId = rid;
            resp.message = 'success saveRentalApply';
            resp.status = status;
            System.debug('respzhj = ' + resp);
            return resp;
        } catch(Exception e) {
            System.debug('into catch'+e.getMessage());
            Database.rollback(sp);
            status = 'fail';
            // PIHelper.saveTransLog(sobjectTypeValue,transId, (String)rentalApplyInfo.get('AWS_Data_Id__c'),rentalApplyJson,status,e.getMessage());
            PIHelper.saveTransLog(sobjectTypeValue,(String)rentalApplyInfo.get('AWS_Data_Id__c'),rid,transId,rentalApplyJson,status,e.getMessage());
            resp.message = e.getMessage();
            resp.status = status;
            return resp;
        }
    }
}
force-app/main/default/classes/RentalApplyController.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/SLAReportDetailsController.cls
@@ -16,6 +16,8 @@
    public String visitor5;
    public String serviceId;
    public String accId;
    public String slaInfoStr{get; set;}
    public String staticResourceContact {get; set;}
    public SLAReportDetailsController(){
        eventcId = ApexPages.currentPage().getParameters().get('eventCId') == null ? '' : ApexPages.currentPage().getParameters().get('eventCId');
        visitor1 = ApexPages.currentPage().getParameters().get('visitor1') == null ? '' : ApexPages.currentPage().getParameters().get('visitor1');
@@ -111,7 +113,8 @@
        }else{
            slaInfo.Visitor5__c = null; 
        }
        slaInfoStr = JSON.serialize(slaInfo);
        staticResourceContact = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));
    }
    public void save(){
        try {
force-app/main/default/classes/SObjectHelper.cls
New file
@@ -0,0 +1,445 @@
public without sharing class SObjectHelper {
    /**
     * Copy every field values from from_sobj to to_sobj, if the field is in to_sobj and the value is not null
     */
    public static void MergeValue(Sobject to_sobj,Sobject from_sobj)
    {
        CopyTo(to_sobj,from_sobj,true);
    }
    /**
     * Copy every field values from from_sobj to to_sobj
     */
    public static void OverwriteValue(Sobject to_sobj,Sobject from_sobj)
    {
        CopyTo(to_sobj,from_sobj,false);
    }
    static void CopyTo(Sobject to_sobj,Sobject from_sobj, Boolean skip_from_null)
    {
        Map<String, Schema.SObjectField> to_sobj_map = GetFields(to_sobj.getSObjectType().getDescribe().getName());
        Map<String, Schema.SObjectField> from_sobj_map = GetFields(from_sobj.getSObjectType().getDescribe().getName());
        for (string field : from_sobj_map.keySet()) {
            object obj = from_sobj.get(field);
            object obj1 = to_sobj.get(field);
            if (obj != obj1 && to_sobj_map.containsKey(field) && to_sobj_map.get(field).getDescribe().isUpdateable()) {
                if (obj != null || !skip_from_null) {
                    System.debug('obj='+obj);
                    System.debug('obj1='+obj1);
                    to_sobj.put(field, obj);
                }
            }
        }
    }
    private static Map<string,Map<String, Schema.SObjectField>> sobject_field_map = new Map<string,Map<String, Schema.SObjectField>>();
    public static Map<String, Schema.SObjectField> GetFieldMap(string obj_name)
    {
        Map<String, Schema.SObjectField> fm = null;
        if(string.isBlank(obj_name))return fm;
        if(sobject_field_map.containsKey(obj_name))
        {
            fm = sobject_field_map.get(obj_name);
        }
        else
        {
            fm = GetFields(obj_name);
            if (fm != null) {
                sobject_field_map.put(obj_name, fm);
            }
        }
        return fm;
    }
/*
    private static Map<string,Set<string>> sobject_common_fields = new Map<string,Set<string>>();
    // get sobject fields that not be assigned in FieldPermission, they were stardard fields
    public static Set<string> GetCommonFields(string obj_name)
    {
        Set<string> fields = null;
        if(string.isBlank(obj_name))return fields;
        if(sobject_common_fields.containsKey(obj_name))
        {
            fields = sobject_common_fields.get(obj_name);
        }
        else
        {
            Map<String, Schema.SObjectField> all_fields = GetFieldMap(obj_name);
            Id profile_id = UserUtility.GetSysAdminProfileId();
            List<FieldPermissions> lfp = [SELECT Id, ParentId, SobjectType, Field, PermissionsEdit, PermissionsRead, SystemModstamp FROM FieldPermissions
            where parentId in (select id from permissionset where PermissionSet.Profile.Id = :profile_id) and sobjecttype = :obj_name ];
            Set<string> admin_s = new Set<string>();
            for(FieldPermissions fp : lfp)
            {
                if(fp.PermissionsRead)
                {
                    admin_s.add(fp.Field.replace(fp.SobjectType+'.',''));
                }
            }
            // if a field not in admin's permission, the field is a common(standard) field
            for (string f : all_fields.keySet()) {
                if (!admin_s.contains(f) && !f.endsWith('__c')) {
                    if (fields == null) {
                        fields = new Set<string>();
                    }
                    fields.add(f);
                }
            }
            if (fields != null) {
                sobject_common_fields.put(obj_name, fields);
            }
        }
        return fields;
    }
    public static Set<string> GetCurrentProfileAccessableFields(string obj_name)
    {
        return GetProfileAccessableFields(UserInfo.getProfileId(), obj_name);
    }
    private static Map<Id,Map<string,List<FieldPermissions>>> profile_field_permission_buffer = new Map<Id,Map<string,List<FieldPermissions>>>();
    public static Set<string> GetProfileAccessableFields(Id profile_id, string obj_name)
    {
        List<FieldPermissions> lfp = null;
        if(!profile_field_permission_buffer.containsKey(profile_id) || !profile_field_permission_buffer.get(profile_id).containsKey(obj_name)){
            lfp = [SELECT Id, ParentId, SobjectType, Field, PermissionsEdit, PermissionsRead, SystemModstamp FROM FieldPermissions
                                        where parentId in (select id from permissionset where PermissionSet.Profile.Id = :profile_id) and sobjecttype = :obj_name ];
            system.debug(string.format('profile {0} object {1} updated ', new object[]{profile_id,obj_name,lfp.size()}));
            Map<string,List<FieldPermissions>> temp = null;
            if(profile_field_permission_buffer.containsKey(profile_id))
            {
                temp = profile_field_permission_buffer.get(profile_id);
            }
            else{
                temp = new Map<string,List<FieldPermissions>>();
                profile_field_permission_buffer.put(profile_id,temp);
            }
            temp.put(obj_name,lfp);
        }
        else{
            lfp = profile_field_permission_buffer.get(profile_id).get(obj_name);
        }
        Set<string> ls = new Set<string>();
        for(FieldPermissions fp : lfp)
        {
            if(fp.PermissionsRead)
            {
                ls.add(fp.Field.replace(fp.SobjectType+'.',''));
            }
        }
        Set<string> css = GetCommonFields(obj_name);
        if (css != null) {
            ls.addAll(css);
        }
        return ls;
    }*/
    public static Map<string,FieldInfo> GetFieldInfos(string obj_name)
    {
        Map<string,Schema.SObjectField> fields_map = SObjecthelper.GetFieldMap(obj_name);
        if(fields_map == null)
        {
            return null;
        }
        Map<string,FieldInfo> res = new Map<string,FieldInfo>();
        Map<string,FieldInfo> result = new Map<string,FieldInfo>();
        FieldInfo temp = null;
        for(string s : fields_map.keySet())
        {
            Schema.DescribeFieldResult dfr = fields_map.get(s).getDescribe();
            temp = new FieldInfo();
            temp.Name = dfr.getName();
            temp.Label = dfr.getLabel();
            // resolve 'Business Phone' bug
            if(obj_name.toLowerCase() == 'contact' && temp.Name =='Phone' && temp.Label =='Business Phone'){
                temp.Label = 'Phone';
            }
            Schema.DisplayType dt = dfr.getType();
            temp.TypeEnumName = dt.name();
            //temp.DisplayType = dt;
            if((dt == schema.DisplayType.MULTIPICKLIST) || (dt == schema.DisplayType.PICKLIST) )
            {
                temp.Options = new List<Option>();
                List<Schema.PicklistEntry> pick_list_values = dfr.getPickListValues();
                for (Schema.PicklistEntry a : pick_list_values) {
                    if (!a.isActive()) {
                        continue;
                    }
                    Option lv = new Option();
                    lv.label = a.getLabel();
                    lv.value = a.getValue();
                    temp.Options.add(lv);
                }
            }
            if(dt == schema.DisplayType.REFERENCE )
            {
                temp.References = new List<Option>();
                for(Schema.SObjectType reference : dfr.getReferenceTo()) {
                    System.debug('Lookup reference object name: ' + reference.getDescribe().getName());
                    System.debug('Lookup reference object label: ' + reference.getDescribe().getLabel());
                    Option lv = new Option();
                    lv.label = reference.getDescribe().getLabel();
                    lv.value = reference.getDescribe().getName();
                    temp.References.add(lv);
                }
                List<Schema.PicklistEntry> pick_list_values = dfr.getPickListValues();
                for (Schema.PicklistEntry a : pick_list_values) {
                    if (!a.isActive()) {
                        continue;
                    }
                }
            }
            res.put(s,temp);
        }
        return res;
    }
    public static Map<String, Schema.SObjectField> GetFields(Sobject sobj ){
        return GetFields(sobj.getSObjectType().getDescribe().getName());
    }
    public static Map<String, Schema.SObjectField> GetFields(string obj_name )
    {
        Map<String, Schema.SObjectType> mss = Schema.getGlobalDescribe();
        if(mss.containsKey(obj_name)){
            return Transform(mss.get(obj_name).getDescribe().fields.getMap());
        }
        else{
            return null;
        }
    }
    public static Map<String, Schema.FieldSet> GetFieldSets(string obj_name )
    {
        Map<String, Schema.SObjectType> mss = Schema.getGlobalDescribe();
        if(!mss.containsKey(obj_name))return null;
        Map<String, Schema.FieldSet> mssfs = mss.get(obj_name).getDescribe().fieldSets.getMap();
        return mssfs;
    }
    public static Map<String, Schema.FieldSetMember> GetFieldSet(string obj_name,string field_set_name )
    {
        Map<String, Schema.FieldSet> mssfs = GetFieldSets(obj_name);
        if(!mssfs.containsKey(field_set_name))return null;
        Map<String, Schema.FieldSetMember> result = new Map<String, Schema.FieldSetMember>();
        for(Schema.FieldSetMember member : mssfs.get(field_set_name).getFields()){
            Schema.SObjectField ssf = member.getSObjectField();
            result.put(ssf.getDescribe().getName(),member);
        }
        return result;
    }
    static Map<String, Schema.SObjectField> Transform(Map<String, Schema.SObjectField> mssof){
        if(mssof == null)return null;
        Map<String, Schema.SObjectField> result = new Map<String, Schema.SObjectField>();
        for(string key : mssof.keySet()){
            result.put(mssof.get(key).getDescribe().getName(),mssof.get(key));
        }
        return result;
    }
    /*
    static Map<String, Schema.FieldSet> Transform(Map<String, Schema.FieldSet> mssfs){
        if(mssfs == null)return null;
        Map<String, Schema.FieldSet> result = new Map<String, Schema.FieldSet>();
        for(string key : mssfs.keySet()){
            result.put(mssfs.get(key).getName(),mssfs.get(key));
        }
        return result;
    }*/
    public static Map<string,string> GetPicklistLabelValueMap(string objectName, string fieldName){
        List<Schema.PicklistEntry> temp = GetPicklistEntryList(objectName,fieldName);
        if(temp == null)return null;
        Map<string,string> res = new Map<string,string>();
        for(Schema.PicklistEntry pe : temp){
            res.put(pe.getLabel(),pe.getValue());
        }
        return res;
    }
    public static Map<string,string> GetPicklistValueLabelMap(string objectName, string fieldName){
        List<Schema.PicklistEntry> temp = GetPicklistEntryList(objectName,fieldName);
        if(temp == null)return null;
        Map<string,string> res = new Map<string,string>();
        for(Schema.PicklistEntry pe : temp){
            res.put(pe.getValue(),pe.getLabel());
        }
        return res;
    }
    public static List<Schema.PicklistEntry> GetPicklistEntryList(string objectName, string fieldName){
        Map<String,String> picklistMap = new Map<String,String>();
        Schema.SObjectType targetSobjectType = Schema.getGlobalDescribe().get(objectName);
        Schema.DescribeSObjectResult objectDescribe = targetSobjectType.getDescribe();
        Map<String, Schema.SObjectField> fieldMap = objectDescribe.fields.getMap();
        if(!fieldMap.containsKey(fieldName))return null;
        List<Schema.PicklistEntry> picklistEntries = fieldMap.get(fieldName).getDescribe().getPickListValues();
        return picklistEntries;
    }
    public static string GetFieldDescription(string object_name, string field_name){
        if(string.isBlank(object_name) || String.isBlank(field_name))return null;
        // List<FieldDefinition> fd = [Select Label, QualifiedApiName, Description from FieldDefinition Where EntityDefinition.QualifiedApiName=:object_name and QualifiedApiName=:field_name];
        List<FieldDefinition> fds = GetFieldDefinitions(object_name);
        for(FieldDefinition fd : fds)
        {
            if(fd.QualifiedApiName == field_name){
                return fd.Description;
            }
        }
        return null;
    }
    public static List<FieldDefinition> GetFieldDefinitions(string object_name){
        return [Select Label, QualifiedApiName, Description from FieldDefinition Where EntityDefinition.QualifiedApiName=:object_name];
    }
    /*
    public static Schema.FieldSet GetFieldSet(string obj_name,string fieldset_name )
    {
        Map<String, Schema.FieldSet> msf = GetFieldSets(obj_name);
        if(msf.containsKey(fieldset_name))return msf.get(fieldset_name);
        return null;
    }
    public static Schema.FieldSet GetFieldSetByName(string obj_name,string fieldset_name )
    {
        Map<String, Schema.FieldSet> msf = GetFieldSets(obj_name);
        for(string key : msf.keyset())
        {
            if(msf.get(key).getName() == fieldset_name )
            {
                return msf.get(key);
            }
        }
        return null;
    }*/
    /**
     * get sobject field value, support forign field if it was queried
     * e.g. GetSObjectField(lead_obj,'Owner.Name')
     */
    public static object GetSObjectField(object o,string f_str){
        return GetSObjectField((sobject)o,f_str);
    }
    /**
     * get sobject field value, support forign field if it was queried
     * e.g. GetSObjectField(lead_obj,'Owner.Name')
     */
    public static object GetSObjectField(sobject o,string f_str){
        List<string> fields = f_str.split('\\.');
        //system.debug('fields = ' + fields);
        sobject temp = o;
        Object result = null;
        for(integer i =0; i < fields.size();i++){
            if(temp == null) return null;
            if(i==fields.size()-1){
                result = temp.get(fields[i]);
            }
            else{
                temp = temp.getSObject(fields[i]);
            }
            /*
            if(result instanceof SObject){
                temp = (SObject)result;
                continue;
            }
            break;*/
        }
        return result;
    }
    /*
    public static Schema.FieldSet GetFieldSetByLabel(string obj_name,string fieldset_lable )
    {
        Map<String, Schema.FieldSet> msf = GetFieldSets(obj_name);
        for(string key : msf.keyset())
        {
            if(msf.get(key).getLabel() == fieldset_lable )
            {
                return msf.get(key);
            }
        }
        return null;
    }*/
    public static List<string> GetMultiPickListOptions(string val){
        return GetOptions(val);
    }
    public static List<string> GetOptions(string val){
        if(val == null)return new List<string>();
            return ValidMultiPickListValue(val).split(';');
    }
    public static string AppendValueToMultiPickList(string old_val,string val){
        return ValidMultiPickListValue(old_val+';'+val);
    }
    public static string ValidMultiPickListValue( string val ){
        if(string.isBlank(val))return val;
        return ValidMultiPickListValue(val.split(';'));
    }
    public static string ValidMultiPickListValue( List<string> vals ){
        if(vals == null ) vals = new List<string>();
        Set<string> ss = new Set<string>(vals);
        List<string> ls = new List<string>();
        for(string s : ss){
            if(string.isBlank(s)){
                continue;
            }
            ls.add(s);
        }
        return string.join(ls, ';');
    }
}
force-app/main/default/classes/SObjectHelper.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/SearchContactController.cls
New file
@@ -0,0 +1,61 @@
/*
 * Author: Bubba Li
 * Created Date: 02/08/2022
 * Purpose: SearchContactController
 * Test Class: SearchContactController
 * History:
 *      02/08/2022 - Bubba Li - Initial Code.
 *
 * */
public without sharing class SearchContactController {
    public String searchKeyWord{set;get;}
    public String staticResource {get; set;}
    public String contactAWSIds {set;get;}
    public String contactsInfo {set;get;}
    public String PIPL_Search_Contact_Label{set;get;}
    public SearchContactController() {
        String accountId = ApexPages.currentPage().getParameters().get('accountId');
        PIPL_Search_Contact_Label = Label.PIPL_Search_Contact_Label;
        //1. Query Contact by accountId
        List<Contact> conList = new List<Contact>();
        system.debug('Account Id from Front-end:'+accountId);
        if(String.isNotBlank(accountId) && String.isNotEmpty(accountId)){
            conList = new List<Contact>([select Id,AWS_Data_Id__c from Contact where AccountId=:accountId and AWS_Data_Id__c!='']);
        }
        //2. Prepare the Contact Info
        Map<String,Contact> awsIdToContactMap = new Map<String,Contact>();
        List<String> conAWSIds = new List<String>();
        for(Contact con:conList){
            conAWSIds.add(con.AWS_Data_Id__c);
            awsIdToContactMap.put(con.AWS_Data_Id__c,con);
        }
        contactsInfo = JSON.serialize(awsIdToContactMap);
        contactAWSIds = JSON.serialize(conAWSIds);
        staticResource = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));
    }
    @RemoteAction
    public static Response searchContacts(String awsContactIds) {
        Response resp = new Response();
        resp.status = 'fail';
        if(String.isBlank(awsContactIds)||String.isEmpty(awsContactIds)){
            return resp;
        }
        List<String> awsDataIds = (List<String>) JSON.deserialize(awsContactIds, List<String>.class);
        Map<String,Contact> awsIdToContactMapTemp = new Map<String,Contact>();
        List<Contact> conListTemp = new List<Contact>([select Id,AWS_Data_Id__c from Contact where AWS_Data_Id__c in:awsDataIds]);
        for(Contact con:conListTemp){
            awsIdToContactMapTemp.put(con.AWS_Data_Id__c,con);
        }
        if(awsIdToContactMapTemp.keySet().size()>0){
            resp.status = 'success';
            resp.message = JSON.serialize(awsIdToContactMapTemp);
        }
        return resp;
    }
    public class Response{
        public String message{set;get;}
        public String status{set;get;}
    }
}
force-app/main/default/classes/SearchContactController.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>52.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/SearchLeadController.cls
New file
@@ -0,0 +1,53 @@
public without sharing class SearchLeadController {
    public String searchKeyWord{set;get;}
    public String staticResource {get; set;}
    public String leadAWSIds {set;get;}
    public String leadsInfo {set;get;}
    public String PIPL_Search_Contact_Label{set;get;}
    public SearchLeadController() {
        // String accountId = ApexPages.currentPage().getParameters().get('accountId');
        PIPL_Search_Contact_Label = Label.PIPL_Search_Contact_Label;
        //1. Query Contact by accountId
        List<Lead> leadList = new List<Lead>();
        // system.debug('Account Id from Front-end:'+accountId);
        // if(String.isNotBlank(accountId) && String.isNotEmpty(accountId)){
        //     leadList = new List<Lead>([select Id,AWS_Data_Id__c from Lead where AccountId=:accountId and AWS_Data_Id__c!='']);
        // }
        leadList = new List<Lead>([select Id,AWS_Data_Id__c from Lead where AWS_Data_Id__c!='']);
        //2. Prepare the Contact Info
        Map<String,Lead> awsIdToLeadMap = new Map<String,Lead>();
        List<String> leAWSIds = new List<String>();
        for(Lead le:leadList){
            leAWSIds.add(le.AWS_Data_Id__c);
            awsIdToLeadMap.put(le.AWS_Data_Id__c,le);
        }
        leadsInfo = JSON.serialize(awsIdToLeadMap);
        leadAWSIds = JSON.serialize(leAWSIds);
        staticResource = JSON.serialize(PIHelper.getPIIntegrationInfo('Lead'));
    }
    @RemoteAction
    public static Response searchLeads(String awsLeadIds) {
        Response resp = new Response();
        resp.status = 'fail';
        if(String.isBlank(awsLeadIds)||String.isEmpty(awsLeadIds)){
            return resp;
        }
        List<String> awsDataIds = (List<String>) JSON.deserialize(awsLeadIds, List<String>.class);
        Map<String,Lead> awsIdToLeadMapTemp = new Map<String,Lead>();
        List<Lead> leadListTemp = new List<Lead>([select Id,AWS_Data_Id__c from Lead where AWS_Data_Id__c in:awsDataIds]);
        for(Lead le:leadListTemp){
            awsIdToLeadMapTemp.put(le.AWS_Data_Id__c,le);
        }
        if(awsIdToLeadMapTemp.keySet().size()>0){
            resp.status = 'success';
            resp.message = JSON.serialize(awsIdToLeadMapTemp);
        }
        return resp;
    }
    public class Response{
        public String message{set;get;}
        public String status{set;get;}
    }
}
force-app/main/default/classes/SearchLeadController.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>52.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/SearchVisitorController.cls
@@ -5,6 +5,7 @@
    public List<Contact> cl {get;set;}
    public List<AddContactWrapper> acwl {get;set;}
    public String index {get; set;}
    public String awsContactIds{set;get;}//Add By Li Jun 20220214 for PIPL
    public String id1 {get;set;}
    public String hId1 {get;set;}
    public String idVa1 {get;set;}
@@ -24,6 +25,14 @@
    
    public User u {get;set;}
    public Account a {get;set;}
    //Add By Li Jun 20220217 Start
    public String staticResource {get; set;}
    public String contactAWSIds {set;get;}
    public String contactsInfo {set;get;}
    public String awsDataIdArray {set;get;}
    //Add By Li Jun 20220217 End
    
    public SearchVisitorController(){
        this.id1 = Apexpages.currentPage().getParameters().get('id1');
@@ -161,10 +170,40 @@
        }*/
        
        serContact();
        //Add By Li Jun for PIPL 20220217 Start
        //1. Query Contact by accountId
        List<Contact> conList = new List<Contact>();
        system.debug('Account Id from Front-end:'+a.Id);
        String accountId = a.Id;
        if(String.isNotBlank(accountId) && String.isNotEmpty(accountId)){
            conList = new List<Contact>([select Id,AWS_Data_Id__c from Contact where AccountId=:accountId and AWS_Data_Id__c!='']);
        }
        //2. Prepare the Contact Info
        List<String> conAWSIds = new List<String>();
        for(Contact con:conList){
            conAWSIds.add(con.AWS_Data_Id__c);
        }
        contactAWSIds = JSON.serialize(conAWSIds);
        staticResource = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));
        //Add By Li Jun for PIPL 20220217 End
     }
    //Add by Li Jun for PIPL 202202117 Start
    public PageReference clearLineInfoList()  {
        scwl = new List<SltContactWrapper>();
        return null;
    }
    //Add by Li Jun for PIPL 202202117 End
    public PageReference serContact(){
        System.debug('===== serContact start =====');
        System.debug('===== serContact start ====='+awsContactIds);
        //Add By Li Jun for PIPL 20220218 Start
        Set<String> awsContactSet = new Set<String>();
        if(String.isNotBlank(awsContactIds)&&String.isNotEmpty(awsContactIds)){
            List<String> awsDataIds = (List<String>) JSON.deserialize(awsContactIds, List<String>.class);
            awsContactSet = new Set<String>(awsDataIds);
        }
        System.debug('===== serContact start ====='+awsContactSet);
         //Add By Li Jun for PIPL 20220218 End
        String searchHospital = 'Select Hospital__c, Department_Class__c,Is_Active__c From Account Where Id = \'' + vp + '\' ';
        Account a = Database.query(searchHospital);
        if(a.Is_Active__c == '無効'){
@@ -172,16 +211,20 @@
            return null;
        }
        
        String searchSql = 'Select id, name,Ignore_Same_Name__c, Account.Name, Type__c, Doctor_Division1__c, MyDr_Flg__c, phone, Supplement__c, MyDr__c, Select_Flg__c,Delete_Reason__c, Please_Delete__c, Please_Delete_applier__c, FirstName, LastName, Search_LastName__c, Account_Visitor_Search__c  From Contact ';
        String searchSql = 'Select id, name,Ignore_Same_Name__c,AWS_Data_Id__c, Account.Name, Type__c, Doctor_Division1__c, MyDr_Flg__c, phone, Supplement__c, MyDr__c, Select_Flg__c,Delete_Reason__c, Please_Delete__c, Please_Delete_applier__c, FirstName, LastName, Search_LastName__c, Account_Visitor_Search__c  From Contact ';
        String whereStr = 'Where Account.ParentId =\'' + a.Department_Class__c + '\' and Account.Is_Active__c != \'無効\' ' + ' and Isactive__c != \'无效(退休)\' and Isactive__c != \'无效(重复)\'';
        String whereSql = '';
        if(sc.Search_LastName__c != null && sc.Search_LastName__c != ''){
            whereSql += 'and LastName like ' + '\'%' + sc.Search_LastName__c + '%\' ';
        //Commented by Li Jun 20220214 for PIPL
        if(awsContactSet.size()>0){
            whereSql += 'and AWS_Data_Id__c in: awsContactSet ';
        }
        // if(sc.Search_LastName__c != null && sc.Search_LastName__c != ''){
        //     whereSql += 'and LastName like ' + '\'%' + sc.Search_LastName__c + '%\' ';
        // }
        
        if(sc.Search_FirstName__c != null && sc.Search_FirstName__c != ''){
            whereSql += 'and FirstName like ' + '\'%' + sc.Search_FirstName__c + '%\' ';
        }
        // if(sc.Search_FirstName__c != null && sc.Search_FirstName__c != ''){
        //     whereSql += 'and FirstName like ' + '\'%' + sc.Search_FirstName__c + '%\' ';
        // }
        
        if(sc.Type__c != null && sc.Type__c != ''){
            whereSql += 'and Type__c = \'' + sc.Type__c + '\' ';
@@ -202,6 +245,7 @@
        
        System.debug('searchSql:'+searchSql);
        cl = Database.query(searchSql);
        System.debug('Query Result from SF:'+JSON.serialize(cl));
        Integer i = 0;
        
        scwl = new List<SltContactWrapper>();
force-app/main/default/classes/SimpleEventRegisterController.cls
@@ -88,6 +88,12 @@
    //2021-10-20  mzy  任务管理改善   start
    private Boolean IsGeneratePlan;  //是否生成计划
    //2021-10-20  mzy  任务管理改善   end
    //Add By Li Jun 20220224 for PIPL start
    public String idVisitor1PI{set;get;}
    public String idVisitor2PI{set;get;}
    public String staticResource {get; set;}
    public String contactAWSIds{set;get;}
    //Add By Li Jun 20220224 for PIPL end
    public SimpleEventRegisterController(ApexPages.StandardController controller) {
        this.isHospital = true;
        this.isAgent = false;
@@ -153,6 +159,11 @@
            System.debug('-----:inputDatetime=' + inputDatetime);
            this.targetEvent.StartDateTime = inputDatetime;
        }
        //Add by Li Jun 20220303 for PIPL Start
        PIHelper.PIIntegration piIntegration = PIHelper.getPIIntegrationInfo('Contact');
        staticResource = JSON.serialize(piIntegration);
        system.debug('static resource:'+JSON.serialize(staticResource));
        //Add by Li Jun 20220303 for PIPL End
    }
    public void init() {
@@ -212,6 +223,22 @@
            //2021-07-28  mzy  SWAG-C4YB9J 事件页面优化 今天的事件 如果已经生成报告一览,则不允许进行取消和延期操作 end
                allDisable = true;
            }
            //Add By Li Jun for PIPL 20220303 Start
            List<String> conAWSIds = new List<String>();
            Set<String> contactIdsForReport = new Set<String>();
            List<String> visitorList = new List<String>{'Visitor1_ID__c','Visitor2_ID__c','Visitor3_ID__c','Visitor4_ID__c','Visitor5_ID__c'};
            for(String visitorValue:visitorList){
                if(String.isNotEmpty((String)targetEvent.get(visitorValue))&&String.isNotBlank((String)targetEvent.get(visitorValue))){
                    contactIdsForReport.add((String)targetEvent.get(visitorValue));
                }
            }
            List<Contact> conListForReport = new List<Contact>([select id,AWS_Data_Id__c from Contact where id in:contactIdsForReport and AWS_Data_Id__c!='']);
            for(Contact con:conListForReport){
                conAWSIds.add(con.AWS_Data_Id__c);
            }
            contactAWSIds = JSON.serialize(conAWSIds);
            system.debug('Contact AWSIDs:'+contactAWSIds);
            //Add By Li Jun for PIPL 20220303 End
        }
        //20210324 zh WLIG-BX3DQ5 【委托】Outlook日历和SFDC日历同步 end
        if (targetEvent.OPDPlan_Flag__c) {
force-app/main/default/classes/SoqlHelper.cls
New file
@@ -0,0 +1,136 @@
public  class SoqlHelper {
    public static string DistinctQueryFields(string sql)
    {
        string query_fields = sql;
        if (query_fields == null) {
            return null;
        }
        query_fields = query_fields.trim();
        Integer sel_i = query_fields.indexOfIgnoreCase('select ');
        string sel = 'select ';
        if ( sel_i < 0) {
            sel = '';
        }
        string whe = '';
        Integer whe_i = query_fields.indexOfIgnoreCase(' from ');
        if ( whe_i >= 0) {
            whe = query_fields.substring(whe_i);
        }
        string query = query_fields.substring(sel_i < 0 ? 0 : sel.length(), whe_i < 0 ? query_fields.length() : whe_i);
        Set<string> ss = new Set<string>();
        for(string f : query.split(',')){
            string s = f.trim().toLowerCase();
            //System.debug('s='+s);
            ss.add(s);
        }
        return sel + QueryFields(ss) + whe;
    }
    public static string WId(string wid){
        return '\'' + wid + '\'';
    }
    public static string QueryFields(Set<string> lo){
        return QueryFields(new List<string>(lo));
    }
    public static string QueryFields(List<object> lo){
        return string.join(lo, ',');
    }
    public static string ToInCondition(List<AggregateResult> lar ,string key)
    {
        if(lar==null || lar.size() == 0)
        {
            return null;
        }
        string ss = ' ( ';
        boolean b = true;
        for(AggregateResult ar : lar)
        {
            if(ar.get(key)==null)continue;
            if( b )
            {
                b = false;
                ss += '\''+ar.get(key)+'\'';
            }
            else
            {
                ss += ',\''+ar.get(key)+'\'';
            }
        }
        ss+=') ';
        return ss;
    }
    public static string ToInCondition(Set<string> so){
        return ToInCondition(new List<string>(so));
    }
    public static string ToInCondition(List<object> lo)
    {
        Set<object> so = new Set<object>(lo);
        lo = new List<object>(so);
        return '(\''+ string.join(lo, '\',\'')+'\')';
    }
    public static void InsertList(List<Sobject> so_list)
    {
        if(so_list == null || so_list.size() == 0)return;
        insert so_list;
    }
    public static void UpdateList(List<Sobject> so_list)
    {
        if(so_list == null || so_list.size() == 0)return;
        update so_list;
    }
    public static Map<string,Database.UpsertResult> UpsertList(List<Sobject> so_list, Schema.SObjectField field)
    {
        Map<string,Database.UpsertResult> mid = new Map<string,Database.UpsertResult>();
        if(so_list == null || so_list.size() == 0)return mid;
        List<Database.UpsertResult> urList2 = Database.upsert( so_list, field, false);
        Set<String> accBasicRecordIdSet = new Set<String>();
        integer index = 0;
        string errorString = '';
        string field_str = field.getDescribe().getName();
        for(Database.UpsertResult ur : urList2){
            if(!ur.IsSuccess()){
                object fv = so_list[index].get(field_str);
                mid.put(fv+'',ur);
                errorString = '';
                for(Database.Error errs: ur.getErrors()){
                    errorString += errs.getMessage() + ';';
                }
                //LogHelper.CreateRunTimeLog('runtime error', errorString, false, fv+'');
            }
            index++;
        }
        return mid;
    }
    public static void DeleteList(List<Sobject> so_list)
    {
        if(so_list == null || so_list.size() == 0)return;
        delete so_list;
    }
    @future
    public static void DeleteListAsync(List<Id> id_list)
    {
        if(id_list == null || id_list.size() == 0)return;
        Database.delete(id_list);
    }
}
force-app/main/default/classes/SoqlHelper.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/StartTradingController.cls
@@ -1,4 +1,4 @@
public class StartTradingController {
public without sharing class StartTradingController {
    /** リードID */
    public String leadId{get;set;}
@@ -9,12 +9,15 @@
    /** リードOnwer */
    public User leadOnwer{get; set;}
    public String staticResource {get; set;}
    /** コンストラクタ */
    public StartTradingController(ApexPages.StandardController controller){
        // リードID設定
        this.leadId = system.currentPageReference().getParameters().get('leadId');
        System.debug('this.leadId'+this.leadId);
        this.SI_Flg = false;
        staticResource = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));
    }
    
    /** 引合ID */
@@ -66,6 +69,8 @@
    
    /** 販売店から引合をConvertするフラグ **/
    private Boolean isAgencyOpp = false;
    
    /** 初期処理 */
    public void init(){
@@ -143,7 +148,7 @@
    /** 診療科選択リスト変更イベント */
    public void depChange(){
        // 診療科選択値によって、担当者選択リストを入れ替える
        this.conList = this.conMap.get(sltDep);
        this.conList = this.conMap.get(sltDep);
    }
    
    /** キャンセルボタン  **/
@@ -153,6 +158,7 @@
    
    /** 取引の開始ボタン **/
    public PageReference start(){
        system.debug('进入start()');
        
        // LHJ 20181012 CHAN-B5G6EZ 购买意向转询价报错 Start
        try {
force-app/main/default/classes/StartTradingController.cls-meta.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>20.0</apiVersion>
    <apiVersion>26.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/StraightBackAddressController.cls
@@ -9,9 +9,14 @@
    /***************表格数据*********************/
    public List<AddressData> tableData { get; set; }
    public String tableDataStr{ get; set; }
    public String staticResource {get; set;}
    public String staticResourceContact {get; set;}
    public Contact newCon{get; set;}
    /***************底部 编辑和新增的 对象*******************/
    public Address__c insUpdData{get;set;}
    public String insUpdDataStr{get;set;}
    /***************被编辑数据的id********************/
    public String UpdId{get;set;}
@@ -55,6 +60,14 @@
    /***************是否发生数据接口的序号*************/
    public Integer AddressTypeIndex{get;set;}
    public String contactId{set;get;}//For Lookup field
    // Add by Li Jun for PIPL 20220308 Start
    public String contactNameValue{set;get;}
    public String contactIdValue{set;get;}
    public String addressDataIds{set;get;}
    // Add by Li Jun for PIPL 20220308 End
    public StraightBackAddressController() {
        //获取url数据
        RepairId = System.currentPageReference().getParameters().get('id');
@@ -77,6 +90,10 @@
        addContact = new Contact();
        //查询到所有的科室类别
        hospitalTypp = '診療科 その他,診療科 呼吸科,診療科 婦人科,診療科 普外科,診療科 泌尿科,診療科 消化科,診療科 耳鼻喉科,診療科(共通)';
        staticResource = JSON.serialize(PIHelper.getPIIntegrationInfo('Address__c'));
        staticResourceContact = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));
    }
    /**
@@ -86,6 +103,7 @@
        String RepairSql = makeTextRepairSql(RepairId);
        try{
            pc = Database.query(RepairSql);
            system.debug('pc = ' + pc);
            //给一个全局变量赋值医院id
            if(!String.isBlank(pc.HP_ID__c)){
                hospitalId = pc.HP_ID__c;
@@ -126,6 +144,7 @@
            ApexPages.addMessages(e);
        }
        insUpdData = new Address__c();
        newCon = new Contact();
        return null;
    }
@@ -141,6 +160,7 @@
                        insUpdData = tableData[i].address;
                    }
                }
                insUpdDataStr = JSON.serialize(insUpdData);
            }
        }
        return null;
@@ -163,6 +183,7 @@
                        }
                    }
                }
                insUpdDataStr = JSON.serialize(insUpdData);
            }
        }
        return null;
@@ -196,8 +217,12 @@
                        }
                        //联系人
                        String contactsName = '';
                        String contactsNameEncrypt ='';
                        String contactawsDataId = '';
                        if(!String.isBlank(tableData[i].address.Contacts__c)){
                            contactsName = tableData[i].address.Contacts__r.Name;
                            contactsNameEncrypt = tableData[i].address.Contacts__r.LastName_Encrypted__c;
                            contactawsDataId = tableData[i].address.Contacts__r.AWS_Data_Id__c;
                        }
                        //客户
                        String ContactPerson = '';
@@ -208,10 +233,18 @@
                            //保存数据到修理表中
                            Repair__c rc = new Repair__c();
                            rc.id=RepairId;
                            rc.address_Contacts__c=contactsName;
                            rc.Address_AWS_Data_Id__c = tableData[i].address.AWS_Data_Id__c;
                            rc.Contact_AWS_Data_Id__c = contactawsDataId;
                            rc.address_Contacts__c = contactsName;
                            rc.Address_Contacts_Encrypt__c = contactsNameEncrypt;
                            rc.address_ZipCode__c = tableData[i].address.ZipCode__c;
                            rc.Address_ZipCode_Encrypt__c = tableData[i].address.ZipCode_Encrypted__c;
                            rc.address_City__c = cityName;
                            rc.address_Contacts_Name__c = ContactPerson;
                            rc.Detailed_Address__c = tableData[i].address.Detailed_Address__c;
                            rc.Detailed_Address_Encrypt__c = tableData[i].address.Detailed_Address_Encrypted__c;
                            rc.address_Telephone__c = tableData[i].address.Telephone__c;
                            rc.Address_Telephone_Encrypt__c = tableData[i].address.Telephone_Encrypted__c;
                            //isUpload:是否上传SAP  FSEApplyForRepairTime:SAP修理申请时间
                            if(isUpload && (FSEApplyForRepairTime != null)){
                                rc.Address_type__c = 'X';
@@ -343,6 +376,8 @@
                }
            }
            ApexPages.addmessage(new ApexPages.message(ApexPages.severity.INFO, '共有 '+indexCou+' 条数据'));
            tableDataStr = JSON.serialize(tableData);
            system.debug('tableDataStr = ' + tableDataStr);
        }catch(Exception e){
            //失败提示
            ApexPages.addMessages(e);
@@ -354,6 +389,12 @@
     * 保存和修改的方法
     */
    public PageReference save(){
        system.debug('Address value:'+JSON.serialize(insUpdData));
        if(String.isNotBlank(contactIdValue)&&String.isNotEmpty(contactIdValue)){
            system.debug('Contact Value:'+contactIdValue);
            insUpdData.Contacts__c = contactIdValue;
        }
        system.debug('Address value:'+JSON.serialize(insUpdData));
        savepoint sp = Database.setsavepoint();
        if(insUpdData != null){
            boolean flag = true;
@@ -451,7 +492,8 @@
                            monicker = surname.substring(1,surname.length());
                            surname = surname.substring(0,1);
                        }
                        addContact = new Contact(LastName=surname,FirstName=monicker,AccountId=insUpdData.Customer__c,RecordTypeId=typeL);
                        System.debug('newCon = '+newCon);
                        addContact = new Contact(LastName=surname,FirstName=monicker,AccountId=insUpdData.Customer__c,RecordTypeId=typeL,AWS_Data_Id__c = newCon.AWS_Data_Id__c,LastName_Encrypted__c=newCon.LastName_Encrypted__c);
                        try{
                            //新增一条联系人数据
                            insert addContact;
@@ -515,8 +557,8 @@
    }
    //查询地址表数据
    private String makeTextAddressSql(String typeSearchId) {
        String AddressSql = 'SELECT ID,Address_Classification__c,Customer__c,Customer__r.Name,Contacts__c,Contacts__r.Name,Telephone__c'
                        +',Province__c,Province__r.Name,City__c,City__r.name,Detailed_Address__c,Create_Contacts__c,ZipCode__c,CreatedByid '
        String AddressSql = 'SELECT AWS_Data_Id__c,ID,Address_Classification__c,Customer__c,Customer__r.Name,Contacts__c,Contacts__r.Name,Contacts__r.AWS_Data_Id__c,Telephone__c'
                        +',Province__c,Province__r.Name,City__c,City__r.name,Detailed_Address__c,Create_Contacts__c,ZipCode__c,CreatedByid,Detailed_Address_Encrypted__c,Telephone_Encrypted__c,ZipCode_Encrypted__c,Contacts__r.LastName_Encrypted__c'
                        + ' FROM Address__c where id != null';
        //类型筛选
        if(!String.isBlank(typeText)){
@@ -542,8 +584,11 @@
            AddressSql += ' and Customer__r.Name LIKE \'%' + txtName.trim() + '%\'' ;
        }
        //详细地址筛选
        if(!String.isBlank(txtAddress)){
            AddressSql += ' and Detailed_Address__c LIKE \'%' + txtAddress.trim() + '%\'' ;
        // if(!String.isBlank(txtAddress)){
        //     AddressSql += ' and Detailed_Address__c LIKE \'%' + txtAddress.trim() + '%\'' ;
        // }
        if(!String.isBlank(addressDataIds)){
            AddressSql += ' and AWS_Data_Id__c in('+addressDataIds.trim()+')';
        }
        //排序,根据上次修改时间和采用时间进行降序排序,值为空放到后面
        AddressSql += ' order by LastModifiedDate desc,Using_Datetime__c desc NULLS LAST';
@@ -551,6 +596,7 @@
        if(String.isBlank(typeSearchId)){
            AddressSql += ' limit 1000 ';
        }
        System.debug('AddressSql = '+AddressSql);
        return AddressSql;
    }
    //查询医院客户人员信息
force-app/main/default/classes/TestClass.cls
New file
@@ -0,0 +1,41 @@
public without sharing class TestClass
{
    public static List<Metadata.LayoutSection> GetLayoutSections(string object_name, string layout_name){
        List<String> componentNameList = new List<String>{object_name+'-'+layout_name};
        //通过Metadata.Operations.retrieve获取metadata
        //Metadata.Layout -> Metadata.LayoutSection -> Metadata.LayoutColumn objects -> Metadata.LayoutItem objects
        List<Metadata.Metadata> componentList = Metadata.Operations.retrieve(Metadata.MetadataType.Layout, componentNameList);
        if(componentList?.size() > 0){
            Metadata.Layout layout = (Metadata.Layout) componentList.get(0);
            List<Metadata.LayoutSection> layoutSectionList = layout.layoutSections;
            return layoutSectionList;
        }
        else{
            return null;
        }
    }
    public static void Foo(){
        string query = 'SELECT Layout.Name, Layout.TableEnumOrId, ProfileId, Profile.Name, RecordTypeId FROM ProfileLayout where recordtypeid=\'01210000000QfWdAAK\'';
        String baseURL = URL.getSalesforceBaseUrl().toExternalForm()+'/services/data/v41.0/tooling/query?q='+ query.replace(' ', '+');
        HttpResponse resp = null;
        HttpRequest req = new HttpRequest();
        req.setMethod('GET');
        req.setHeader('Authorization', 'Bearer ' + UserInfo.getsessionid());
        req.setEndpoint(baseURL);
        Http client = new Http();
        resp = client.send(req);
        Map<string,object> mso = (Map<string,object>)JSON.deserializeUntyped(resp.getBody());
        for(string key : mso.keySet()){
            system.debug('key='+key);
            system.debug(mso.get(key));
        }
        mso = (Map<string,object>)(((List<object>)mso.get('records'))[0]);
        for(string key : mso.keySet()){
            system.debug('key='+key);
            system.debug(mso.get(key));
        }
    }
}
force-app/main/default/classes/TestClass.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>52.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/TestController.cls
New file
@@ -0,0 +1,15 @@
public without sharing class TestController extends NewAndEditBaseController
{
    public TestController(ApexPages.StandardController controller) {
        List<String> fieldList = new List<String>(Schema.getGlobalDescribe().get('Inquiry_form__c').getDescribe().fields.getMap().keyset());
        // Add fields to controller. This is to avoid the SOQL error in visualforce page
        controller.addFields(fieldList);
        LookUpOverrideFields.add('Contact_Name__c');
        //添加项
        Init(controller.getRecord());
        system.debug(LookUpOverrideFieldsMapJson);
    }
}
force-app/main/default/classes/TestController.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>52.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/UpdateContractAimAmountHandler.cls
@@ -246,7 +246,12 @@
            }
    
        }
        if(!System.Test.isRunningTest()){
        //Before :
        //if(!System.Test.isRunningTest()){
        //After : to avoid mutiple execute
        //if(!(System.Test.isRunningTest()||System.isFuture()||System.isBatch())){
        //Update by Li Jun for PIPL 20220304
        if(!(System.Test.isRunningTest()||System.isFuture()||System.isBatch())){
            if (queueableAccountIdList.size() > 0) {
                NFM601Controller.callout('', queueableAccountIdList);
force-app/main/default/classes/ViewParticipantsController.cls
New file
@@ -0,0 +1,6 @@
global class ViewParticipantsController {
    public String staticResourceContact {get; set;}
    public ViewParticipantsController(ApexPages.StandardController controller) {
        staticResourceContact = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));
    }
}
force-app/main/default/classes/ViewParticipantsController.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>52.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/WeeklyReportCmp.cls
@@ -4,10 +4,45 @@
    @AuraEnabled public Map<String,String> fieldsMap{get;set;}
    @AuraEnabled public Map<String,List<Map<String,String>>> docmap{get;set;}
    @AuraEnabled public List<Map<String,String>> doctorList{get;set;}
    // PIPL update Yin Mingjie 21/02/2022 start
    @AuraEnabled public Map<String,String> awsurl{get;set;}
    // PIPL update Yin Mingjie 21/02/2022 end
    public WeeklyReportCmp() {
    }
    // PIPL update Yin Mingjie 21/02/2022 start
    @RemoteAction
    @AuraEnabled
    public static Map<String,String> getAwsurl(String sobj){
        PIHelper.PIIntegration piIntegration = PIHelper.getPIIntegrationInfo(sobj);
        Map<String,String> awsmap = new Map<String,String>();
        awsmap.put('token', piIntegration.token);
        awsmap.put('newUrl', piIntegration.newUrl);
        awsmap.put('searchUrl', piIntegration.searchUrl);
        awsmap.put('transactionURL', piIntegration.transactionURL);
        return awsmap;
    }
    @RemoteAction
    @AuraEnabled
    public static Map<String, String> saveAgencyContact(String name, String nameEncrypt, String type, String typeEncrypt, String doctorDivision1,
        String doctorDivision1Encrypt, String agencyHospitalid, String awsid) {
        Agency_Contact__c agency_contact = new Agency_Contact__c();
        agency_contact.Name = name;
        agency_contact.Name_Encrypted__c = nameEncrypt;
        agency_contact.Type__c = type;
        agency_contact.Type_Encrypted__c = typeEncrypt;
        agency_contact.Doctor_Division1__c = doctorDivision1;
        agency_contact.Doctor_Division1_Encrypted__c = doctorDivision1Encrypt;
        agency_contact.Agency_Hospital__c = agencyHospitalid;
        agency_contact.AWS_Data_Id__c = awsid;
        Map<String, String> acMap = new Map<String, String>();
        acMap = LightningUtil.insertAgencyContact(agency_contact);
        return acMap;
    }
    // PIPL update Yin Mingjie 21/02/2022 end
    @RemoteAction
    @AuraEnabled
    public static List<Map<String,String>> getProductList(String dc, String opdsis){
@@ -112,6 +147,8 @@
        
        //System.debug('fieldsMap is ' + fieldsMap);
        //System.debug('allselectlist is ' + this.allselectlist);
        this.awsurl = getAwsurl('Agency_Contact__c');// 20220222 PI改造 by Bright
    }
    
    
@@ -218,6 +255,9 @@
    
    @RemoteAction
    @AuraEnabled
    // PIPL update Yin Mingjie 21/02/2022 start
    public static Map<String,Map<String,String>> getDoctorList(String hospital_id){
    /*
    public static List<Map<String,String>> getDoctorList(String hospital_id){
        List<Map<String,String>> ret = new List<Map<String,String>>();
        Map<String,String> space = new Map<String,String>();
@@ -225,14 +265,18 @@
        space.put('value', '');
        space.put('selected', 'true');
        ret.add(space);
    */
    // PIPL update Yin Mingjie 21/02/2022 end
        // 戦略科室IDを取得して、それをもとに顧客をSELECT
        Agency_Hospital_Link__c ahl = [select Hospital__c from Agency_Hospital_Link__c where id = :hospital_id];
        // PIPL update Yin Mingjie 21/02/2022 start
        /*
        List<Agency_Contact__c> doctor_list = [select id,Name,Doctor_Division1__c,Type__c,Agency_Hospital__c 
            FROM Agency_Contact__c WHERE Hospital_ID18__c=:ahl.Hospital__c order by Name];
        for (Agency_Contact__c row : doctor_list)
        {
            Map<String,String> tmp = new Map<String,String>();
@@ -242,8 +286,32 @@
            tmp.put('Doctor_Division1__c', row.Doctor_Division1__c);
            ret.add(tmp);
        }
        */
        List<Agency_Contact__c> doctor_list = [select id,Name,AWS_Data_Id__c,Doctor_Division1__c,Type__c,Agency_Hospital__c
            FROM Agency_Contact__c WHERE Hospital_ID18__c=:ahl.Hospital__c order by Name];
        Map<String,Map<String,String>> ret_test = new Map<String,Map<String,String>>();
        for (Agency_Contact__c row : doctor_list)
        {
            if(row.AWS_Data_Id__c == '' || row.AWS_Data_Id__c == null){
                continue;
            }
            Map<String,String> tmp = new Map<String,String>();
            tmp.put('label', row.Name);
            tmp.put('value', row.Id);
            tmp.put('awsid', row.AWS_Data_Id__c);
            tmp.put('selected', 'false');
            tmp.put('Doctor_Division1__c', row.Doctor_Division1__c);
            ret_test.put(row.AWS_Data_Id__c, tmp);
        }
        PIHelper.PIIntegration piIntegration = PIHelper.getPIIntegrationInfo('Agency_Contact__c');
        Map<String, String> sre = new Map<String, String>();
        sre.put('token', piIntegration.token);
        sre.put('searchUrl', piIntegration.searchUrl);
        ret_test.put('sre', sre);
        
        return ret_test;
        // PIPL update Yin Mingjie 21/02/2022 end
        /*
        String record_type_id = LightningUtil.getRecordTypeId(department);
@@ -260,9 +328,13 @@
        }
        */
        // PIPL update Yin Mingjie 21/02/2022 start
        /*
        return ret;
        */
        // PIPL update Yin Mingjie 21/02/2022 end
    }
    /*
    @RemoteAction
    @AuraEnabled
@@ -408,8 +480,8 @@
        if (doctor != '') { agency_report.doctor2__c = doctor; } else { agency_report.doctor2__c = null; }
        if (Department_Cateogy != '') { agency_report.Department_Cateogy__c = Department_Cateogy; } else { agency_report.Department_Cateogy__c = null; }
        if (Purpose_Type != '') { agency_report.Purpose_Type__c = Purpose_Type; } else { agency_report.Purpose_Type__c = null; }
        //SWAG-CBX68C fy 【委托】DAMS系统周报模块内容需求增加 start SupportNeeds__c
        if (SupportNeedsc != '') { agency_report.SupportNeeds__c = SupportNeedsc; } else { agency_report.SupportNeeds__c = null; }
         //SWAG-CBX68C fy 【委托】DAMS系统周报模块内容需求增加 start SupportNeeds__c
         if (SupportNeedsc != '') { agency_report.SupportNeeds__c = SupportNeedsc; } else { agency_report.SupportNeeds__c = null; }
        if (Agency_Hospital != '') { agency_report.Agency_Hospital__c = Agency_Hospital; } else { agency_report.Agency_Hospital__c = null; }
        if (Product_Category1 != '') { agency_report.Product_Category1__c = Product_Category1; } else { agency_report.Product_Category1__c = null; }
        if (Product_Category2 != '') { agency_report.Product_Category2__c = Product_Category2; } else { agency_report.Product_Category2__c = null; }
@@ -516,10 +588,10 @@
       System.debug('sobjectName:::'+sobjectName);
       System.debug('fields:::'+fields);
       String errorMag = '';
       // 创建周报
       try{
            if(fileData!=null){ 
                String[] fileLines = new String[]{};
                fileLines = fileData.split('\n');
@@ -554,23 +626,23 @@
                            errorMag += 'error1 第'+i+'行数据活动日不能为空';
                            errorMag += '=';
                        }
                        //SWAG-C7AASP 【委托】DAMS系统周报补录时间调整  2022-1-10 pk start
                        List<String> R = new List<String>();
                        R = inputvalues[1].split('/');
                        system.debug('R202216'+R);
                        Date rDate = Date.newInstance(Integer.Valueof(R[0]),Integer.Valueof(R[1]),Integer.Valueof(R[2]));
                        system.debug('rDate202216'+rDate);
                        Date start = Date.today().addMonths(-1);
                        Date startDay = start.toStartOfWeek();
                        Date firstDayOfweek = System.today().toStartOfWeek();
                        Date endDay = firstDayOfweek.addDays(6);
                        if(rDate > endDay || rDate < startDay){
                            system.debug('rDate >= ssDate');
                            // return 'error1 第'+i+'行数据活动日不能为空';
                            errorMag += 'error1 第'+i+'行数据,导入周报仅可补报最近一月周报';
                            errorMag += '=';
                        }
                        //SWAG-C7AASP 【委托】DAMS系统周报补录时间调整  2022-1-10 pk end
                         //SWAG-C7AASP 【委托】DAMS系统周报补录时间调整  2022-1-10 pk start
                         List<String> R = new List<String>();
                         R = inputvalues[1].split('/');
                         system.debug('R202216'+R);
                         Date rDate = Date.newInstance(Integer.Valueof(R[0]),Integer.Valueof(R[1]),Integer.Valueof(R[2]));
                         system.debug('rDate202216'+rDate);
                         Date start = Date.today().addMonths(-1);
                         Date startDay = start.toStartOfWeek();
                         Date firstDayOfweek = System.today().toStartOfWeek();
                         Date endDay = firstDayOfweek.addDays(6);
                         if(rDate > endDay || rDate < startDay){
                             system.debug('rDate >= ssDate');
                             // return 'error1 第'+i+'行数据活动日不能为空';
                             errorMag += 'error1 第'+i+'行数据,导入周报仅可补报最近一月周报';
                             errorMag += '=';
                         }
                         //SWAG-C7AASP 【委托】DAMS系统周报补录时间调整  2022-1-10 pk end
                        if(inputvalues[2] == '' || inputvalues[2] == null){
                            // return 'error1 第'+i+'行数据医院不能为空';
                            errorMag += 'error1 第'+i+'行数据医院不能为空';
@@ -603,7 +675,7 @@
                            errorMag += '=';
                        }
                        if((inputvalues[7] != '' && inputvalues[7] != null)&& inputvalues[5] == inputvalues[7]){
                            // return 'error1 第'+i+'行数据产品区分1和产品区分3的值不能重复';
                            errorMag += 'error1 第'+i+'行数据产品区分1和产品区分3的值不能重复';
@@ -642,7 +714,7 @@
                            errorMag += 'error3 第'+i+'行数据结果选项列表的值'+inputvalues[9]+'不存在';
                            errorMag += '=';
                        }
                        system.debug('inputvalues[0]=================>'+inputvalues[0]);
                       system.debug('inputvalues[0]=================>'+inputvalues[0]);
                        system.debug('inputvalues[1]=================>'+inputvalues[1]);
                        system.debug('inputvalues[2]=================>'+inputvalues[2]);
                        system.debug('inputvalues[3]=================>'+inputvalues[3]);
@@ -652,7 +724,7 @@
                        system.debug('inputvalues[7]=================>'+inputvalues[7]);
                        system.debug('inputvalues[8]=================>'+inputvalues[8]);
                        system.debug('inputvalues[9]=================>'+inputvalues[9]);
                        nameList.add(inputvalues[0]);
                        dateList.add(Date.valueOf(inputvalues[1].replace('/','-')));
force-app/main/default/classes/XinDailyReportController.cls
@@ -78,7 +78,14 @@
    public String repoErrorMessage{get;set;}
    public String idParam{get;set;}
    public Integer activitiesSize {get;set;}
    //Add By Li Jun 20220224 for PIPL start
    public String idVisitor1PI{set;get;}
    public String idVisitor2PI{set;get;}
    public String idVisitor3PI{set;get;}
    public String idVisitor4PI{set;get;}
    public String idVisitor5PI{set;get;}
    public String staticResource {get; set;}
    //Add By Li Jun 20220224 for PIPL end
//*************************Create 20160630 OCM-231 趙徳芳 Start*************************//
    public String completionFlg{get;set;}
    public Daily_Report__c reportBak {get;set;}
@@ -91,8 +98,14 @@
    public String etAPPMsg1 {get;set;} // 20210603 zh ETAPP与日报联动
    public String etAPPMsg2 {get;set;} // 20210603 zh ETAPP与日报联动
    public String etAPPFlg {get;set;} // 20210603 zh ETAPP与日报联动
    //Add By Li Jun for PIPL 20220225
    public String contactAWSIds{set;get;}
    public String acSize{set;get;}
    /** コンストラクタ */
    public XinDailyReportController() {
        PIHelper.PIIntegration piIntegration = PIHelper.getPIIntegrationInfo('Contact');
        staticResource = JSON.serialize(piIntegration);
        system.debug('static resource:'+JSON.serialize(staticResource));
        EsetId = ApexPages.currentPage().getParameters().get('id');
        completionFlg =  ApexPages.currentPage().getParameters().get('completion');
        eventFlg = ApexPages.currentPage().getParameters().get('event');
@@ -113,6 +126,9 @@
    /** コンストラクタ */
    public XinDailyReportController(ApexPages.StandardController controller) {
        PIHelper.PIIntegration piIntegration = PIHelper.getPIIntegrationInfo('Contact');
        staticResource = JSON.serialize(piIntegration);
        system.debug('static resource:'+JSON.serialize(staticResource));
        EsetId = ApexPages.currentPage().getParameters().get('id');
        completionFlg =  ApexPages.currentPage().getParameters().get('completion');
        eventFlg = ApexPages.currentPage().getParameters().get('event');
@@ -469,6 +485,35 @@
            managerCommentEditFlg = false;
        }
        reportBak = report;
        //Add By Li Jun for PIPL 20220225 Start
        List<String> conAWSIds = new List<String>();
        Set<String> contactIdsForReport = new Set<String>();
        for(Activity a:activities){
            if(String.isNotEmpty(a.act.Visitor1_ID__c)&&String.isNotBlank(a.act.Visitor1_ID__c)){
                contactIdsForReport.add(a.act.Visitor1_ID__c);
            }
            if(String.isNotEmpty(a.act.Visitor2_ID__c)&&String.isNotBlank(a.act.Visitor2_ID__c)){
                contactIdsForReport.add(a.act.Visitor2_ID__c);
            }
            if(String.isNotEmpty(a.act.Visitor3_ID__c)&&String.isNotBlank(a.act.Visitor3_ID__c)){
                contactIdsForReport.add(a.act.Visitor3_ID__c);
            }
            if(String.isNotEmpty(a.act.Visitor4_ID__c)&&String.isNotBlank(a.act.Visitor4_ID__c)){
                contactIdsForReport.add(a.act.Visitor4_ID__c);
            }
            if(String.isNotEmpty(a.act.Visitor5_ID__c)&&String.isNotBlank(a.act.Visitor5_ID__c)){
                contactIdsForReport.add(a.act.Visitor5_ID__c);
            }
            system.debug('Activity:'+JSON.serialize(a.act.Visitor1_ID__c));
        }
        List<Contact> conListForReport = new List<Contact>([select id,AWS_Data_Id__c from Contact where id in:contactIdsForReport and AWS_Data_Id__c!='']);
        for(Contact con:conListForReport){
            conAWSIds.add(con.AWS_Data_Id__c);
        }
        contactAWSIds = JSON.serialize(conAWSIds);
        system.debug('Contact AWSIDs:'+contactAWSIds);
        //Add By Li Jun for PIPL 20220225 End
        return null;
    }
    
@@ -3549,7 +3594,7 @@
            if(insertCancelPostponePlan.size() > 0){
                insert insertCancelPostponePlan;
            }
        }catch(Exception ex){
            logstr += '\n' + ex.getMessage();
            //2022-02-07  mzy 日志修改  start            
force-app/main/default/pages/AssessmentReport.page
@@ -4,6 +4,62 @@
    <apex:includeScript value="{!URLFOR($Resource.PleaseWaitDialog)}"/>
    <apex:includeScript value="/soap/ajax/29.0/connection.js"/>
    <apex:includeScript value="/soap/ajax/29.0/apex.js"/>
    <apex:includeScript value="{!URLFOR($Resource.AWSService, 'AWSService.js') }" />
    <script>
        var aws = JSON.parse('{!awsString}');
        var staticResources = JSON.parse('{!staticResource}');
        var contactAwsDataIds = [];
        var contact = {};
        queryContact();
        function preparePayloadForSearchContact(){
            let searchPayload = new Object();
            searchPayload.dataIds = contactAwsDataIds;
            searchPayload.contactName = '';
            return JSON.stringify(searchPayload);
        }
        function queryContact(){
            for(var i = 0;i<aws.length;i++){
                contactAwsDataIds.push(aws[i].CamMem.Contact_ID__r.AWS_Data_Id__c);
            }
            let data = preparePayloadForSearchContact();
            let searchCallBack = function searchCallBack(result){
                console.log(result);
                let contacts = result.object;
                if(contacts == null){
                    return;
                }
                for(var i=0;i<contacts.length;i++){
                    contact[contacts[i].dataId] = contacts[i].lastName.replace(/"/g,"");
                }
                console.log(JSON.stringify(contact));
            };
            AWSService.search(staticResources.searchUrl,data,searchCallBack,staticResources.token);
        }
        function showPIDiv(awsDataId){
            console.log('awsDataId Value:'+awsDataId);
            let parentNode = document.getElementById(awsDataId);
            let createDiv = document.createElement("div");
            createDiv.id = awsDataId+"_PI";
            let piInformation = 'Name:'+contact[awsDataId]
            //let piInformation = 'Name:'+contact['943114607025717249'].lastName +'\n' +'Phone:'+contact['943114607025717249'].phone
            createDiv.innerText = piInformation;
            let x=window.event.x;
            let y=window.event.y;
            createDiv.style.left=x;
            createDiv.style.top=y;
            createDiv.style.background="#dddddd";
            createDiv.style.position = "absolute";
            parentNode.appendChild(createDiv);
        }
        function hidePIDiv(awsDataId){
            document.getElementById(awsDataId+'_PI').remove();
        }
    </script>
    <apex:form id="allForm">
@@ -86,8 +142,10 @@
                            <apex:column style="width: 18%">
                               <apex:outputField style="resize:vertical;width: 95%" id="Department" value="{!al.CamMem.Department_ID__c}"/>
                            </apex:column>
                            <apex:column style="width: 8%">
                               <apex:outputField style="resize:vertical;width: 95%" id="Name" value="{!al.CamMem.Contact_ID__c}"/>
                            <!-- id="{!al.CamMem.Contact_ID__r.AWS_Data_Id__c}" onmouseover="showPIDiv('{!al.CamMem.Contact_ID__r.AWS_Data_Id__c}')" onmouseout="hidePIDiv('{!al.CamMem.Contact_ID__r.AWS_Data_Id__c}')" -->
                            <apex:column style="width: 8%" >
                               <!-- <apex:outputField style="resize:vertical;width: 95%" id="Name" value="{!al.CamMem.Contact_ID__c}" /> -->
                               <span id="{!al.CamMem.Contact_ID__r.AWS_Data_Id__c}" onmouseover="showPIDiv('{!al.CamMem.Contact_ID__r.AWS_Data_Id__c}')" onmouseout="hidePIDiv('{!al.CamMem.Contact_ID__r.AWS_Data_Id__c}')">{!al.ARS.Name}</span>
                            </apex:column>
                            <apex:column style="width: 14%">
                               <apex:outputText style="resize:vertical;width: 95%" id="dept" value="{!al.CamMem.dept__c}"/>
force-app/main/default/pages/BMEWorkPage.page
@@ -5,6 +5,12 @@
<apex:includeScript value="{!URLFOR($Resource.jquery183minjs)}"/>
<apex:includeScript value="{!URLFOR($Resource.PleaseWaitDialog)}"/>
<apex:includeScript value="{!URLFOR($Resource.BmeWorkJs)}"/>
<!-- 20220222 PI改造 by Bright--start -->
<apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
<script src="../../soap/ajax/53.0/connection.js" type="text/javascript"></script>
<!-- 20220222 PI改造 by Bright--end -->
<style>
    td .dateFormat  {
        display: none;
@@ -83,6 +89,11 @@
}
body .pbBody table.list tr.headerRow td.col_Scroll {width:0px; padding:0px; border-width:0px;}
body .pbBody table.list tr.dataRow td.col_Scroll {width:0px; padding:0px; border-width:0px;}
.decrypt{position: absolute;top: 0;left: 100%;display: none;text-align: left;
    padding-left: 5px;}
a:hover .decrypt{display: block;width: 100px}
</style>
<script type="text/javascript">
var heightAjustment = 120;
@@ -96,14 +107,14 @@
</script>
</head>
    <apex:form id="allForm">
        <apex:actionFunction name="saveAndSearch" action="{!save}" rerender="allPanel" oncomplete="unblockUI();">
        <apex:actionFunction name="saveAndSearch" action="{!save}" rerender="allPanel" oncomplete="afterSaveAndSearch();">
             <apex:param name="firstParam" assignTo="{!saveType}" value="" />
        </apex:actionFunction>
         <apex:actionFunction name="saveAndSort" action="{!save}" rerender="allPanel" oncomplete="unblockUI();">
            <apex:param name="firstParam" assignTo="{!saveType}" value="" />
            <apex:param name="secondParam" assignTo="{!sortKey}" value="" />
        </apex:actionFunction>
        <apex:actionFunction name="searchOpp" action="{!chick}" rerender="allPanel" oncomplete="unblockUI();"/>
        <apex:actionFunction name="searchOpp" action="{!chick}" rerender="allPanel" oncomplete="afterSearchOpp();"/>
        <apex:actionFunction name="sortTable" action="{!sortTable}" rerender="allPanel" oncomplete="unblockUI();">
            <apex:param name="firstParam" assignTo="{!sortKey}" value="" />
        </apex:actionFunction>
@@ -113,7 +124,7 @@
                    <tr>
                        <td width="150px">
                            <apex:commandButton onclick="blockme()" oncomplete="unblockUI();" action="{!save}" value="保存"  style="height:30px;width:50px;"/>&nbsp;&nbsp;
                            <apex:commandButton value="检索" onclick="searchOppJs_Account_copy();return false;" style="height:30px;width:70px;"/>
                            <apex:commandButton value="检索" onclick="NewSearch();return false;" style="height:30px;width:70px;"/>
                        </td>
                        <td width="1000px">
                            <apex:pageMessages />
@@ -149,10 +160,11 @@
                            <apex:selectList value="{!numtextC1}" size="1" style="width:110px"><apex:selectOptions value="{!textOpts02}"/></apex:selectList>
                        </td>
                        <td width="130px">  
                            <apex:selectList value="{!numtextC2}" size="1" style="width:110px"><apex:selectOptions value="{!equalOpts}"/></apex:selectList>
                            <apex:selectList value="{!numtextC2}" size="1" style="width:110px"><apex:selectOptions value="{!equalOpts2}"/></apex:selectList>
                        </td>
                         <td width="200px">
                          <apex:inputText style="width:150px" value="{!numtextC}"/>
                          <apex:inputHidden id="AwsDataIds" value="{!AwsDataIds}"/>
                          <apex:inputText id="numtextC" style="width:150px" value="{!numtextC}"/>
                        </td>
                        <td width="200px">
                            <font>数&nbsp;据&nbsp;字&nbsp;段&nbsp;</font>&nbsp;
@@ -165,7 +177,7 @@
                          <apex:inputText style="width:150px" value="{!numtextD}"/>
                        </td>
                        <td width="230px">显示&nbsp;
                          <apex:selectList value="{!limits}" size="1" onchange="searchOppJs_Account_copy();return false;">
                          <apex:selectList value="{!limits}" size="1" onchange="NewSearch();return false;">
                          <apex:selectOptions value="{!limitOpts}"/></apex:selectList> 条数据
                        </td>
                    </tr>
@@ -245,8 +257,10 @@
                                    <apex:outputField value="{!or.con.CampaignOwnerName__c}" />
                                    </apex:outputLink>
                                  </td>
                                  <td align="center">
                                    <apex:outputField value="{!or.Agcmmc.Contact__c}"/>
                                  <td align="center" >
                                    <a style="position: relative" href="/{!or.con.Id}" aws-data-id="{!or.con.AWS_Data_Id__c}" title=""><span>{!or.con.MedicalStaff_Full_name__c}</span><span class="decrypt"></span></a>
                                  </td>
                                  <td>
                                    <apex:outputField value="{!or.con.Accountid}"/>
@@ -304,45 +318,131 @@
                    </div>
                </apex:outputPanel>
            </apex:pageBlock>
<script type="text/javascript">
j$(function() {
    var tableWidth = 0;
    j$('body .pbBody table#tableHeader tr.headerRow td').each(function() {
        var colClass = getColClassName(this);
        if (colClass != 'col_Scroll') {
            var headerCol = j$('body .pbBody table.list tr.headerRow td.' + colClass);
            tableWidth += headerCol.width();
        }
    });
    j$('table#tableData').css('width', (tableWidth + 2) + 'px');
    j$('table#tableHeader').css('width', (tableWidth + 2) + 'px');
    // list の headerRow の tdに toggleWidth() を追加
    bindTdToggleWidth();
});
var elements = document.getElementsByTagName("select");
for (i = 0; i < elements.length; i++) {
    var id = elements[i].id;
    if (id.length > 5 && id.substring(id.length - 5, id.length) == 'mlktp') {
        elements[i].style.display = "none";
    }
}
var tbl_l = document.getElementById("tableData_L");
var input_l = tbl_l.getElementsByTagName("input");
for (i = 0; i < input_l.length; i++) {
    var id = input_l[i].id + '_lkid';
    if (document.getElementById(id) != null) {
        input_l[i].style.width = "75%";
    }
}
var tbl = document.getElementById("tableData");
var input = tbl.getElementsByTagName("input");
for (i = 0; i < input.length; i++) {
    var id = input[i].id + '_lkid';
    if (document.getElementById(id) != null) {
        input[i].style.width = "75%";
    }
}
</script>
            <script type="text/javascript">
              j$(function() {
                  var tableWidth = 0;
                  j$('body .pbBody table#tableHeader tr.headerRow td').each(function() {
                      var colClass = getColClassName(this);
                      if (colClass != 'col_Scroll') {
                          var headerCol = j$('body .pbBody table.list tr.headerRow td.' + colClass);
                          tableWidth += headerCol.width();
                      }
                  });
                  j$('table#tableData').css('width', (tableWidth + 2) + 'px');
                  j$('table#tableHeader').css('width', (tableWidth + 2) + 'px');
                  // list の headerRow の tdに toggleWidth() を追加
                  bindTdToggleWidth();
              });
              var elements = document.getElementsByTagName("select");
              for (i = 0; i < elements.length; i++) {
                  var id = elements[i].id;
                  if (id.length > 5 && id.substring(id.length - 5, id.length) == 'mlktp') {
                      elements[i].style.display = "none";
                  }
              }
              var tbl_l = document.getElementById("tableData_L");
              var input_l = tbl_l.getElementsByTagName("input");
              for (i = 0; i < input_l.length; i++) {
                  var id = input_l[i].id + '_lkid';
                  if (document.getElementById(id) != null) {
                      input_l[i].style.width = "75%";
                  }
              }
              var tbl = document.getElementById("tableData");
              var input = tbl.getElementsByTagName("input");
              for (i = 0; i < input.length; i++) {
                  var id = input[i].id + '_lkid';
                  if (document.getElementById(id) != null) {
                      input[i].style.width = "75%";
                  }
              }
              AWSService.sfSessionId = '{!GETSESSIONID()}';
              var staticResource = JSON.parse('{!staticResource}');
              document.body.onload = function(){
                NewSearch();
              }
              var awsdata_map={};
              function NewSearch(){
                // 如果有填写姓名,先去aws查询,再用awsdataid查询后台,如果没有填写直接查询后台
                awsdata_map={};
                let e = document.getElementById("allPage:allForm:searchBlock:numtextC");
                if(e && e.value){
                  blockme();
                  AWSService.search(staticResource.searchUrl,JSON.stringify({
                    "contactName":e.value
                  }),function(data){
                    unblockUI();
                    if(data.object && data.object.length > 0){
                      let aws_data_ids = [];
                      for(let d of data.object){
                        if(d.dataId){
                          awsdata_map[d.dataId] = d;
                          aws_data_ids.push(d.dataId);
                        }
                      }
                      document.getElementById("allPage:allForm:searchBlock:AwsDataIds").value = aws_data_ids.join(";");
                    }else{
                      document.getElementById("allPage:allForm:searchBlock:AwsDataIds").value = new Date().getTime();
                    }
                    searchOppJs_Account_copy();
                  },staticResource.token);
                }else{
                  searchOppJs_Account_copy();
                }
              }
              function afterSearchOpp(){
                DecryptContactName(()=>unblockUI());
              }
              function afterSaveAndSearch(){
                DecryptContactName(()=>unblockUI());
              }
              function DecryptContactName(callback){
                let no_in_ids = [];
                j$("[aws-data-id]").each(function(i,e){
                  let id = e.getAttribute("aws-data-id");
                  if(!(id && awsdata_map.hasOwnProperty(id))){
                    no_in_ids.push(id);
                  }
                });
                if(no_in_ids.length>0){
                  AWSService.search(staticResource.searchUrl,JSON.stringify({
                    "dataIds":no_in_ids
                  }),function(data){
                    if(data.object && data.object.length > 0){
                      for(let d of data.object){
                        if(d.dataId){
                          awsdata_map[d.dataId] = d;
                        }
                      }
                    }
                    BindToTile();
                    if(callback)callback();
                  },staticResource.token);
                }
                else{
                  BindToTile();
                  if(callback)callback();
                }
              }
              function BindToTile(){
                j$("[aws-data-id]").each(function(i,e){
                  let id = e.getAttribute("aws-data-id");
                  if(id && awsdata_map.hasOwnProperty(id) && awsdata_map[id].medicalStaffFullName){
                    j$(e).find(".decrypt").html(awsdata_map[id].medicalStaffFullName);
                  }
                });
              }
            </script>
        </apex:outputPanel>
    </apex:form>
</apex:page>
force-app/main/default/pages/B_Test.page
New file
@@ -0,0 +1,304 @@
<apex:page id="Page" controller="B_Test" sidebar="false" showHeader="false" action="{!init}">
    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
    <apex:stylesheet value="{!URLFOR($Resource.blockUIcss)}"/>
    <apex:includeScript value="{!URLFOR($Resource.jquery183minjs)}"/>
    <apex:includeScript value="{!URLFOR($Resource.PleaseWaitDialog)}"/>
    <script type="text/javascript">
    var staticResources = JSON.parse('{!staticResource}');
        var awsResult = [{
            "dataId": "942720697313001472",
            "isDelete": 0,
            "lastName": "张三12312321",
            "phone": "2988a8e6bcc90e83f54f81bc841aa822",
            "email": "d0152175c99a1c050f46d0d23996ff987b738add75e73c476b65611ba4a2b1b5",
            "medicalStaffFullName": null,
            "mobilePhone": "2988a8e6bcc90e83f54f81bc841aa822",
            "title": null,
            "olyAssistantType": null,
            "jobCategoryPicklist": null,
            "type": "3b13e2b5c5fd4003a931a38dcaf1c545",
            "contactAddress": null,
            "contactType": null,
            "doctorDivision1": null,
            "uniqueNumber": null,
            "lastNameEncrypt": null,
            "phoneEncrypt": null,
            "emailEncrypt": null,
            "medicalStaffFullNameEncrypt": null,
            "mobilePhoneEncrypt": null,
            "titleEncrypt": null,
            "olyAssistantTypeEncrypt": null,
            "jobCategoryPicklistEncrypt": null,
            "typeEncrypt": null,
            "contactAddressEncrypt": null,
            "contactTypeEncrypt": null,
            "doctorDivision1Encrypt": null,
            "uniqueNumberEncrypt": null
        },{
            "dataId": "942720697313001472",
            "isDelete": 0,
            "lastName": "李四12312321",
            "phone": "2988a8e6bcc90e83f54f81bc841aa822",
            "email": "d0152175c99a1c050f46d0d23996ff987b738add75e73c476b65611ba4a2b1b5",
            "medicalStaffFullName": null,
            "mobilePhone": "2988a8e6bcc90e83f54f81bc841aa822",
            "title": null,
            "olyAssistantType": null,
            "jobCategoryPicklist": null,
            "type": "3b13e2b5c5fd4003a931a38dcaf1c545",
            "contactAddress": null,
            "contactType": null,
            "doctorDivision1": null,
            "uniqueNumber": null,
            "lastNameEncrypt": null,
            "phoneEncrypt": null,
            "emailEncrypt": null,
            "medicalStaffFullNameEncrypt": null,
            "mobilePhoneEncrypt": null,
            "titleEncrypt": null,
            "olyAssistantTypeEncrypt": null,
            "jobCategoryPicklistEncrypt": null,
            "typeEncrypt": null,
            "contactAddressEncrypt": null,
            "contactTypeEncrypt": null,
            "doctorDivision1Encrypt": null,
            "uniqueNumberEncrypt": null
        }];
        var now_edit_id = '';
        function sobjectToAws(){
            return {
                "LastName":"张三",
                "Phone":"13800138000"
            }
        }
        function searchContactJs() {
            blockme();
            searchContact();
        }
        function editContactJs(conid) {
            blockme();
            now_edit_id=conid;
            editContact(conid);
        }
        function editSaveJs() {
            blockme();
            ProcessPI({},GetEditObj());
        }
        function editClearJs() {
            blockme();
            editClear();
        }
        function setContact(line) {
            var openLine = '{!openLine}';
            var cm = 'allPage:allForm:allBlock:records:'+ (openLine - 1) + ':contact';
            var cmid = 'allPage:allForm:allBlock:records:'+ (openLine - 1) + ':contactId';
            var conid = j$(escapeVfId('Page:allForm:listBlock:lineinfo:' + (line - 1) + ':conId')).value();
            var conname = j$(escapeVfId('Page:allForm:listBlock:lineinfo:' + (line - 1) + ':conName')).value();
            j$(escapeVfId(cmid),window.opener.document).val(conid);
            j$(escapeVfId(cm),window.opener.document).val(conname);
            // SWAG-BB44G7  设置所在科室名字和id的位置和内容 start
            var department = 'allPage:allForm:allBlock:records:'+ (openLine - 1) + ':department';
            var departmentid = 'allPage:allForm:allBlock:records:'+ (openLine - 1) + ':departmentid';
            var departmentHidden = 'allPage:allForm:allBlock:records:'+ (openLine - 1) + ':departmentHidden';
            var departmentHiddenId = 'allPage:allForm:allBlock:records:'+ (openLine - 1) + ':departmentHiddenId';
            var accid = j$(escapeVfId('Page:allForm:listBlock:lineinfo:' + (line - 1) + ':accountid')).value();
            var accName = j$(escapeVfId('Page:allForm:listBlock:lineinfo:' + (line - 1) + ':accountName')).value();
            j$(escapeVfId(department),window.opener.document).val(accName);
            j$(escapeVfId(departmentid),window.opener.document).val(accid);
            j$(escapeVfId(departmentHidden),window.opener.document).val(accName);
            j$(escapeVfId(departmentHiddenId),window.opener.document).val(accid);
            // SWAG-BB44G7  设置所在科室名字和id的位置和内容 end
            window.close();
        }
        jQuery(function(){
            alert("Init返回之后,继续查询AWS");
        })
/*
        function insertOrUpdateBack(payloadJson, r, isNewMode){
            payloadJson.LastName = r.object[0].lastName;
            payloadJson.Phone = r.object[0].phone;
            payloadJson.LastName_Encrypted__c = r.object[0].lastNameEncrypted;
            payloadJson.Phone_Encrypted__c = r.object[0].phoneEncrypted;
            payloadJson.AWS_Data_Id__c = r.object[0].dataId;
            return payloadJson;
        }*/
        var aws_result = {};
        function GetAWSResultObj(){
            if(aws_result && aws_result.object && aws_result.object.length > 0){
                return aws_result.object[0];
            }
            return null;
        }
        function ProcessPI(sobjJson, payloadForNewPI) {
            //blockme();
            let url = staticResources.newUrl
            if (now_edit_id) {
                url = staticResources.updateUrl
            }
            AWSService.post(staticResources.updateUrl, payloadForNewPI, function(result){
                aws_result = result;
                SetEditObj();
                saveNew();
            }, staticResources.token);
        }
        function Trans(){
            let status = aws_result.status == '0';
            AWSService.sfdcBack({status:status}, aws_result, aws_result.txId, staticResources.token, staticResources.transactionURL,function(){
                unblockUI();
            })
        }
    </script>
    <apex:form id="allForm">
        <apex:actionFunction name="searchContact" action="{!searchContact}" rerender="allForm" onComplete="unblockUI();">
        </apex:actionFunction>
        <apex:actionFunction name="editContact" action="{!editContact}" rerender="allForm" onComplete="unblockUI();assignUnencrypted()">
            <apex:param name="firstParam" assignTo="{!conId}" value="" />
        </apex:actionFunction>
        <apex:actionFunction name="saveNew" action="{!saveNew}" rerender="allForm" onComplete="Trans();">
        </apex:actionFunction>
        <apex:actionFunction name="editClear" action="{!editClear}" rerender="allForm" onComplete="unblockUI();">
        </apex:actionFunction>
        <apex:outputPanel id="allPanel">
            <apex:pageBlock id="searchBlock" title="检索条件">
                <table class="linetable" border="0" style="border-collapse: collapse;width:600px;table-layout:fixed;">
                    <colgroup>
                        <col width="50px" />
                        <col width="150px" />
                        <col width="50px" />
                        <col width="150px" />
                        <col width="200px" />
                    </colgroup>
                    <tr>
                        <td>{!$ObjectType.Contact.fields.LastName.Label}</td>
                        <td><apex:inputField value="{!searchCon.Search_LastName__c}" style="width: 90%"/></td>
                        <td>{!$ObjectType.Contact.fields.FirstName.Label}</td>
                        <td><apex:inputField value="{!searchCon.Search_FirstName__c}" style="width: 90%"/></td>
                        <td><input type="button" value="检索" onclick="searchContactJs(); return null;" /></td>
                    </tr>
                </table>
            </apex:pageBlock>
            <apex:pageBlock id="listBlock" title="检索结果">
            <div style="height: 200px; overflow-y: auto; overflow-x: hidden;">
                <table class="edittable" border="0" style="border-collapse: collapse;width:580px;table-layout:fixed;">
                    <colgroup>
                        <col width="50px" />
                        <col width="100px" />
                        <col width="380px" />
                        <col width="50px" />
                    </colgroup>
                    <tr>
                        <th>No.</th>
                        <th>{!$ObjectType.Contact.fields.Name.Label}</th>
                        <th>{!$ObjectType.Contact.fields.AccountName__c.Label}</th>
                        <th>操作</th>
                    </tr>
                    <apex:repeat id="lineinfo" value="{!lineInfoList}" var="lineinfo">
                    <tr>
                        <td>{!lineinfo.lineNo}
                            <apex:inputHidden id="conId" value="{!lineinfo.con.id}"/>
                            <apex:inputHidden id="conName" value="{!lineinfo.con.name}"/>
                            <apex:inputHidden id="accountName" value="{!lineinfo.con.AccountName__c}"/>
                            <apex:inputHidden id="accountid" value="{!lineinfo.con.accountid}"/>
                        </td>
                        <td><a href="#" onclick="setContact('{!lineinfo.lineNo}');">{!lineinfo.con.Name}</a></td>
                        <td>{!lineinfo.con.AccountName__c}</td>
                        <td><input style="width:90%;" type="button" value="编辑" onclick="editContactJs('{!lineinfo.con.Id}'); return null;" /></td>
                    </tr>
                    </apex:repeat>
                </table>
            </div>
            </apex:pageBlock>
            <script>
                function assignUnencrypted(){
                    let obj = sobjectToAws();
                    document.getElementById("Page:allForm:editBlock:Search_LastName__c").value = obj.LastName;
                    document.getElementById("Page:allForm:editBlock:Phone").value = obj.Phone;
                }
                function GetEditObj(){
                    return JSON.stringify([{
                        lastName : document.getElementById("Page:allForm:editBlock:Search_LastName__c").value,
                        phone : document.getElementById("Page:allForm:editBlock:Phone").value,
                        dataId:document.getElementById("Page:allForm:editBlock:AWS_Data_Id__c").value,
                    }]);
                }
                function SetEditObj(){
                    let obj = GetAWSResultObj();
                    if(obj){
                        document.getElementById("Page:allForm:editBlock:Search_LastName__c").value = obj.lastName;
                        document.getElementById("Page:allForm:editBlock:LastName_Encrypted__c").value = obj.lastNameEncrypt;
                        document.getElementById("Page:allForm:editBlock:Phone").value = obj.phone;
                        document.getElementById("Page:allForm:editBlock:Phone_Encrypted__c").value = obj.phoneEncrypt;
                    }
                }
            </script>
            <apex:pageBlock id="editBlock" title="联系人编辑">
                <apex:pageBlockButtons location="top">
                    <apex:commandButton onclick="editClearJs();" value="清空" rerender="dummy"/>
                    <apex:commandButton onclick="editSaveJs();" value="保存" rerender="dummy"/>
                </apex:pageBlockButtons>
                <apex:inputHidden id="LastName_Encrypted__c" value="{!newCon.LastName_Encrypted__c}"/>
                <apex:inputHidden id="Phone_Encrypted__c" value="{!newCon.Phone_Encrypted__c}"/>
                <apex:inputHidden id="AWS_Data_Id__c" value="{!newCon.AWS_Data_Id__c}"/>
                <table class="edittable" border="0" style="border-collapse: collapse; width:600px; table-layout:fixed;">
                    <colgroup>
                        <col width="50px" />
                        <col width="150px" />
                        <col width="50px" />
                        <col width="150px" />
                        <col width="50px" />
                        <col width="150px" />
                    </colgroup>
                    <tr>
                        <td>{!$ObjectType.Contact.fields.LastName.Label}</td>
                        <td><span><div class="requiredInput"><div class="requiredBlock"></div>
                            <apex:inputField id="Search_LastName__c" value="{!newCon.Search_LastName__c}" style="width: 90%"/>
                        </div></span></td>
                        <td>{!$ObjectType.Contact.fields.Phone.Label}</td>
                        <td><apex:inputField id="Phone" value="{!newCon.Phone}" style="width: 90%"/></td>
                    </tr>
                    <tr>
                        <td>{!$ObjectType.Contact.fields.Supplement__c.Label}</td>
                        <td colspan="5"><apex:inputField id="Supplement__c" value="{!newCon.Supplement__c}" style="width: 95%; resize: none; height: 50px"/></td>
                    </tr>
                </table>
            </apex:pageBlock>
        </apex:outputPanel>
    </apex:form>
</apex:page>
force-app/main/default/pages/B_Test.page-meta.xml
New file
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <availableInTouch>false</availableInTouch>
    <confirmationTokenRequired>false</confirmationTokenRequired>
    <label>B_Test</label>
</ApexPage>
force-app/main/default/pages/CM_SearchContact.page
@@ -1,21 +1,83 @@
<apex:page id="Page" controller="CM_SearchContact" sidebar="false" showHeader="false" action="{!init}">
    <apex:stylesheet value="{!URLFOR($Resource.blockUIcss)}"/>
    <!-- 2022/02/15 张华建 dependency start -->
    <apex:includeScript value="{!URLFOR($Resource.AWSService, 'AWSService.js') }" />
    <!-- 2022/02/15 张华建 dependency end -->
    <apex:includeScript value="{!URLFOR($Resource.jquery183minjs)}"/>
    <apex:includeScript value="{!URLFOR($Resource.PleaseWaitDialog)}"/>
    <script type="text/javascript">
        // 2022/02/15 张华建 改造PI start
        var staticResources = JSON.parse('{!staticResource}');
        var contactAWSIds = JSON.parse('{!contactAWSIds}');
        var LastName = '';
        var contact = {};
        var now_edit_id = '';
        var aws_result = {};
        searchContactAll();
        function preparePayloadForSearchContact(){
            let searchPayload = new Object();
            searchPayload.dataIds = contactAWSIds;
            searchPayload.contactName = LastName;
            return JSON.stringify(searchPayload);
        }
        function searchContactAll(){
            let data = preparePayloadForSearchContact();
            let searchCallBack = function searchCallBack(result){
                let contacts = result.object;
                if(contacts == null){
                    return;
                }
                for(var i=0;i<contacts.length;i++){
                    let temp = {}
                    temp.lastName = contacts[i].lastName;
                    temp.phone = contacts[i].phone;
                    contact[contacts[i].dataId] = temp;
                }
                console.log(JSON.stringify(contact));
            };
            AWSService.search(staticResources.searchUrl,data,searchCallBack,staticResources.token);
        }
        function searchContactJs() {
            blockme();
            searchContact();
            LastName = document.getElementById('Page:allForm:searchBlock:LastName').value;
            let awsDataIdArray = [];
            for(var key in contact){
                if(contact[key].lastName.includes(LastName)){
                    awsDataIdArray.push(key);
                }
            }
            console.log(awsDataIdArray)
            if(awsDataIdArray.length == 0){
                clearLineInfoList();
                return;
            }
            searchContactAll();
            searchContact(awsDataIdArray.toString());
        }
        // 2022/02/15 张华建 改造PI end
        function editContactJs(conid) {
            blockme();
            now_edit_id=conid;// 2022/02/15 徐亮 改造PI
            editContact(conid);
        }
        function editSaveJs() {
            document.getElementById("errorMsg").innerHTML = '';
            if(!document.getElementById("Page:allForm:editBlock:Search_LastName__c").value){
                document.getElementById("errorMsg").innerHTML = '<strong>错误:</strong> 必须填写。';
                return;
            }
            blockme();
            saveNew();
            ProcessPI({},GetEditObj());
        }
        function editClearJs() {
@@ -23,14 +85,17 @@
            editClear();
        }
        function setContact(line) {
        function setContact(line,awsDataId) {
            var openLine = '{!openLine}';
            var cm = 'allPage:allForm:allBlock:records:'+ (openLine - 1) + ':contact';
            var cmid = 'allPage:allForm:allBlock:records:'+ (openLine - 1) + ':contactId';
            var conid = j$(escapeVfId('Page:allForm:listBlock:lineinfo:' + (line - 1) + ':conId')).value();
            var conname = j$(escapeVfId('Page:allForm:listBlock:lineinfo:' + (line - 1) + ':conName')).value();
            //var conname = j$(escapeVfId('Page:allForm:listBlock:lineinfo:' + (line - 1) + ':conName')).value();
            //2022/02/15 张华建 赋值成明文 start
            var conname = contact[awsDataId].lastName;
            //2022/02/15 张华建 赋值成明文 end
            j$(escapeVfId(cmid),window.opener.document).val(conid);
            j$(escapeVfId(cm),window.opener.document).val(conname);
@@ -53,19 +118,136 @@
            window.close();
        }
        function showPIDiv(awsDataId){
            console.log('awsDataId Value:'+awsDataId);
            let parentNode = document.getElementById(awsDataId);
            let createDiv = document.createElement("div");
            createDiv.id = awsDataId+"_PI";
            let piInformation = 'Name:'+contact[awsDataId].lastName +'\n' +'Phone:'+contact[awsDataId].phone
            //let piInformation = 'Name:'+contact['943114607025717249'].lastName +'\n' +'Phone:'+contact['943114607025717249'].phone
            createDiv.innerText = piInformation;
            let x=window.event.x;
            let y=window.event.y;
            createDiv.style.left=x;
            createDiv.style.top=y;
            createDiv.style.background="#dddddd";
            createDiv.style.position = "absolute";
            parentNode.appendChild(createDiv);
        }
        function hidePIDiv(awsDataId){
            document.getElementById(awsDataId+'_PI').remove();
        }
        // 2022年2月15日 PI改造 徐亮 start
        function sobjectToAws(){
            let aws_id = document.getElementById("Page:allForm:editBlock:AWS_Data_Id__c").value;
            if(contact.hasOwnProperty(aws_id)){
                return contact[aws_id];
            }
            else{
                console.log('not found aws data in contact obj');
                return {};
            }
        }
        function GetAWSResultObj(){
            if(aws_result && aws_result.object && aws_result.object.length > 0){
                return aws_result.object[0];
            }
            return null;
        }
        function ProcessPI(sobjJson, payloadForNewPI) {
            let url = staticResources.newUrl
            if (now_edit_id) {
                url = staticResources.updateUrl
            }
            AWSService.post(url, payloadForNewPI, function(result){
                aws_result = result;
                SetEditObj();
                saveNew();
            }, staticResources.token);
        }
        function Trans(){
            /*
            jQuery.ajax({
                "type":"post",
                "url":staticResources.transactionUrl,
                "data":{
                    "txId":aws_result.txId,
                    "isSuccess":1
                },
                beforeSend: function(request) {
                    request.setRequestHeader("pi-token",staticResources.token);
                    request.setRequestHeader('Content-Type', 'application/json');
                },
                success:function(data){
                    console.log(data);
                },
                error:function(jqXHR, textStatus, errorThrown) {
                    console.log(jqXHR);
                    console.log(textStatus);
                    console.log(errorThrown);
                }
            });*/
            AWSService.post(staticResources.transactionUrl, JSON.stringify({
                    "txId":aws_result.txId,
                    "isSuccess":1
                }), function(result){
                    window.location.reload();
                }, staticResources.token);
        }
        function assignUnencrypted(){
            let obj = sobjectToAws();
            document.getElementById("Page:allForm:editBlock:Search_LastName__c").value = obj.lastName;
            document.getElementById("Page:allForm:editBlock:Phone").value = obj.phone;
            unblockUI();
        }
        function GetEditObj(){
            return JSON.stringify([{
                lastName : document.getElementById("Page:allForm:editBlock:Search_LastName__c").value,
                phone : document.getElementById("Page:allForm:editBlock:Phone").value,
                dataId:document.getElementById("Page:allForm:editBlock:AWS_Data_Id__c").value,
            }]);
        }
        function SetEditObj(){
            let obj = GetAWSResultObj();
            if(obj){
                document.getElementById("Page:allForm:editBlock:AWS_Data_Id__c").value = obj.dataId;
                document.getElementById("Page:allForm:editBlock:Search_LastName__c").value = obj.lastName;
                document.getElementById("Page:allForm:editBlock:LastName_Encrypted__c").value = obj.lastNameEncrypt;
                document.getElementById("Page:allForm:editBlock:Phone").value = obj.phone;
                document.getElementById("Page:allForm:editBlock:Phone_Encrypted__c").value = obj.phoneEncrypt;
            }
        }
        // 2022年2月15日 PI改造 徐亮 end
    </script>
    <apex:form id="allForm">
        <apex:actionFunction name="searchContact" action="{!searchContact}" rerender="allForm" onComplete="unblockUI();">
            <apex:param name="awsDataIdArray" assignTo="{!awsDataIdArray}" value="" />
        </apex:actionFunction>
        <apex:actionFunction name="editContact" action="{!editContact}" rerender="allForm" onComplete="unblockUI();">
        <apex:actionFunction name="editContact" action="{!editContact}" rerender="allForm" onComplete="assignUnencrypted();">
            <apex:param name="firstParam" assignTo="{!conId}" value="" />
        </apex:actionFunction>
        <apex:actionFunction name="saveNew" action="{!saveNew}" rerender="allForm" onComplete="unblockUI();">
        <apex:actionFunction name="saveNew" action="{!saveNew}" rerender="allForm" onComplete="Trans();">
        </apex:actionFunction>
        <apex:actionFunction name="editClear" action="{!editClear}" rerender="allForm" onComplete="unblockUI();">
        </apex:actionFunction>
        <!-- 2022/02/15 张华建 清空LineInfoList start -->
        <apex:actionFunction name="clearLineInfoList" action="{!clearLineInfoList}" rerender="allForm" onComplete="unblockUI();">
        </apex:actionFunction>
        <!-- 2022/02/15 张华建 清空LineInfoList end -->
        <apex:outputPanel id="allPanel">
            <apex:pageBlock id="searchBlock" title="检索条件">
                <table class="linetable" border="0" style="border-collapse: collapse;width:600px;table-layout:fixed;">
@@ -78,44 +260,49 @@
                    </colgroup>
                    <tr>
                        <td>{!$ObjectType.Contact.fields.LastName.Label}</td>
                        <td><apex:inputField value="{!searchCon.Search_LastName__c}" style="width: 90%"/></td>
                        <td>{!$ObjectType.Contact.fields.FirstName.Label}</td>
                        <td><apex:inputField value="{!searchCon.Search_FirstName__c}" style="width: 90%"/></td>
                        <td><apex:inputField id="LastName" value="{!searchCon.Search_LastName__c}" style="width: 90%"/></td>
                        <!-- 2022/02/15 张华建 不需要FirstName start -->
                        <!-- <td>{!$ObjectType.Contact.fields.FirstName.Label}</td>
                        <td><apex:inputField id="FirstName" value="{!searchCon.Search_FirstName__c}" style="width: 90%"/></td> -->
                        <!-- 2022/02/15 张华建 不需要FirstName end -->
                        <td><input type="button" value="检索" onclick="searchContactJs(); return null;" /></td>
                    </tr>
                </table>
            </apex:pageBlock>
            <apex:pageBlock id="listBlock" title="检索结果">
            <div style="height: 200px; overflow-y: auto; overflow-x: hidden;">
                <table class="edittable" border="0" style="border-collapse: collapse;width:580px;table-layout:fixed;">
                    <colgroup>
                        <col width="50px" />
                        <col width="100px" />
                        <col width="380px" />
                        <col width="50px" />
                    </colgroup>
                    <tr>
                        <th>No.</th>
                        <th>{!$ObjectType.Contact.fields.Name.Label}</th>
                        <th>{!$ObjectType.Contact.fields.AccountName__c.Label}</th>
                        <th>操作</th>
                    </tr>
                    <apex:repeat id="lineinfo" value="{!lineInfoList}" var="lineinfo">
                    <tr>
                        <td>{!lineinfo.lineNo}
                            <apex:inputHidden id="conId" value="{!lineinfo.con.id}"/>
                            <apex:inputHidden id="conName" value="{!lineinfo.con.name}"/>
                            <apex:inputHidden id="accountName" value="{!lineinfo.con.AccountName__c}"/>
                            <apex:inputHidden id="accountid" value="{!lineinfo.con.accountid}"/>
                        </td>
                        <td><a href="#" onclick="setContact('{!lineinfo.lineNo}');">{!lineinfo.con.Name}</a></td>
                        <td>{!lineinfo.con.AccountName__c}</td>
                        <td><input style="width:90%;" type="button" value="编辑" onclick="editContactJs('{!lineinfo.con.Id}'); return null;" /></td>
                    </tr>
                    </apex:repeat>
                </table>
            </div>
                <div style="height: 200px; overflow-y: auto; overflow-x: hidden;">
                    <table class="edittable" border="0" style="border-collapse: collapse;width:580px;table-layout:fixed;">
                        <colgroup>
                            <col width="50px" />
                            <col width="100px" />
                            <col width="380px" />
                            <col width="50px" />
                        </colgroup>
                        <tr>
                            <th>No.</th>
                            <th>{!$ObjectType.Contact.fields.Name.Label}</th>
                            <th>{!$ObjectType.Contact.fields.AccountName__c.Label}</th>
                            <th>操作</th>
                        </tr>
                        <apex:repeat id="lineinfo" value="{!lineInfoList}" var="lineinfo">
                        <tr>
                            <td>{!lineinfo.lineNo}
                                <apex:inputHidden id="conId" value="{!lineinfo.con.id}"/>
                                <apex:inputHidden id="conName" value="{!lineinfo.con.name}"/>
                                <apex:inputHidden id="accountName" value="{!lineinfo.con.AccountName__c}"/>
                                <apex:inputHidden id="accountid" value="{!lineinfo.con.accountid}"/>
                            </td>
                            <!-- <td><a href="#" onclick="setContact('{!lineinfo.lineNo}');" id="943114607025717249" onmouseover="showPIDiv('943114607025717249')" onmouseout="hidePIDiv('943114607025717249')">{!lineinfo.con.Name}</a></td> -->
                            <!-- 2022/02/15 张华建 解密信息 start -->
                            <td><a href="#" onclick="setContact('{!lineinfo.lineNo}','{!lineinfo.con.AWS_Data_Id__c}');" id="{!lineinfo.con.AWS_Data_Id__c}" onmouseover="showPIDiv('{!lineinfo.con.AWS_Data_Id__c}')" onmouseout="hidePIDiv('{!lineinfo.con.AWS_Data_Id__c}')">{!lineinfo.con.Name}</a></td>
                            <!-- 2022/02/15 张华建 解密信息 end -->
                            <td>{!lineinfo.con.AccountName__c}</td>
                            <td><input style="width:90%;" type="button" value="编辑" onclick="editContactJs('{!lineinfo.con.Id}'); return null;" /></td>
                        </tr>
                        </apex:repeat>
                    </table>
                </div>
            </apex:pageBlock>
            <apex:pageBlock id="editBlock" title="联系人编辑">
@@ -123,6 +310,11 @@
                    <apex:commandButton onclick="editClearJs();" value="清空" rerender="dummy"/>
                    <apex:commandButton onclick="editSaveJs();" value="保存" rerender="dummy"/>
                </apex:pageBlockButtons>
                <apex:inputHidden id="LastName_Encrypted__c" value="{!newCon.LastName_Encrypted__c}"/>
                <apex:inputHidden id="Phone_Encrypted__c" value="{!newCon.Phone_Encrypted__c}"/>
                <apex:inputHidden id="AWS_Data_Id__c" value="{!newCon.AWS_Data_Id__c}"/>
                <table class="edittable" border="0" style="border-collapse: collapse; width:600px; table-layout:fixed;">
                    <colgroup>
                        <col width="50px" />
@@ -135,12 +327,13 @@
                    <tr>
                        <td>{!$ObjectType.Contact.fields.LastName.Label}</td>
                        <td><span><div class="requiredInput"><div class="requiredBlock"></div>
                            <apex:inputField value="{!newCon.Search_LastName__c}" style="width: 90%"/>
                            <apex:inputField id="Search_LastName__c" value="{!newCon.Search_LastName__c}" style="width: 90%"/>
                            <div id="errorMsg" class="errorMsg"></div>
                        </div></span></td>
                        <td>{!$ObjectType.Contact.fields.FirstName.Label}</td>
                        <td><apex:inputField value="{!newCon.Search_FirstName__c}" style="width: 90%"/></td>
                        <!-- <td>{!$ObjectType.Contact.fields.FirstName.Label}</td>
                        <td><apex:inputField value="{!newCon.Search_FirstName__c}" style="width: 90%"/></td> -->
                        <td>{!$ObjectType.Contact.fields.Phone.Label}</td>
                        <td><apex:inputField value="{!newCon.Phone}" style="width: 90%"/></td>
                        <td><apex:inputField id="Phone" value="{!newCon.Phone}" style="width: 90%"/></td>
                    </tr>
                    <tr>
                        <td>{!$ObjectType.Contact.fields.Supplement__c.Label}</td>
force-app/main/default/pages/CM_SearchContactService.page
@@ -1,21 +1,83 @@
<apex:page id="Page" controller="CM_SearchContactServiceController" sidebar="false" showHeader="false" action="{!init}">
    <!-- 2022/02/15 张华建 dependency start -->
    <apex:includeScript value="{!URLFOR($Resource.AWSService, 'AWSService.js') }" />
    <!-- 2022/02/15 张华建 dependency end -->
    <apex:stylesheet value="{!URLFOR($Resource.blockUIcss)}"/>
    <apex:includeScript value="{!URLFOR($Resource.jquery183minjs)}"/>
    <apex:includeScript value="{!URLFOR($Resource.PleaseWaitDialog)}"/>
    <script type="text/javascript">
        // 2022/02/15 张华建 改造PI start
        var staticResources = JSON.parse('{!staticResource}');
        var contactAWSIds = JSON.parse('{!contactAWSIds}');
        var LastName = '';
        var contact = {};
        var now_edit_id = '';
        var aws_result = {};
        searchContactAll();
        function preparePayloadForSearchContact(){
            let searchPayload = new Object();
            searchPayload.dataIds = contactAWSIds;
            searchPayload.contactName = LastName;
            return JSON.stringify(searchPayload);
        }
        function searchContactAll(){
            let data = preparePayloadForSearchContact();
            let searchCallBack = function searchCallBack(result){
                let contacts = result.object;
                if(contacts == null){
                    return;
                }
                for(var i=0;i<contacts.length;i++){
                    let temp = {}
                    temp.lastName = contacts[i].lastName;
                    temp.phone = contacts[i].phone;
                    contact[contacts[i].dataId] = temp;
                }
                console.log(JSON.stringify(contact));
            };
            AWSService.search(staticResources.searchUrl,data,searchCallBack,staticResources.token);
        }
        function searchContactJs() {
            blockme();
            searchContact();
            LastName = document.getElementById('Page:allForm:searchBlock:LastName').value;
            let awsDataIdArray = [];
            for(var key in contact){
                if(contact[key].lastName.includes(LastName)){
                    awsDataIdArray.push(key);
                }
            }
            console.log(awsDataIdArray)
            if(awsDataIdArray.length == 0){
                clearLineInfoList();
                return;
            }
            searchContactAll();
            searchContact(awsDataIdArray.toString());
        }
        // 2022/02/15 张华建 改造PI end
        function editContactJs(conid) {
            blockme();
            now_edit_id=conid;// 2022/02/15 徐亮 改造PI
            editContact(conid);
        }
        function editSaveJs() {
            document.getElementById("errorMsg").innerHTML = '';
            if(!document.getElementById("Page:allForm:editBlock:Search_LastName__c").value){
                document.getElementById("errorMsg").innerHTML = '<strong>错误:</strong> 必须填写。';
                return;
            }
            blockme();
            saveNew();
            ProcessPI({},GetEditObj());
        }
        function editClearJs() {
@@ -23,12 +85,16 @@
            editClear();
        }
        function setContact(line) {
        function setContact(line,awsDataId) {
            var openLine = '{!openLine}';
            var cm = 'allPage:allForm:allBlock:records:'+ (openLine - 1) + ':contact';
            var cmid = 'allPage:allForm:allBlock:records:'+ (openLine - 1) + ':contactId';
            var conid = j$(escapeVfId('Page:allForm:listBlock:lineinfo:' + (line - 1) + ':conId')).value();
            var conname = j$(escapeVfId('Page:allForm:listBlock:lineinfo:' + (line - 1) + ':conName')).value();
            //var conname = j$(escapeVfId('Page:allForm:listBlock:lineinfo:' + (line - 1) + ':conName')).value();
            //2022/02/15 张华建 赋值成明文 start
            var conname = contact[awsDataId].lastName;
            //2022/02/15 张华建 赋值成明文 end
            // 2018/11/19 HWAG-B399RW 自动设置省和市 start
            var cityName = j$(escapeVfId('Page:allForm:listBlock:lineinfo:' + (line - 1) + ':City')).value();
            var StateName = j$(escapeVfId('Page:allForm:listBlock:lineinfo:' + (line - 1) + ':State')).value();
@@ -45,19 +111,115 @@
            window.close();
        }
        function showPIDiv(awsDataId){
            console.log('awsDataId Value:'+awsDataId);
            let parentNode = document.getElementById(awsDataId);
            let createDiv = document.createElement("div");
            createDiv.id = awsDataId+"_PI";
            let piInformation = 'Name:'+contact[awsDataId].lastName +'\n' +'Phone:'+contact[awsDataId].phone
            //let piInformation = 'Name:'+contact['943114607025717249'].lastName +'\n' +'Phone:'+contact['943114607025717249'].phone
            createDiv.innerText = piInformation;
            let x=window.event.x;
            let y=window.event.y;
            createDiv.style.left=x;
            createDiv.style.top=y;
            createDiv.style.background="#dddddd";
            createDiv.style.position = "absolute";
            parentNode.appendChild(createDiv);
        }
        function hidePIDiv(awsDataId){
            document.getElementById(awsDataId+'_PI').remove();
        }
        // 2022年2月15日 PI改造 徐亮 start
        function sobjectToAws(){
            let aws_id = document.getElementById("Page:allForm:editBlock:AWS_Data_Id__c").value;
            if(contact.hasOwnProperty(aws_id)){
                return contact[aws_id];
            }
            else{
                console.log('not found aws data in contact obj');
                return {};
            }
        }
        function GetAWSResultObj(){
            if(aws_result && aws_result.object && aws_result.object.length > 0){
                return aws_result.object[0];
            }
            return null;
        }
        function ProcessPI(sobjJson, payloadForNewPI) {
            //blockme();
            let url = staticResources.newUrl
            if (now_edit_id) {
                url = staticResources.updateUrl
            }
            AWSService.post(url, payloadForNewPI, function(result){
                aws_result = result;
                SetEditObj();
                saveNew();
            }, staticResources.token);
        }
        function Trans(){
            AWSService.post(staticResources.transactionUrl, JSON.stringify({
                "txId":aws_result.txId,
                "isSuccess":1
            }), function(result){
                window.location.reload();
            }, staticResources.token);
        }
        function assignUnencrypted(){
            let obj = sobjectToAws();
            document.getElementById("Page:allForm:editBlock:Search_LastName__c").value = obj.lastName;
            //document.getElementById("Page:allForm:editBlock:Phone").value = obj.phone;
            unblockUI();
        }
        function GetEditObj(){
            return JSON.stringify([{
                lastName : document.getElementById("Page:allForm:editBlock:Search_LastName__c").value,
                //phone : document.getElementById("Page:allForm:editBlock:Phone").value,
                dataId:document.getElementById("Page:allForm:editBlock:AWS_Data_Id__c").value,
            }]);
        }
        function SetEditObj(){
            let obj = GetAWSResultObj();
            if(obj){
                document.getElementById("Page:allForm:editBlock:AWS_Data_Id__c").value = obj.dataId;
                document.getElementById("Page:allForm:editBlock:Search_LastName__c").value = obj.lastName;
                document.getElementById("Page:allForm:editBlock:LastName_Encrypted__c").value = obj.lastNameEncrypt;
                //document.getElementById("Page:allForm:editBlock:Phone").value = obj.phone;
                document.getElementById("Page:allForm:editBlock:Phone_Encrypted__c").value = obj.phoneEncrypt;
            }
        }
        // 2022年2月15日 PI改造 徐亮 end
    </script>
    <apex:form id="allForm">
        <apex:actionFunction name="searchContact" action="{!searchContact}" rerender="allForm,allPanel" onComplete="unblockUI();">
            <apex:param name="awsDataIdArray" assignTo="{!awsDataIdArray}" value="" />
        </apex:actionFunction>
        <apex:actionFunction name="editContact" action="{!editContact}" rerender="allForm,allPanel" onComplete="unblockUI();">
        <apex:actionFunction name="editContact" action="{!editContact}" rerender="allForm,allPanel" onComplete="assignUnencrypted();">
            <apex:param name="firstParam" assignTo="{!conId}" value="" />
        </apex:actionFunction>
        <apex:actionFunction name="saveNew" action="{!saveNew}" rerender="allForm,allPanel" onComplete="unblockUI();">
        <apex:actionFunction name="saveNew" action="{!saveNew}" rerender="allForm,allPanel" onComplete="Trans();">
        </apex:actionFunction>
        <apex:actionFunction name="editClear" action="{!editClear}" rerender="allForm,allPanel" onComplete="unblockUI();">
        </apex:actionFunction>
        <!-- 2022/02/15 张华建 清空LineInfoList start -->
        <apex:actionFunction name="clearLineInfoList" action="{!clearLineInfoList}" rerender="allForm" onComplete="unblockUI();">
        </apex:actionFunction>
        <!-- 2022/02/15 张华建 清空LineInfoList end -->
        <apex:outputPanel id="allPanel">
            <apex:pageBlock id="searchBlock" title="检索条件">
                <table class="linetable" border="0" style="border-collapse: collapse;width:600px;table-layout:fixed;">
@@ -70,9 +232,11 @@
                    </colgroup>
                    <tr>
                        <td>{!$ObjectType.Contact.fields.LastName.Label}</td>
                        <td><apex:inputField value="{!searchCon.Search_LastName__c}" style="width: 90%"/></td>
                        <td>{!$ObjectType.Contact.fields.FirstName.Label}</td>
                        <td><apex:inputField value="{!searchCon.Search_FirstName__c}" style="width: 90%"/></td>
                        <td><apex:inputField id="LastName" value="{!searchCon.Search_LastName__c}" style="width: 90%"/></td>
                        <!-- 2022/02/15 张华建 不需要FirstName start -->
                        <!-- <td>{!$ObjectType.Contact.fields.FirstName.Label}</td>
                        <td><apex:inputField id="FirstName" value="{!searchCon.Search_FirstName__c}" style="width: 90%"/></td> -->
                        <!-- 2022/02/15 张华建 不需要FirstName end -->
                        <td><input type="button" value="检索" onclick="searchContactJs(); return null;" /></td>
                    </tr>
                </table>
@@ -104,7 +268,10 @@
                            <!--  2018/11/19 HWAG-B399RW  存取客户人员省市数据 end -->
                        </td>
                        <td><a href="#" onclick="setContact('{!lineinfo.lineNo}');">{!lineinfo.con.Name}</a></td>
                        <!-- <td><a href="#" onclick="setContact('{!lineinfo.lineNo}');" id="943114607025717249" onmouseover="showPIDiv('943114607025717249')" onmouseout="hidePIDiv('943114607025717249')">{!lineinfo.con.Name}</a></td> -->
                        <!-- 2022/02/15 张华建 解密信息 start -->
                        <td><a href="#" onclick="setContact('{!lineinfo.lineNo}','{!lineinfo.con.AWS_Data_Id__c}');" id="{!lineinfo.con.AWS_Data_Id__c}" onmouseover="showPIDiv('{!lineinfo.con.AWS_Data_Id__c}')" onmouseout="hidePIDiv('{!lineinfo.con.AWS_Data_Id__c}')">{!lineinfo.con.Name}</a></td>
                        <!-- 2022/02/15 张华建 解密信息 end -->
                        <td>{!lineinfo.con.AccountName__c}</td>
                        <td><input style="width:90%;" type="button" value="编辑" onclick="editContactJs('{!lineinfo.con.Id}'); return null;" /></td>
                    </tr>
@@ -118,6 +285,9 @@
                    <apex:commandButton onclick="editClearJs();" value="清空" rerender="dummy"/>
                    <apex:commandButton onclick="editSaveJs();" value="保存" rerender="dummy"/>
                </apex:pageBlockButtons>
                <apex:inputHidden id="LastName_Encrypted__c" value="{!newCon.LastName_Encrypted__c}"/>
                <apex:inputHidden id="Phone_Encrypted__c" value="{!newCon.Phone_Encrypted__c}"/>
                <apex:inputHidden id="AWS_Data_Id__c" value="{!newCon.AWS_Data_Id__c}"/>
                <table class="edittable" border="0" style="border-collapse: collapse; width:600px; table-layout:fixed;">
                    <colgroup>
                        <col width="50px" />
@@ -130,10 +300,11 @@
                    <tr>
                        <td>{!$ObjectType.Contact.fields.LastName.Label}</td>
                        <td><span><div class="requiredInput"><div class="requiredBlock"></div>
                            <apex:inputField value="{!newCon.Search_LastName__c}" style="width: 90%"/>
                            <apex:inputField id="Search_LastName__c" value="{!newCon.Search_LastName__c}" style="width: 90%"/>
                            <div id="errorMsg" class="errorMsg"></div>
                        </div></span></td>
                        <td>{!$ObjectType.Contact.fields.FirstName.Label}</td>
                        <td><apex:inputField value="{!newCon.Search_FirstName__c}" style="width: 90%"/></td>
                        <!-- <td>{!$ObjectType.Contact.fields.FirstName.Label}</td>
                        <td><apex:inputField value="{!newCon.Search_FirstName__c}" style="width: 90%"/></td> -->
                    </tr>
                    <tr>
                        <td>{!$ObjectType.Contact.fields.Supplement__c.Label}</td>
force-app/main/default/pages/CampaignMember.page
@@ -6,6 +6,9 @@
<apex:includeScript value="{!URLFOR($Resource.jquerysuggestjs)}"/>
<apex:includeScript value="{!URLFOR($Resource.connection20)}"/>
<apex:includeScript value="{!URLFOR($Resource.apex20)}"/>
<!-- 2022/02/15 张华建 dependency start -->
<apex:includeScript value="{!URLFOR($Resource.AWSService, 'AWSService.js') }" />
<!-- 2022/02/15 张华建 dependency end -->
<style type="text/css">
    .visitorplace_results {
        border: 1px solid gray;
@@ -138,8 +141,49 @@
        }
    }
    // 20220216 PI改造 by 徐亮 start
    var staticResource = JSON.parse('{!staticResource}');
    var awsids = [];
    var aws_result={};
    jQuery(function(){
        var eles = document.getElementsByClassName("contact");
        for(let e of eles){
            let awsid = e.getAttribute('awsid');
            if(awsid) awsids.push(awsid);
        }
        if(awsids.length > 0){
            AWSService.search(staticResource.searchUrl,JSON.stringify({dataIds:awsids}),function(result){
                if(result.status == '0' && result.object && result.object.length > 0){
                    for(let obj of result.object){
                        jQuery("[awsid='"+obj.dataId + "']").val(obj.lastName);
                    }
                }
            },staticResource.token);
        }
    })
    //jQuery(".contact").attr("awsid");
    function encrypt(){
        jQuery(".contact").each(function(i,e){
            if(e.value){
                e.value = '***';
            }
        });
    }
    // 20220216 PI改造 by 徐亮 end
function saveJs() {
    blockme();
    encrypt() // 20220216 PI改造 by 徐亮
    saveLine();
}
function addJs() {
@@ -349,7 +393,7 @@
                            <apex:inputHidden id="departmentHiddenId" value="{!lineInfo.cm.Department_ID__c}" />
                        </td>
                        <td align="center">
                            <apex:inputField id="contact" value="{!lineInfo.cm.Contact__c}" onclick="openSearchContact({!lineInfo.line})" style="width: 95%"></apex:inputField>
                            <apex:inputField styleClass="contact" html-awsid="{!lineInfo.cm.Contact_ID__r.AWS_Data_Id__c}" id="contact" value="{!lineInfo.cm.Contact__c}" onclick="openSearchContact({!lineInfo.line})" style="width: 95%"></apex:inputField>
                            <apex:inputHidden id="contactId" value="{!lineInfo.cm.Contact_ID__c}"></apex:inputHidden>
                            <apex:inputHidden id="contactSDCName" value="{!lineInfo.cm.Contact_ID__r.Strategic_dept_Class__r.Name}"></apex:inputHidden>
                        </td>
force-app/main/default/pages/CampaignMemberService.page
@@ -6,6 +6,9 @@
<apex:includeScript value="{!URLFOR($Resource.jquerysuggestjs)}"/>
<apex:includeScript value="{!URLFOR($Resource.connection20)}"/>
<apex:includeScript value="{!URLFOR($Resource.apex20)}"/>
<!-- 2022/02/15 张华建 dependency start -->
<apex:includeScript value="{!URLFOR($Resource.AWSService, 'AWSService.js') }" />
<!-- 2022/02/15 张华建 dependency end -->
<style type="text/css">
    .visitorplace_results {
        border: 1px solid gray;
@@ -136,10 +139,53 @@
        }
    }
// 20220216 PI改造 by 徐亮 start
var staticResource = JSON.parse('{!staticResource}');
    var awsids = [];
    var aws_result={};
    jQuery(function(){
        var eles = document.getElementsByClassName("contact");
        for(let e of eles){
            let awsid = e.getAttribute('awsid');
            if(awsid) awsids.push(awsid);
        }
        if(awsids.length > 0){
            AWSService.search(staticResource.searchUrl,JSON.stringify({dataIds:awsids}),function(result){
                if(result.status == '0' && result.object && result.object.length > 0){
                    for(let obj of result.object){
                        jQuery("[awsid='"+obj.dataId + "']").val(obj.lastName);
                    }
                }
            },staticResource.token);
        }
    })
    //jQuery(".contact").attr("awsid");
    function encrypt(){
        jQuery(".contact").each(function(i,e){
            if(e.value){
                e.value = '***';
            }
        });
    }
    // 20220216 PI改造 by 徐亮 end
function saveJs() {
    blockme();
    encrypt() // 20220216 PI改造 by 徐亮
    saveLine();
}
function addJs() {
    blockme();
    addLine();
@@ -261,7 +307,7 @@
                            <apex:inputHidden id="departmentHiddenId" value="{!lineInfo.cm.Department_ID__c}" />
                        </td>
                        <td align="center">
                            <apex:inputField id="contact" value="{!lineInfo.cm.Contact__c}" onclick="openSearchContact({!lineInfo.line})" style="width: 95%"></apex:inputField>
                            <apex:inputField styleClass="contact" html-awsid="{!lineInfo.cm.Contact_ID__r.AWS_Data_Id__c}" id="contact" value="{!lineInfo.cm.Contact__c}" onclick="openSearchContact({!lineInfo.line})" style="width: 95%"></apex:inputField>
                            <apex:inputHidden id="contactId" value="{!lineInfo.cm.Contact_ID__c}"></apex:inputHidden>
                            <apex:inputHidden id="contactSDCName" value="{!lineInfo.cm.Contact_ID__r.Strategic_dept_Class__r.Name}"></apex:inputHidden>
                        </td>
force-app/main/default/pages/ConsumApplyUploadPdf.page
New file
@@ -0,0 +1,190 @@
<!-- 该页面用于Lead对象上传PDF,未来如果要添加其他对象的上传PDF功能,复制该页面,将**standardController**修改为其他对象API名称即可 -->
<apex:page standardController="Consum_Apply__c" extensions="FileUploadController" id="page" lightningStyleSheets="true">
    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
    <script>
        var staticResources = JSON.parse('{!staticResource}');
        var parentId = '{!parentId}';
        var uploadUrl = staticResources.newUrl;
        var key;
        function alertErrorMessage(errorMsg) {
            let errorMsgNode = document.getElementById("page:theForm:block:msgContent");
            errorMsgNode.innerText = errorMsg;
            errorMsgNode.className = 'message errorM3';
        }
        function hiddenErrorMsgNode() {
            let errorMsgNode = document.getElementById("page:theForm:block:msgContent");
            errorMsgNode.innerText = '';
            errorMsgNode.className = '';
        }
        function getFileContent(event) {
            var fileObject = document.getElementById("page:theForm:block:uploadSection:file");
            var reader = new FileReader();
            var data = reader.readAsDataURL(fileObject.files[0]);
            debugger
            console.log(event);
        }
        function getBase64(file) {
            return new Promise((resolve, reject) => {
                const reader = new FileReader();
                reader.readAsDataURL(file);
                reader.onload = () => resolve(reader.result);
                reader.onerror = error => reject(error);
            });
        }
        function disableButtonStatus() {
            let btnNode = document.getElementById('uploadFileId');
            btnNode.classList.add("btnDisabled");
        }
        function enableButtonStatus() {
            let btnNode = document.getElementById('uploadFileId');
            btnNode.classList.remove("btnDisabled");
        }
        function uploadFile() {
            disableButtonStatus();
            var fileObject = document.getElementById("file").files[0];
            getBase64(fileObject).then(
                data => {
                    console.log(data);
                    uploadFileToAWS(data, (fileObject.size).toString(), fileObject.name);
                }
            );
        }
        function confirmTrans(transId, isSuccess) {
            fetch(staticResources.updateUrl, {
                method: 'POST',
                body: JSON.stringify({ 'txId': transId, "isSuccess": isSuccess }),
                headers: {
                    'Content-Type': 'application/json',
                    'pi-token': staticResources.token
                }
            }).then((data) => {
                return data.json();
            }).then(data => {
                console.log("confirmTrans-" + JSON.stringify(data));
                document.getElementById("file").files[0].name = '';
                enableButtonStatus();
                refreshFiles();
                return data.status;
            })
        }
        function calculateFileSize(fileObject) {
            if (fileObject.size > 20971520) {
                alertErrorMessage('文件过大,请选择小于20mb的文件');
            }
        }
        function uploadFileToAWS(data, size, fileName) {
            console.log("body=" + JSON.stringify({ 'file': data, "size": size, 'fileName': fileName }));
            fetch(uploadUrl, {
                method: 'POST',
                body: JSON.stringify({ 'file': data, "size": size, 'fileName': fileName }),
                headers: {
                    'Content-Type': 'application/json',
                    'pi-token': staticResources.token
                }
            }).then((data) => {
                return data.json();
            }).then(result => {
                console.log("result" + JSON.stringify(result));
                if (result.success == true) {
                    key = result.object;
                    Visualforce.remoting.Manager.invokeAction(
                        '{!$RemoteAction.FileUploadController.saveFile}',
                        fileName, key, result.txId, parentId,
                        function (resultvalue, event) {
                            //2. show file list
                            if (resultvalue.status == 'fail') {
                                alertErrorMessage(resultvalue.message);
                                //1. Confirm trans
                                confirmTrans(result.txId, 0);
                            } else {
                                alertErrorMessage('上传成功');
                                confirmTrans(result.txId, 1);
                            }
                            // window.location.reload();
                        },
                        { escape: true }
                    );
                    console.log('key' + key);
                } else {
                    alertErrorMessage('上传失败请稍后再试!');
                }
            }).catch((error) => {
                console.error('Error:', error);
            })
            debugger
        }
        function downPdf(fileUrl) {
            window.open(fileUrl,'_blank');
        }
    </script>
    <style>
        .pdf .num {
            width: 30%;
        }
        .pdf.name {
            width: 30%
        }
        .pdf.downLink {
            width: 40%
        }
    </style>
    <apex:form id="theForm">
        <apex:actionFunction name="refreshFiles" action="{!refreshFiles}" reRender="pdf,uploadSection"/>
        <br/>
        <br/>
        <apex:pageBlock id="block">
            <div style="text-align: center;">
                <apex:outputPanel id="errorMsg">
                    <apex:pageMessages id="msgContent" escape="false" />
                </apex:outputPanel>
            </div>
            <apex:pageBlockSection id="uploadSection">
                <!-- <apex:inputFile id="file" value="{!documentData.body}" filename="{!documentData.name}" /> -->
                <input type="file" id="file" name="filename"/>
                <input class="btn" id='uploadFileId' type="Button" value="确认上传" onclick="uploadFile()" />
            </apex:pageBlockSection>
        </apex:pageBlock>
        <apex:pageBlock title="PDF列表" id="pdf">
            <!-- <apex:pageBlockSection > -->
            <!-- show uploated file list -->
            <apex:pageBlockTable value="{!fileList}" var="file" align="center" columns="3" columnsWidth="30%,30%,40%">
                <apex:column id="name" headerValue="文件名称">
                    <apex:outputLink value="/{!file.Id}" target="_blank">{!file.FileName__c}</apex:outputLink>
                </apex:column>
                <!-- <apex:column id="num" headerValue="父记录链接">
                    <apex:outputLink value="/{!file.ParentRecordId__c}" target="_blank">{!file.ParentRecordId__c}</apex:outputLink>
                </apex:column> -->
                <apex:column id="previewLink" headerValue="预览链接">
                    <apex:outputLink value="{!file.ViewLink__c}" target="{!file.ViewLink__c}">预览链接
                    </apex:outputLink>
                </apex:column>
                <apex:column id="downLink" headerValue="下载链接">
                    <!-- <apex:outputLink value= "{!file.DownloadLink__c}" target="{!file.DownloadLink__c}">下载链接
                    </apex:outputLink> -->
                    <input class="btn" id='downloadFileButton' type="Button" value="下载" onclick="downPdf('{!file.DownloadLink__c}')" />
                </apex:column>
            </apex:pageBlockTable>
            <!-- </apex:pageBlockSection> -->
        </apex:pageBlock>
    </apex:form>
</apex:page>
force-app/main/default/pages/ConsumApplyUploadPdf.page-meta.xml
New file
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>52.0</apiVersion>
    <availableInTouch>false</availableInTouch>
    <confirmationTokenRequired>false</confirmationTokenRequired>
    <label>ConsumApplyUploadPdf</label>
</ApexPage>
force-app/main/default/pages/ConsumReassign.page
@@ -2,7 +2,23 @@
<apex:stylesheet value="{!URLFOR($Resource.blockUIcss)}"/>
<apex:includeScript value="{!URLFOR($Resource.jquery183minjs)}"/>
<apex:includeScript value="{!URLFOR($Resource.PleaseWaitDialog)}"/>
<apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
<script src="../../soap/ajax/53.0/connection.js" type="text/javascript"></script>
<style>
    .decrypt {
        position: absolute;
        top: 0;
        left: 100%;
        display: none;
        text-align: left;
        padding-left: 5px;
    }
    a:hover .decrypt {
        display: block;
        width: 100px
    }
</style>
<script type="text/javascript">
    function savejs() {
        if (confirm('是否操作重新分配?')) {
@@ -29,6 +45,54 @@
            returnjs();
        }
    }
    AWSService.sfSessionId = '{!GETSESSIONID()}';
    var staticResource = JSON.parse('{!staticResource}');
    document.body.onload = function () {
        blockme();
        DecryptContactName(() => unblockUI());
    }
    var awsdata_map = {};
    function DecryptContactName(callback) {
        let no_in_ids = [];
        j$("[aws-data-id]").each(function (i, e) {
            let id = e.getAttribute("aws-data-id");
            if (!(id && awsdata_map.hasOwnProperty(id))) {
                no_in_ids.push(id);
            }
        });
        if (no_in_ids.length > 0) {
            AWSService.search(staticResource.searchUrl, JSON.stringify({
                "dataIds": no_in_ids
            }), function (data) {
                if (data.object && data.object.length > 0) {
                    for (let d of data.object) {
                        if (d.dataId) {
                            awsdata_map[d.dataId] = d;
                        }
                    }
                }
                BindToTile();
                if (callback) callback();
            }, staticResource.token);
        }
        else {
            BindToTile();
            if (callback) callback();
        }
    }
    function BindToTile() {
        j$("[aws-data-id]").each(function (i, e) {
            let id = e.getAttribute("aws-data-id");
            if (id && awsdata_map.hasOwnProperty(id) && awsdata_map[id].trialUser) {
                j$(e).find(".decrypt").html(awsdata_map[id].trialUser);
            }
        });
    }
</script>
    <apex:form id="allForm">
@@ -37,7 +101,7 @@
        <apex:outputPanel id="allPanel">
            <apex:pageBlock title="重新分配" id="allBlock">
                <apex:pageBlockButtons >
                    <apex:commandButton onclick="savejs(); return false;" value="保存" disabled="{!saveBtn}" rerender="dummy"/>
                    <apex:commandButton onclick="savejs(); return false;" value="保存" disabled="{!saveBtn}" rerender="dummy" />
                    <apex:commandButton onclick="returnjs(); return false;" value="返回" rerender="dummy"/>
                </apex:pageBlockButtons>
@@ -59,7 +123,9 @@
                        <col width="175"/>
                    </colgroup>
                    <tr style="background-color:#DCDCDC;">
                        <th style="text-align:center">全选<apex:inputCheckbox id="checkAll" value="{!checkAll}" onclick="checkAll(this);"/></th>
                        <th style="text-align:center">全选
                            <apex:inputCheckbox id="checkAll" value="{!checkAll}" onclick="checkAll(this);" />
                        </th>
                        <th style="text-align:center">{!$ObjectType.Consum_Apply_Equipment_Set_Detail__c.fields.Consum_Apply_Equipment_Set__c.label}</th>
                        <th style="text-align:center">{!$ObjectType.Consum_Apply_Equipment_Set_Detail__c.fields.Fixture_Model_No_F__c.label}</th>
                        <th style="text-align:center">数量</th>
@@ -72,15 +138,37 @@
                    <apex:repeat value="{!lineInfoList}" var="info" id="records">
                        <tr>
                            <!--<td align="center"><apex:inputCheckbox value="{!info.isSelect}" id="rowCheck" disabled="{!IF(info.status=='cantCancel', true, false)}"/></td>-->
                            <td align="center"><apex:inputCheckbox styleClass="checker" value="{!info.isSelect}" id="rowCheck"/></td>
                            <td align="left"><apex:outputField value="{!info.caesd.Consum_Apply_Equipment_Set__c}"></apex:outputField></td>
                            <td align="left"><apex:outputField value="{!info.caesd.Fixture_Model_No_F__c}"></apex:outputField></td>
                            <td align="left"><apex:outputField value="{!info.caesd.Trial_Num__c}"></apex:outputField></td>
                            <td align="left"><apex:outputField value="{!info.caesd.Asset__c}"></apex:outputField></td>
                            <td align="left"><apex:outputField value="{!info.caesd.SerialNumber_F__c}"></apex:outputField></td>
                            <td align="center"><apex:outputField value="{!info.caesd.RAESD_Status__c}"></apex:outputField></td>
                            <td align="center"><apex:outputField value="{!info.caesd.Trial_User__c}"></apex:outputField></td>
                            <td align="center"><apex:outputField value="{!info.caesd.Degree_Of_Importance__c}"></apex:outputField></td>
                            <td align="center">
                                <apex:inputCheckbox styleClass="checker" value="{!info.isSelect}" id="rowCheck" />
                            </td>
                            <td align="left">
                                <apex:outputField value="{!info.caesd.Consum_Apply_Equipment_Set__c}"></apex:outputField>
                            </td>
                            <td align="left">
                                <apex:outputField value="{!info.caesd.Fixture_Model_No_F__c}"></apex:outputField>
                            </td>
                            <td align="left">
                                <apex:outputField value="{!info.caesd.Trial_Num__c}"></apex:outputField>
                            </td>
                            <td align="left">
                                <apex:outputField value="{!info.caesd.Asset__c}"></apex:outputField>
                            </td>
                            <td align="left">
                                <apex:outputField value="{!info.caesd.SerialNumber_F__c}"></apex:outputField>
                            </td>
                            <td align="center">
                                <apex:outputField value="{!info.caesd.RAESD_Status__c}"></apex:outputField>
                            </td>
                            <td align="center">
                                <a style="position: relative" href="/{!info.caesd.Id}" aws-data-id="{!info.caesd.AWS_Data_Id__c}" title="">
                                    <span>{!info.caesd.Trial_User__c}</span>
                                    <span class="decrypt"></span>
                                </a>
                                <!-- <apex:outputField value="{!info.caesd.Trial_User__c}"></apex:outputField> -->
                            </td>
                            <td align="center">
                                <apex:outputField value="{!info.caesd.Degree_Of_Importance__c}"></apex:outputField>
                            </td>
                        </tr>
                    </apex:repeat>
                </table>
force-app/main/default/pages/ConsumTrial.page
@@ -5,6 +5,7 @@
    <apex:stylesheet value="{!URLFOR($Resource.ConsumTrialPageCss)}"/>
    <apex:includeScript value="{!URLFOR($Resource.ReceivingNotePageJS)}"/>
    <apex:includeScript value="{!URLFOR($Resource.CommonUtilJs)}"/>
    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }"/>
    <apex:form id="allForm">
        <style>
            table.headTable td   {
@@ -23,287 +24,392 @@
              background-repeat:no-repeat;
            }
        </style>
<script type="text/javascript">
    var heightAjustment = 120;
    var widthAjustment = 30;
        <script type="text/javascript">
            var heightAjustment = 120;
            var widthAjustment = 30;
            var staticResource = JSON.parse('{!staticResource}');
    // 适用按钮
    function applyJs() {
        var appliedFlag = true;
        var selectFlag = true;
        var isCheckFlag = false;
        var ShowDemonstration = j$(escapeVfId('allPage:allForm:searchBlock:ShowDemonstration')).val();  // 展示/演示
        var OperationType = j$(escapeVfId('allPage:allForm:searchBlock:OperationType')).val();  // 术式类别
        var ConsumStartDate = j$(escapeVfId('allPage:allForm:searchBlock:ConsumStartDate')).val();  // 预计使用日
        var CaseOrAnimalOrgan = j$(escapeVfId('allPage:allForm:searchBlock:CaseOrAnimalOrgan')).val();  // 病例/动物脏器
        var TrialUser= j$(escapeVfId('allPage:allForm:searchBlock:TrialUser')).val();  // 试用者
        var FollowerUserid = j$(escapeVfId('allPage:allForm:searchBlock:FollowerUser_lkid')).val();  // 跟台者Id
        var FollowerUsername = j$(escapeVfId('allPage:allForm:searchBlock:FollowerUser_lkold')).val();  // 跟台者Name
            // 适用按钮
            function applyJs() {
                var appliedFlag = true;
                var selectFlag = true;
                var isCheckFlag = false;
                var ShowDemonstration = j$(escapeVfId('allPage:allForm:searchBlock:ShowDemonstration')).val();  // 展示/演示
                var OperationType = j$(escapeVfId('allPage:allForm:searchBlock:OperationType')).val();  // 术式类别
                var ConsumStartDate = j$(escapeVfId('allPage:allForm:searchBlock:ConsumStartDate')).val();  // 预计使用日
                var CaseOrAnimalOrgan = j$(escapeVfId('allPage:allForm:searchBlock:CaseOrAnimalOrgan')).val();  // 病例/动物脏器
                var TrialUser= j$(escapeVfId('allPage:allForm:searchBlock:TrialUser')).val();  // 试用者
                var FollowerUserid = j$(escapeVfId('allPage:allForm:searchBlock:FollowerUser_lkid')).val();  // 跟台者Id
                var FollowerUsername = j$(escapeVfId('allPage:allForm:searchBlock:FollowerUser_lkold')).val();  // 跟台者Name
        var ShowDemonstrations = []; // 展示/演示
        j$("td.intf.dataCellBorder1.Show_demonstration__c").each(function() {
            ShowDemonstrations.push(j$(this));
        });
        var OperationTypes = [];  // 术式类别
        j$("td.intf.dataCellBorder1.Operation_Type__c").each(function() {
            OperationTypes.push(j$(this));
        });
        var ConsumStartDates = [];  // 备品预计使用日
        j$("td.intf.dataCellBorder1.Consum_Start_Date__c").each(function() {
            ConsumStartDates.push(j$(this));
        });
        var CaseOrAnimalOrgans = [];  // 病例/动物脏器
        j$("td.intf.dataCellBorder1.Case_OR_animal_organ__c").each(function() {
            CaseOrAnimalOrgans.push(j$(this));
        });
                var ShowDemonstrations = []; // 展示/演示
                j$("td.intf.dataCellBorder1.Show_demonstration__c").each(function() {
                    ShowDemonstrations.push(j$(this));
                });
                var OperationTypes = [];  // 术式类别
                j$("td.intf.dataCellBorder1.Operation_Type__c").each(function() {
                    OperationTypes.push(j$(this));
                });
                var ConsumStartDates = [];  // 备品预计使用日
                j$("td.intf.dataCellBorder1.Consum_Start_Date__c").each(function() {
                    ConsumStartDates.push(j$(this));
                });
                var CaseOrAnimalOrgans = [];  // 病例/动物脏器
                j$("td.intf.dataCellBorder1.Case_OR_animal_organ__c").each(function() {
                    CaseOrAnimalOrgans.push(j$(this));
                });
        var TrialUsers = [];  // 试用者
        j$("td.intf.dataCellBorder1.Trial_User__c").each(function() {
            TrialUsers.push(j$(this));
        });
                var TrialUsers = [];  // 试用者
                j$("td.intf.dataCellBorder1.Trial_User__c").each(function() {
                    TrialUsers.push(j$(this));
                });
        var FollowerUsers = [];  // 跟台者:
        j$("td.intf.dataCellBorder1.Follower_User__c").each(function() {
            FollowerUsers.push(j$(this));
        });
                var FollowerUsers = [];  // 跟台者:
                j$("td.intf.dataCellBorder1.Follower_User__c").each(function() {
                    FollowerUsers.push(j$(this));
                });
        var currentPageRecordCount = j$(escapeVfId('allPage:allForm:dataBlock:currentPageRecordCnt')).val();
        for (var i = 0; i < currentPageRecordCount; i++) {
            var checkBox = j$(escapeVfId('allPage:allForm:dataBlock:dataline_L:' + i + ':rowCheck'));
            if (checkBox.prop('checked') == true) {
                isCheckFlag = true;
                // 'x'时不适用
                if (ShowDemonstration != 'x') {
                    ShowDemonstrations[i].find("select").val(ShowDemonstration);
                    appliedFlag = false;
                }
                if (OperationType != 'x') {
                    OperationTypes[i].find("select").val(OperationType);
                    appliedFlag = false;
                }
                if (ConsumStartDate != null && ConsumStartDate != '' && typeof(ConsumStartDate) != "undefined") {
                    ConsumStartDates[i].find("input").val(ConsumStartDate);
                    appliedFlag = false;
                }
                if (CaseOrAnimalOrgan != 'x') {
                    CaseOrAnimalOrgans[i].find("select").val(CaseOrAnimalOrgan);
                    appliedFlag = false;
                }
                if (TrialUser != null && TrialUser != '' && typeof(TrialUser) != "undefined") {
                    TrialUsers[i].find("input").val(TrialUser);
                    appliedFlag = false;
                }
                // if (equipmentTypes[i].find("select").val() != productCategory && productCategory != '') {
                if (FollowerUserid != null && parseInt(FollowerUserid) != 0 && typeof(FollowerUserid) != "undefined"
                    && FollowerUsername != null && FollowerUsername != 'null' && typeof(FollowerUsername) != "undefined") {
                    // setChangeFlg();
                    var inputs = FollowerUsers[i].find("input");
                    for (var j = 0; j < inputs.length; j++) {
                        if(inputs[j].name.endsWith('_lkid')) {
                            inputs[j].value = FollowerUserid;
                var currentPageRecordCount = j$(escapeVfId('allPage:allForm:dataBlock:currentPageRecordCnt')).val();
                for (var i = 0; i < currentPageRecordCount; i++) {
                    var checkBox = j$(escapeVfId('allPage:allForm:dataBlock:dataline_L:' + i + ':rowCheck'));
                    if (checkBox.prop('checked') == true) {
                        isCheckFlag = true;
                        // 'x'时不适用
                        if (ShowDemonstration != 'x') {
                            ShowDemonstrations[i].find("select").val(ShowDemonstration);
                            appliedFlag = false;
                        }
                        else if (inputs[j].name.endsWith('_lkold')
                            || inputs[j].name.endsWith('inputField')) {
                            inputs[j].value = FollowerUsername;
                        if (OperationType != 'x') {
                            OperationTypes[i].find("select").val(OperationType);
                            appliedFlag = false;
                        }
                        if (ConsumStartDate != null && ConsumStartDate != '' && typeof(ConsumStartDate) != "undefined") {
                            ConsumStartDates[i].find("input").val(ConsumStartDate);
                            appliedFlag = false;
                        }
                        if (CaseOrAnimalOrgan != 'x') {
                            CaseOrAnimalOrgans[i].find("select").val(CaseOrAnimalOrgan);
                            appliedFlag = false;
                        }
                        if (TrialUser != null && TrialUser != '' && typeof(TrialUser) != "undefined") {
                            TrialUsers[i].find("input").val(TrialUser);
                            appliedFlag = false;
                        }
                        // if (equipmentTypes[i].find("select").val() != productCategory && productCategory != '') {
                        if (FollowerUserid != null && parseInt(FollowerUserid) != 0 && typeof(FollowerUserid) != "undefined"
                            && FollowerUsername != null && FollowerUsername != 'null' && typeof(FollowerUsername) != "undefined") {
                            // setChangeFlg();
                            var inputs = FollowerUsers[i].find("input");
                            for (var j = 0; j < inputs.length; j++) {
                                if(inputs[j].name.endsWith('_lkid')) {
                                    inputs[j].value = FollowerUserid;
                                }
                                else if (inputs[j].name.endsWith('_lkold')
                                    || inputs[j].name.endsWith('inputField')) {
                                    inputs[j].value = FollowerUsername;
                                }
                            }
                            appliedFlag = false;
                        }
                    }
                    appliedFlag = false;
                }
                j$(escapeVfId('allPage:allForm:pageBlockButton1:clearApplyFlagId')).val(false);
                // var clearApplyFlag = false;
                window.setTimeout(function () {
                    if (ConsumStartDate == null
                        && TrialUser == null
                        && (FollowerUserid== null || FollowerUsername == null)) {  // 适用入力框全为空
                        // alert('适用区输入框为空,请输入适用值。');
                        var applyMsg = '适用区输入框为空,请输入适用值。';
                        //passApplyMsgToController(applyMsg, 'Fail');
                        return;
                    }
                    if (isCheckFlag == false) {
                        // alert('未勾选任何待适用数据。');
                        var applyMsg = '未勾选任何待适用数据。';
                        //passApplyMsgToController(applyMsg, 'Fail');
                        return;
                    }
                    if (selectFlag) {
                        if (!appliedFlag) {
                            var alertMsg = "适用完了 \r\n";
                            if (ConsumStartDate != null && typeof(ConsumStartDate) != "undefined") {
                                var alertMsg1 = "已将打勾数据中的 " + "备品预计使用日" + " 适用为 " + ConsumStartDate + " \r\n";
                                alertMsg += alertMsg1;
                            }
                            if (TrialUser != null && typeof(TrialUser) != "undefined") {
                                var alertMsg1 = "已将打勾数据中的 " + "试用者" + " 适用为 " + TrialUser + " \r\n";
                                alertMsg += alertMsg1;
                            }
                            if (FollowerUserid != null && typeof(FollowerUserid) != "undefined"
                                && FollowerUsername != null && typeof(FollowerUsername) != "undefined") {
                                var alertMsg2 = "已将打勾数据中的 " + "跟台者:" + " 适用为 " + FollowerUsername + " \r\n";
                                alertMsg += alertMsg2;
                            }
                            // alert(alertMsg);
                            // clearApplyFlag = true;
                            j$(escapeVfId('allPage:allForm:pageBlockButton1:clearApplyFlagId')).val(true);
                            //passApplyMsgToController(alertMsg, 'Success');
                        }
                    } else {
                        if (!appliedFlag) {
                            var alertMsg = "适用完了 \r\n";
                            if (ConsumStartDate != null && typeof(ConsumStartDate) != "undefined") {
                                var alertMsg1 = "已将打勾数据中的 " + "备品预计使用日" + " 适用为 " + ConsumStartDate + " \r\n";
                                alertMsg += alertMsg1;
                            }
                            if (TrialUser != null && typeof(TrialUser) != "undefined") {
                                var alertMsg1 = "已将打勾数据中的 " + " 试用者" + " 适用为 " + TrialUser + " \r\n";
                                alertMsg += alertMsg1;
                            }
                            if (FollowerUserid != null && typeof(FollowerUserid) != "undefined"
                                && FollowerUsername != null && typeof(FollowerUsername) != "undefined") {
                                var alertMsg2 = "已将打勾数据中的 " + "跟台者:" + " 适用为 " + FollowerUsername + " \r\n";
                                alertMsg += alertMsg2;
                            }
                            //passApplyMsgToController(alertMsg, 'Success');
                            j$(escapeVfId('allPage:allForm:pageBlockButton1:clearApplyFlagId')).val(true);
                        } else {
                            var alertMsg = "其他选项: " + otherSelectOptionText +"中无此选项值" + otherSelectOptionValue + ",无法更新。";
                            //passApplyMsgToController(alertMsg, 'Fail');
                        }
                    }
                }, 5);
            }
            function clearApplyValue() {
                var clearApplyValueFlag = j$(escapeVfId('allPage:allForm:pageBlockButton1:clearApplyFlagId')).val();
                if(clearApplyValueFlag) {
                    j$(escapeVfId('{!$Component.stockId}')).val('');
                    j$(escapeVfId('{!$Component.applyEquipmentTypeId}')).val('');
                    j$(escapeVfId('{!$Component.applyAssetTypeListId}')).val('');
                    j$(escapeVfId('{!$Component.otherSelectionId}')).val('');
                }
                j$(escapeVfId('allPage:allForm:pageBlockButton1:clearApplyFlagId')).val(false);
            }
            function checkSavingJs() {
                var isSavingSuccess = j$(escapeVfId('isSavingSuccessId')).val();
                // alert(isSavingSuccess);
                if (isSavingSuccess != 'false') {
                    //setSaveSuccessMsg();
                }
            }
        }
        j$(escapeVfId('allPage:allForm:pageBlockButton1:clearApplyFlagId')).val(false);
        // var clearApplyFlag = false;
        window.setTimeout(function () {
            if (ConsumStartDate == null
                    && TrialUser == null
                    && (FollowerUserid== null || FollowerUsername == null)) {  // 适用入力框全为空
                // alert('适用区输入框为空,请输入适用值。');
                var applyMsg = '适用区输入框为空,请输入适用值。';
                //passApplyMsgToController(applyMsg, 'Fail');
                return;
            }
            if (isCheckFlag == false) {
                 // alert('未勾选任何待适用数据。');
                var applyMsg = '未勾选任何待适用数据。';
                //passApplyMsgToController(applyMsg, 'Fail');
                return;
            function resetMove(d, up, len) {
                var line = j$(escapeVfId(d)).find('input')[0].value;
                resetMoveUpDown(up, parseInt(line), len);
            }
            if (selectFlag) {
                if (!appliedFlag) {
                    var alertMsg = "适用完了 \r\n";
                    if (ConsumStartDate != null && typeof(ConsumStartDate) != "undefined") {
                        var alertMsg1 = "已将打勾数据中的 " + "备品预计使用日" + " 适用为 " + ConsumStartDate + " \r\n";
                        alertMsg += alertMsg1;
            function moveToTop(d, up, len) {
                var line = j$(escapeVfId(d)).find('input')[0].value;
                console.log(line);
                var isSuccessful = true;
                if (up) {
                    for(var i = parseInt(line) ; i > 1 && isSuccessful; i-- ) {
                        isSuccessful = resetMoveUpDown(up, i, len);
                    }
                    if (TrialUser != null && typeof(TrialUser) != "undefined") {
                        var alertMsg1 = "已将打勾数据中的 " + "试用者" + " 适用为 " + TrialUser + " \r\n";
                        alertMsg += alertMsg1;
                    }
                    if (FollowerUserid != null && typeof(FollowerUserid) != "undefined"
                    && FollowerUsername != null && typeof(FollowerUsername) != "undefined") {
                        var alertMsg2 = "已将打勾数据中的 " + "跟台者:" + " 适用为 " + FollowerUsername + " \r\n";
                        alertMsg += alertMsg2;
                    }
                    // alert(alertMsg);
                    // clearApplyFlag = true;
                    j$(escapeVfId('allPage:allForm:pageBlockButton1:clearApplyFlagId')).val(true);
                    //passApplyMsgToController(alertMsg, 'Success');
                }
            } else {
                if (!appliedFlag) {
                    var alertMsg = "适用完了 \r\n";
                    if (ConsumStartDate != null && typeof(ConsumStartDate) != "undefined") {
                        var alertMsg1 = "已将打勾数据中的 " + "备品预计使用日" + " 适用为 " + ConsumStartDate + " \r\n";
                        alertMsg += alertMsg1;
                else {
                    for(var i = parseInt(line) ; i < len && isSuccessful; i++ ) {
                        isSuccessful = resetMoveUpDown(up, i, len);
                    }
                    if (TrialUser != null && typeof(TrialUser) != "undefined") {
                        var alertMsg1 = "已将打勾数据中的 " + " 试用者" + " 适用为 " + TrialUser + " \r\n";
                        alertMsg += alertMsg1;
                    }
                    if (FollowerUserid != null && typeof(FollowerUserid) != "undefined"
                    && FollowerUsername != null && typeof(FollowerUsername) != "undefined") {
                        var alertMsg2 = "已将打勾数据中的 " + "跟台者:" + " 适用为 " + FollowerUsername + " \r\n";
                        alertMsg += alertMsg2;
                    }
                    //passApplyMsgToController(alertMsg, 'Success');
                    j$(escapeVfId('allPage:allForm:pageBlockButton1:clearApplyFlagId')).val(true);
                } else {
                    var alertMsg = "其他选项: " + otherSelectOptionText +"中无此选项值" + otherSelectOptionValue + ",无法更新。";
                    //passApplyMsgToController(alertMsg, 'Fail');
                }
                unblockUI();
            }
        }, 5);
    }
    function clearApplyValue() {
        var clearApplyValueFlag = j$(escapeVfId('allPage:allForm:pageBlockButton1:clearApplyFlagId')).val();
        if(clearApplyValueFlag) {
            j$(escapeVfId('{!$Component.stockId}')).val('');
            j$(escapeVfId('{!$Component.applyEquipmentTypeId}')).val('');
            j$(escapeVfId('{!$Component.applyAssetTypeListId}')).val('');
            j$(escapeVfId('{!$Component.otherSelectionId}')).val('');
        }
        j$(escapeVfId('allPage:allForm:pageBlockButton1:clearApplyFlagId')).val(false);
    }
            function resetMoveUpDown(up, line, len) {
    function checkSavingJs() {
        var isSavingSuccess = j$(escapeVfId('isSavingSuccessId')).val();
        // alert(isSavingSuccess);
        if (isSavingSuccess != 'false') {
            //setSaveSuccessMsg();
        }
    }
                var items = j$(".dataCellBorder2");
                var item1 = j$("td.intf.dataCellBorder1.Degree_Of_Importance__c");
                var item2 = j$("td.dataCellBorder1.col_Fixture_Model_No__c");
                var currentPageRecordCount = j$(escapeVfId('allPage:allForm:dataBlock:currentPageRecordCnt')).val();
                var isSuccessful = false;
                // alert(item1);
                var i = line - 1;
                var i1 = line + 1;
                // var tr = j$('#tableData').find('tbody').find('tr:eq(' + (i) + ')');
                if (up == true){
                    var tr = j$('#tableData').find('tbody').find('tr:eq(' + (i) + ')');
                    var trL = j$('#tableData_L').find('tbody').find('tr:eq(' + (i) + ')');
                    if(line != 1) {
                        var model1 = j$(item2[i - 1]).find("span").text();
                        var model2 = j$(item2[i]).find("span").text();
                        if (model1 != model2) {
                            unblockUI();
                            return;
                        }
    function resetMove(d, up, len) {
        var line = j$(escapeVfId(d)).find('input')[0].value;
        resetMoveUpDown(up, parseInt(line), len);
    }
                        var v1 = j$(item1[i - 1]).find("input").val();
                        var v2 = j$(item1[i]).find("input").val();
                        setChangeFlg(i-1);
                        setChangeFlg(i);
                        j$(items[i - 1]).children('.ordernocls').val(line);
                        j$(items[i]).children('.ordernocls').val(line - 1);
                        j$(item1[i - 1]).find("input").val(v2);
                        j$(item1[i]).find("input").val(v1);
    function moveToTop(d, up, len) {
        var line = j$(escapeVfId(d)).find('input')[0].value;
        console.log(line);
        var isSuccessful = true;
        if (up) {
            for(var i = parseInt(line) ; i > 1 && isSuccessful; i-- ) {
                isSuccessful = resetMoveUpDown(up, i, len);
                        isSuccessful = true;
                        // j$(item1[i - 1]).children('.ordernocls').val('' + line);
                        // j$(item1[i]).children('.ordernocls').val('' + i);
                    }
                    else {
                        j$(items[i]).children('.ordernocls').val(line);
                    }
                    var tr1 = j$(items[i]).parents("tr");
                    tr.prev().before(tr);
                    trL.prev().before(trL);
                }
                else {
                    if(line < currentPageRecordCount) {
                        var model1 = j$(item2[i]).find("span").text();
                        var model2 = j$(item2[line]).find("span").text();
                        if (model1 != model2) {
                            unblockUI();
                            return;
                        }
                        var tr = j$('#tableData').find('tbody').find('tr:eq(' + (i) + ')');
                        var trL = j$('#tableData_L').find('tbody').find('tr:eq(' + (i) + ')');
                        var v1 = j$(item1[i]).find("input").val();
                        var v2 = j$(item1[i + 1]).find("input").val();
                        setChangeFlg(i);
                        setChangeFlg(i + 1);
                        j$(items[i]).children('.ordernocls').val(line + 1);
                        j$(items[i + 1]).children('.ordernocls').val(line);
                        j$(item1[i]).find("input").val(v2);
                        j$(item1[line]).find("input").val(v1);
                        var tr1 = j$(items[i]).parents("tr");
                        tr.next().after(tr);
                        trL.next().after(trL);
                        isSuccessful = true;
                    }
                    else {
                        j$(items[i]).children('.ordernocls').val(line);
                    }
                }
                unblockUI();
                return isSuccessful;
            }
        }
        else {
            for(var i = parseInt(line) ; i < len && isSuccessful; i++ ) {
                isSuccessful = resetMoveUpDown(up, i, len);
            function refopener() {
                window.opener.location.href = '/apex/ConsumTrial?id={!parId}';
            }
        }
        unblockUI();
    }
    function resetMoveUpDown(up, line, len) {
            if (window.history.pushState) {
                if (window.location.href.indexOf('&saveType=1') > -1) {
                    refopener();
                }
                window.history.pushState({}, "", window.location.href.replace('&saveType=1', ''));
            }
        var items = j$(".dataCellBorder2");
        var item1 = j$("td.intf.dataCellBorder1.Degree_Of_Importance__c");
        var item2 = j$("td.dataCellBorder1.col_Fixture_Model_No__c");
        var currentPageRecordCount = j$(escapeVfId('allPage:allForm:dataBlock:currentPageRecordCnt')).val();
        var isSuccessful = false;
        // alert(item1);
        var i = line - 1;
        var i1 = line + 1;
        // var tr = j$('#tableData').find('tbody').find('tr:eq(' + (i) + ')');
        if (up == true){
            var tr = j$('#tableData').find('tbody').find('tr:eq(' + (i) + ')');
            var trL = j$('#tableData_L').find('tbody').find('tr:eq(' + (i) + ')');
            if(line != 1) {
                var model1 = j$(item2[i - 1]).find("span").text();
                var model2 = j$(item2[i]).find("span").text();
                if (model1 != model2) {
            //2022 02 24 张华建 display PI Data start
            var rowBList;
            var TrialUser = {};
            var ids = [];
            queryUser();
            function q1(){
                var p = new Promise(function(resolve, reject){
                    rowBList = JSON.parse('{!rowListString}')
                    var x = 0;
                    let searchCallBack = function searchCallBack(result){
                        let contacts = result.object;
                        if(contacts == null){
                            return;
                        }
                        let temp = {}
                        temp.trialUser = contacts.trialUser;
                        TrialUser[contacts.dataId] = temp;
                        x++;
                    };
                    for(var i=0;i<rowBList.length;i++){
                        ids.push(rowBList[i].rnd.AWS_Data_Id__c + '_' + rowBList[i].rnd.Id);
                        AWSService.query(staticResource.queryUrl,rowBList[i].rnd.AWS_Data_Id__c,searchCallBack,staticResource.token);
                    }
                    var id = setInterval(function(){
                        if(x >= rowBList.length){
                            console.log('success')
                            resolve('success');
                            clearInterval(id);
                        }
                    },1000);
                });
                return p;
            }
            function q2(value){
                var p = new Promise(function(resolve, reject){
                    console.log('进入q2'+value)
                    for(var i=0;i<ids.length;i++){
                        console.log('i = '+i);
                        document.getElementById(ids[i]).children[0].children[0].children[0].value = TrialUser[ids[i].substring(0,18)].trialUser;
                        console.log('i = '+i);
                    }
                });
            }
            function queryUser(){
                rowBList = JSON.parse('{!rowListString}')
                console.log('pageB.fixMode = '+'{!pageB.fixMode}')
                if('{!pageB.fixMode}' == 'true'){
                    q1().then(function(data){
                        return q2(data);
                    })
                    unblockUI();
                    return;
                }
                var v1 = j$(item1[i - 1]).find("input").val();
                var v2 = j$(item1[i]).find("input").val();
                setChangeFlg(i-1);
                setChangeFlg(i);
                j$(items[i - 1]).children('.ordernocls').val(line);
                j$(items[i]).children('.ordernocls').val(line - 1);
                j$(item1[i - 1]).find("input").val(v2);
                j$(item1[i]).find("input").val(v1);
                isSuccessful = true;
                // j$(item1[i - 1]).children('.ordernocls').val('' + line);
                // j$(item1[i]).children('.ordernocls').val('' + i);
            }
            else {
                j$(items[i]).children('.ordernocls').val(line);
            }
            var tr1 = j$(items[i]).parents("tr");
            tr.prev().before(tr);
            trL.prev().before(trL);
        }
        else {
            if(line < currentPageRecordCount) {
                var model1 = j$(item2[i]).find("span").text();
                var model2 = j$(item2[line]).find("span").text();
                if (model1 != model2) {
                }else{
                    blockme();
                    console.log(rowBList)
                    let searchCallBack = function searchCallBack(result){
                        let contacts = result.object;
                        if(contacts == null){
                            return;
                        }
                        let temp = {}
                        temp.trialUser = contacts.trialUser;
                        TrialUser[contacts.dataId] = temp;
                    };
                    for(var i=0;i<rowBList.length;i++){
                        ids.push(rowBList[i].rnd.AWS_Data_Id__c + '_' + rowBList[i].rnd.Id);
                        AWSService.query(staticResource.queryUrl,rowBList[i].rnd.AWS_Data_Id__c,searchCallBack,staticResource.token);
                    }
                    unblockUI();
                    return;
                }
                var tr = j$('#tableData').find('tbody').find('tr:eq(' + (i) + ')');
                var trL = j$('#tableData_L').find('tbody').find('tr:eq(' + (i) + ')');
                var v1 = j$(item1[i]).find("input").val();
                var v2 = j$(item1[i + 1]).find("input").val();
                setChangeFlg(i);
                setChangeFlg(i + 1);
                j$(items[i]).children('.ordernocls').val(line + 1);
                j$(items[i + 1]).children('.ordernocls').val(line);
                j$(item1[i]).find("input").val(v2);
                j$(item1[line]).find("input").val(v1);
                var tr1 = j$(items[i]).parents("tr");
                tr.next().after(tr);
                trL.next().after(trL);
                isSuccessful = true;
            }
            else {
                j$(items[i]).children('.ordernocls').val(line);
            function showPIDiv(awsDataId){
                if(awsDataId.length == 0){
                    return
                }
                console.log('awsDataId Value:'+awsDataId);
                let parentNode = document.getElementById(awsDataId);
                let createDiv = document.createElement("div");
                createDiv.id = awsDataId+"_PI";
                let piInformation = 'trialUser:'+TrialUser[awsDataId.substring(0,18)].trialUser
                //let piInformation = 'Name:'+contact['943114607025717249'].lastName +'\n' +'Phone:'+contact['943114607025717249'].phone
                createDiv.innerText = piInformation;
                let x=window.event.x;
                let y=window.event.y;
                createDiv.style.left=x;
                createDiv.style.top=y;
                createDiv.style.background="#dddddd";
                createDiv.style.position = "absolute";
                parentNode.appendChild(createDiv);
            }
        }
        unblockUI();
        return isSuccessful;
    }
    function refopener() {
        window.opener.location.href = '/apex/ConsumTrial?id={!parId}';
    }
    if (window.history.pushState) {
        if (window.location.href.indexOf('&saveType=1') > -1) {
            refopener();
        }
        window.history.pushState({},"", window.location.href.replace('&saveType=1',''));
    }
</script>
            function hidePIDiv(awsDataId){
                if(awsDataId.length == 0){
                    return
                }
                document.getElementById(awsDataId+'_PI').remove();
            }
            //2022 02 24 张华建 display PI Data end
        </script>
        <apex:pageMessages />
        <!-- oncomplete="clearApplyValue(); return false;" -->
        <apex:actionFunction name="passApplyMsgToController" action="{!showApplyMsg}"  rerender="allForm">
@@ -352,6 +458,15 @@
                                    <!-- 试用者 -->
                                    {!$ObjectType.Consum_Apply_Equipment_Set_Detail__c.fields.Trial_User__c.label}
                                    <apex:inputField id="TrialUser" value="{!pageB.caesdInput.Trial_User__c}"/>
                                    <!-- <script>
                                           sfdcPage.appendToOnloadQueue(function () {
                                            var queryBack = function queryBack(data) {
                                                console.log('data = ' + data);
                                                document.getElementById('{!pageB.caesdInput.AWS_Data_Id__c}') = data.object.trialUser;
                                            };
                                                AWSService.query(staticResources.queryUrl, '{!pageB.caesdInput.AWS_Data_Id__c}', queryBack, staticResources.token);
                                            });
                                    </script> -->
                                </td>
                                <td>
                                    <!-- 跟台者 -->
@@ -359,11 +474,11 @@
                                    <apex:inputField id="FollowerUser" value="{!pageB.caesdInput.Follower_User__c}"/>
                                </td>
                            </apex:outputPanel>
                        <!-- </tr> -->
                        <!-- <tr> -->
                            <!-- </tr> -->
                            <!-- <tr> -->
                            <td>
                            <!-- </td> -->
                            <!-- <td colspan="5"> -->
                                <!-- </td> -->
                                <!-- <td colspan="5"> -->
                                <span style="margin-left: 10px;">
                                    <apex:commandButton value="编辑" rendered="{!canEdit}" onclick="blockme();" action="{!changeFixModel}" reRender="allForm" oncomplete="unblockUI();windowResize();"/>
                                    <apex:commandButton value="编辑" style="float: right; margin-right: 40px;" rendered="{!AND(canEdit == false, redOnly == false)}" onclick="var w = window.open('/apex/ConsumTrial?id={!parId}&canedit=true', '编辑试用表画面', 'width='+(window.screen.width-200)+',height='+(window.screen.height-200)+',left=100,top=100'); w.focus(); return false;"/>
@@ -378,10 +493,10 @@
                        </tr>
                    </table>
                </apex:outputPanel>
                </apex:pageBlock>
                <apex:pageBlock id="dataBlock" tabStyle="Report">
            </apex:pageBlock>
            <apex:pageBlock id="dataBlock" tabStyle="Report">
                <apex:inputHidden id="currentPageRecordCnt" value="{!pageB.currentPageRecordCnt}"/>
<!--                     <table id="msgtable">
                <!--                     <table id="msgtable">
                <tr>
                    <td>
                        <apex:outputPanel id="message">
@@ -390,39 +505,39 @@
                    </td>
                </tr>
            </table> -->
            <div id="out_Div_L">
                <table class="list" style="border-bottom-width: 0px; font-size:11px; border-spacing:0;" border="" id="tableHeader_L">
                    <tr class="headerRow" height="30px">
                        <apex:outputPanel layout="none" rendered="{!canEdit}">
                            <td class="col_chk" align="center">
                                <input type='checkbox' onClick='checkAll()' id="checker" />
                            </td>
                        </apex:outputPanel>
                        <apex:repeat value="{!outputFieldList}" var="info">
                            <td class="col_{!info.value}">
                               {!info.label}
                            </td>
                        </apex:repeat>
                    </tr>
                </table>
            </div>
            <div id="out_Div" >
                <table class="list" style="border-bottom-width: 0px; font-size:11px; border-spacing:0;" border="" id="tableHeader">
                    <tr class="headerRow" height="30px">
                         <apex:repeat value="{!inputFieldList}" var="info">
                            <td class="col_{!info.value} colViewing" >
                               {!info.label}
                            </td>
                        </apex:repeat>
                        <td class="col_UpDown"> 向上/向下 </td>
                        <td class="col_Scroll"></td>
                    </tr>
                </table>
            </div>
            <div style="clear:both;"/>
            <div id="in_Div_L">
                <table class="list" style="border-bottom-width: 0px; font-size:11px; border-spacing:0;" border="" id="tableData_L">
                    <apex:variable value="{!0}" var="Cnt" />
                <div id="out_Div_L">
                    <table class="list" style="border-bottom-width: 0px; font-size:11px; border-spacing:0;" border="" id="tableHeader_L">
                        <tr class="headerRow" height="30px">
                            <apex:outputPanel layout="none" rendered="{!canEdit}">
                                <td class="col_chk" align="center">
                                    <input type='checkbox' onClick='checkAll()' id="checker" />
                                </td>
                            </apex:outputPanel>
                            <apex:repeat value="{!outputFieldList}" var="info">
                                <td class="col_{!info.value}">
                                    {!info.label}
                                </td>
                            </apex:repeat>
                        </tr>
                    </table>
                </div>
                <div id="out_Div" >
                    <table class="list" style="border-bottom-width: 0px; font-size:11px; border-spacing:0;" border="" id="tableHeader">
                        <tr class="headerRow" height="30px">
                            <apex:repeat value="{!inputFieldList}" var="info">
                                <td class="col_{!info.value} colViewing" >
                                    {!info.label}
                                </td>
                            </apex:repeat>
                            <td class="col_UpDown"> 向上/向下 </td>
                            <td class="col_Scroll"></td>
                        </tr>
                    </table>
                </div>
                <div style="clear:both;"/>
                <div id="in_Div_L">
                    <table class="list" style="border-bottom-width: 0px; font-size:11px; border-spacing:0;" border="" id="tableData_L">
                        <apex:variable value="{!0}" var="Cnt" />
                        <apex:repeat id="dataline_L" value="{!pageB.rowBList}" var="var">
                            <tr class="dataRow" id="tableData_L_{!Cnt}" style="{!IF(var.isOddnumber, 'background-color : #EFF4FC;', '')}">
                                <apex:outputPanel layout="none" rendered="{!canEdit}">
@@ -434,120 +549,120 @@
                                    <td class="dataCellBorder1 {!'col_' + info.value}"><apex:outputField value="{!var.rnd[info.value]}" /></td>
                                </apex:repeat>
                            </tr>
                        <apex:variable value="{!Cnt+1}" var="Cnt" />
                    </apex:repeat>
                </table>
            </div>
            <div id="in_Div" style="overflow:auto;">
                <table class="list" style="border-bottom-width: 0px; font-size:11px; border-spacing:0;" border="" id="tableData">
                    <apex:variable value="{!0}" var="Cnt_R" />
                    <apex:repeat id="dataline_R" value="{!pageB.rowBList}" var="var">
                    <tr id="tableData_R_{!Cnt_R}" class="dataRow" onmouseover="if (window.hiOn){hiOn(this);} " onmouseout="if (window.hiOff){hiOff(this);} " onblur="if (window.hiOff){hiOff(this);}" onfocus="if (window.hiOn){hiOn(this);}" style="{!IF(var.isOddnumber, 'background-color : #EFF4FC;', '')}">
                        <apex:repeat value="{!inputFieldList}" var="info" id="inputField">
                            <td class="dataCellBorder1 intf {!info.value} col_{!info.value}">
                                <apex:outputPanel rendered="{!(contains(var.canChangeField, info.value) || var.canChangeField == '') && pageB.fixMode == true && var.canChange == true && info.value != 'Degree_Of_Importance__c'}">
                                    <!-- onchange="setChangeFlg('{!var.lineNo}')" -->
                                    <apex:outputPanel rendered="{!info.value != 'Case_OR_animal_organ__c'}">
                                        <apex:inputField id="inputField" value="{!var.rnd[info.value]}" onchange="setChangeFlg('{!var.lineNo - 1}')" style="{!IF(info.value == 'Follower_User__c', 'width: 75%; ', '')}"/>
                                        <script>
                                            if( document.getElementById('{!$Component.inputField}' + ':inputField_mlktp')){
                                                document.getElementById('{!$Component.inputField}' + ':inputField_mlktp').style.display="none" ;
                                            }
                                        </script>
                                    </apex:outputPanel>
                                    <apex:outputPanel rendered="{!info.value == 'Case_OR_animal_organ__c'}">
                                    <apex:selectList value="{!var.rnd.Case_OR_animal_organ__c}" multiselect="false" size="1">
                                            <apex:selectOptions value="{!Case_OR_animal_organOps}"/>
                                        </apex:selectList>
                                    </apex:outputPanel>
                                </apex:outputPanel>
                                <apex:outputPanel rendered="{!(contains(var.canChangeField, info.value) || var.canChangeField == '') && pageB.fixMode == true && var.canChange == true && info.value == 'Degree_Of_Importance__c'}">
                                    <input id="Degree_Of_Importance__c" value="{!var.rnd[info.value]}" disabled="true"/>
                                    <apex:inputHidden value="{!var.rnd[info.value]}"/>
                                </apex:outputPanel>
                                <apex:outputPanel rendered="{!((contains(var.canChangeField, info.value) || var.canChangeField == '') && pageB.fixMode == true && var.canChange == true) == false}">
                                    <apex:outputField value="{!var.rnd[info.value]}"/>
                                </apex:outputPanel>
                            </td>
                            <apex:variable value="{!Cnt+1}" var="Cnt" />
                        </apex:repeat>
                        <td class="dataCellBorder2 col_UpDown" id="row{!Cnt_R}">
                            <apex:outputPanel rendered="{!pageB.fixMode}">
                                <button value="↑↑" id="top" onclick="blockme(); moveToTop('row{!Cnt_R}', true, '{!var.maxDegree_Of_Importance}'); return false;">↑↑</button>
                                <button value="↑" id="up" onclick="blockme(); resetMove('row{!Cnt_R}', true, '{!var.maxDegree_Of_Importance}'); return false;">↑</button>|
                                <button value="↓" id="down" onclick="blockme(); resetMove('row{!Cnt_R}', false, '{!var.maxDegree_Of_Importance}'); return false;">↓</button>
                                <button value="↓↓" id="bottom" onclick="blockme(); moveToTop('row{!Cnt_R}', false, '{!var.maxDegree_Of_Importance}'); return false;">↓↓</button>
                            </apex:outputPanel>
                            <apex:inputText value="{!var.lineNo}" styleClass="ordernocls" style="display:none;"/>
                            <!-- <apex:inputHidden value="{!var.rnd.Degree_Of_Importance__c}"/> -->
                        </td>
                        <td class="col_Scroll"></td>
                    </tr>
                    <apex:variable value="{!Cnt_R+1}" var="Cnt_R" />
                    </apex:repeat>
                </table>
            </div>
                    </table>
                </div>
                <div id="in_Div" style="overflow:auto;">
                    <table class="list" style="border-bottom-width: 0px; font-size:11px; border-spacing:0;" border="" id="tableData">
                        <apex:variable value="{!0}" var="Cnt_R" />
                        <apex:repeat id="dataline_R" value="{!pageB.rowBList}" var="var">
                            <tr id="tableData_R_{!Cnt_R}" class="dataRow" onmouseover="if (window.hiOn){hiOn(this);} " onmouseout="if (window.hiOff){hiOff(this);} " onblur="if (window.hiOff){hiOff(this);}" onfocus="if (window.hiOn){hiOn(this);}" style="{!IF(var.isOddnumber, 'background-color : #EFF4FC;', '')}">
                                <apex:repeat value="{!inputFieldList}" var="info" id="inputField">
                                    <td class="dataCellBorder1 intf {!info.value} col_{!info.value}" id="{! IF(info.value=='Trial_User__c',var.rnd.AWS_Data_Id__c+'_'+var.rnd.Id,info.value)}" onmouseover="showPIDiv('{! IF(info.value=='Trial_User__c',var.rnd.AWS_Data_Id__c+'_'+var.rnd.Id,'')}')" onmouseout="hidePIDiv('{! IF(info.value=='Trial_User__c',var.rnd.AWS_Data_Id__c+'_'+var.rnd.Id,'')}')">
                                        <apex:outputPanel rendered="{!(contains(var.canChangeField, info.value) || var.canChangeField == '') && pageB.fixMode == true && var.canChange == true && info.value != 'Degree_Of_Importance__c'}">
                                            <!-- onchange="setChangeFlg('{!var.lineNo}')" -->
                                            <apex:outputPanel rendered="{!info.value != 'Case_OR_animal_organ__c'}">
                                                <apex:inputField id="inputField" value="{!var.rnd[info.value]}" onchange="setChangeFlg('{!var.lineNo - 1}')" style="{!IF(info.value == 'Follower_User__c', 'width: 75%; ', '')}"/>
                                                <script>
                                                    if( document.getElementById('{!$Component.inputField}' + ':inputField_mlktp')){
                                                        document.getElementById('{!$Component.inputField}' + ':inputField_mlktp').style.display="none" ;
                                                    }
                                                </script>
                                            </apex:outputPanel>
                                            <apex:outputPanel rendered="{!info.value == 'Case_OR_animal_organ__c'}">
                                                <apex:selectList value="{!var.rnd.Case_OR_animal_organ__c}" multiselect="false" size="1">
                                                    <apex:selectOptions value="{!Case_OR_animal_organOps}"/>
                                                </apex:selectList>
                                            </apex:outputPanel>
                                        </apex:outputPanel>
                                        <apex:outputPanel rendered="{!(contains(var.canChangeField, info.value) || var.canChangeField == '') && pageB.fixMode == true && var.canChange == true && info.value == 'Degree_Of_Importance__c'}">
                                            <input id="Degree_Of_Importance__c" value="{!var.rnd[info.value]}" disabled="true"/>
                                            <apex:inputHidden value="{!var.rnd[info.value]}"/>
                                        </apex:outputPanel>
                                        <apex:outputPanel rendered="{!((contains(var.canChangeField, info.value) || var.canChangeField == '') && pageB.fixMode == true && var.canChange == true) == false}">
                                            <apex:outputField value="{!var.rnd[info.value]}"/>
                                        </apex:outputPanel>
                                    </td>
                                </apex:repeat>
                                <td class="dataCellBorder2 col_UpDown" id="row{!Cnt_R}">
                                    <apex:outputPanel rendered="{!pageB.fixMode}">
                                        <button value="↑↑" id="top" onclick="blockme(); moveToTop('row{!Cnt_R}', true, '{!var.maxDegree_Of_Importance}'); return false;">↑↑</button>
                                        <button value="↑" id="up" onclick="blockme(); resetMove('row{!Cnt_R}', true, '{!var.maxDegree_Of_Importance}'); return false;">↑</button>|
                                        <button value="↓" id="down" onclick="blockme(); resetMove('row{!Cnt_R}', false, '{!var.maxDegree_Of_Importance}'); return false;">↓</button>
                                        <button value="↓↓" id="bottom" onclick="blockme(); moveToTop('row{!Cnt_R}', false, '{!var.maxDegree_Of_Importance}'); return false;">↓↓</button>
                                    </apex:outputPanel>
                                    <apex:inputText value="{!var.lineNo}" styleClass="ordernocls" style="display:none;"/>
                                    <!-- <apex:inputHidden value="{!var.rnd.Degree_Of_Importance__c}"/> -->
                                </td>
                                <td class="col_Scroll"></td>
                            </tr>
                            <apex:variable value="{!Cnt_R+1}" var="Cnt_R" />
                        </apex:repeat>
                    </table>
                </div>
            </apex:pageBlock>
<script type="text/javascript">
    function runSFDCAddRemote(MetadataConnectionWarning) {
        if (MetadataConnectionWarning) SFDCAddRemote('{!$Api.Session_ID}');
    }
    function sortTableJs(key) {
      // blockme();
      sortTablefunc(key);
    }
            <script type="text/javascript">
                function runSFDCAddRemote(MetadataConnectionWarning) {
                    if (MetadataConnectionWarning) SFDCAddRemote('{!$Api.Session_ID}');
                }
                function sortTableJs(key) {
                    // blockme();
                    sortTablefunc(key);
                }
    j$(function() {
        var tableWidth = 0;
        j$('body .pbBody table#tableHeader tr.headerRow td').each(function() {
            var colClass = getColClassName(this);
            if (colClass != 'col_Scroll') {
                var headerCol = j$('body .pbBody table.list tr.headerRow td.' + colClass);
                tableWidth += headerCol.width();
            }
        });
        j$('table#tableData').css('width', (1260 + 2) + 'px');
        j$('table#tableHeader').css('width', (1260 + 2) + 'px');
                j$(function() {
                    var tableWidth = 0;
                    j$('body .pbBody table#tableHeader tr.headerRow td').each(function() {
                        var colClass = getColClassName(this);
                        if (colClass != 'col_Scroll') {
                            var headerCol = j$('body .pbBody table.list tr.headerRow td.' + colClass);
                            tableWidth += headerCol.width();
                        }
                    });
                    j$('table#tableData').css('width', (1260 + 2) + 'px');
                    j$('table#tableHeader').css('width', (1260 + 2) + 'px');
        // list の headerRow の tdに toggleWidth() を追加
        bindTdToggleWidth();
        if( document.getElementById('allPage:allForm:searchBlock:FollowerUser_mlktp')){
            document.getElementById('allPage:allForm:searchBlock:FollowerUser_mlktp').style.display="none" ;
        }
    });
    // var elements = document.getElementsByTagName("select");
    // for (i = 0; i < elements.length; i++) {
    //     var id = elements[i].id;
    //     if (id.length > 5 && id.substring(id.length - 5, id.length) == 'mlktp') {
    //         elements[i].style.display = "none";
    //     }
    // }
    // var tbl_l = document.getElementById("tableData_L");
    // var input_l = tbl_l.getElementsByTagName("input");
    // for (i = 0; i < input_l.length; i++) {
    //     var id = input_l[i].id + '_lkid';
    //     if (document.getElementById(id) != null) {
    //         input_l[i].style.width = "75%";
    //     }
    // }
    // var tbl = document.getElementById("tableData");
    // var input = tbl.getElementsByTagName("input");
    // for (i = 0; i < input.length; i++) {
    //     var id = input[i].id + '_lkid';
    //     if (document.getElementById(id) != null) {
    //         input[i].style.width = "75%";
    //     }
    // }
    //aをクリックする際に、tdイベントを実装しない
    // j$("a[name='out_Div_a']").bind("click",function(event){
    //     event.stopPropagation();
    // });
    windowResize();
    j$("td.dataCellBorder1 input").change(function(){
        var names = this.name.split(':');
        var i = names[names.length - 4];
        j$("input.rowchkcls")[i].checked = true;
    })
</script>
                    // list の headerRow の tdに toggleWidth() を追加
                    bindTdToggleWidth();
                    if( document.getElementById('allPage:allForm:searchBlock:FollowerUser_mlktp')){
                        document.getElementById('allPage:allForm:searchBlock:FollowerUser_mlktp').style.display="none" ;
                    }
                });
                // var elements = document.getElementsByTagName("select");
                // for (i = 0; i < elements.length; i++) {
                //     var id = elements[i].id;
                //     if (id.length > 5 && id.substring(id.length - 5, id.length) == 'mlktp') {
                //         elements[i].style.display = "none";
                //     }
                // }
                // var tbl_l = document.getElementById("tableData_L");
                // var input_l = tbl_l.getElementsByTagName("input");
                // for (i = 0; i < input_l.length; i++) {
                //     var id = input_l[i].id + '_lkid';
                //     if (document.getElementById(id) != null) {
                //         input_l[i].style.width = "75%";
                //     }
                // }
                // var tbl = document.getElementById("tableData");
                // var input = tbl.getElementsByTagName("input");
                // for (i = 0; i < input.length; i++) {
                //     var id = input[i].id + '_lkid';
                //     if (document.getElementById(id) != null) {
                //         input[i].style.width = "75%";
                //     }
                // }
                //aをクリックする際に、tdイベントを実装しない
                // j$("a[name='out_Div_a']").bind("click",function(event){
                //     event.stopPropagation();
                // });
                windowResize();
                j$("td.dataCellBorder1 input").change(function(){
                    var names = this.name.split(':');
                    var i = names[names.length - 4];
                    j$("input.rowchkcls")[i].checked = true;
                })
            </script>
        </apex:outputPanel>
    </apex:form>
</apex:page>
force-app/main/default/pages/ConsumTrialPDF.page
@@ -1,5 +1,5 @@
<apex:page applyHtmlTag="false" Controller="ConsumTrialPDFController" showHeader="false" sidebar="false" id="allPage" action="{!init}" renderAs="pdf">
<!-- renderAs="pdf" -->
<apex:page applyHtmlTag="false" Controller="ConsumTrialPDFController" showHeader="false" sidebar="false" id="allPage" action="{!init}">
<!-- renderAs="pdf" -->
    <html>
        <head>
            <style type="text/css" media="print">
@@ -39,16 +39,66 @@
                }
            </style>
            <style>
                /* 20220221 PI改造 by 徐亮 start */
                body {
                    font-family: Arial Unicode MS;
                    page-break-inside: auto;
                    font-size: 14px;
                }
                table {
                    border-collapse: collapse;
                    width: 100%;
                }
                table, th, td {
                    border: 1px solid black;
                    text-align: left;
                }
                table.headTable tr td {
                    font-size: 13px;
                }
                table.deliInfoTable tr td {
                    font-size: 13px;
                }
                table.detailListTable tr td {
                    font-size: 8px;
                    text-align: left;
                    box-sizing:border-box;
                    padding: 1px;
                }
                table.tailTable tr td {
                    font-size: 12px;
                }
                body{margin: 0 auto;width: 920px;font-size: 14px;}
                #title1{height: 30px;}
                #title2{height: 80px;}
                #pdf-wrapper {position: relative;}
                #pdf-wrapper table{width: 100%;border-spacing: 0px;border-collapse: collapse;    border: none;}
                #pdf-wrapper table th,td{border-bottom: 1px #000 solid;}
                /* 20220221 PI改造 by 徐亮 end */
            </style>
            <!-- 20220221 PI改造 by 徐亮 start  -->
        <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
        <script src="../../soap/ajax/53.0/connection.js" type="text/javascript"></script>
        <apex:stylesheet value="{!URLFOR($Resource.blockUIcss)}"/>
        <apex:includeScript value="{!URLFOR($Resource.jquery183minjs)}"/>
        <apex:includeScript value="{!URLFOR($Resource.PleaseWaitDialog)}"/>
        <apex:includeScript value="{!URLFOR($Resource.jspdf)}"/>
        <apex:includeScript value="{!URLFOR($Resource.html2canvas)}"/>
        <!-- 20220221 PI改造 by 徐亮 end  -->
        </head>
        <body>
            <div id="pdf-wrapper">
                <div id="title1"></div>
            <!-- 页码 -->
            <apex:variable value="{!1}" var="pageCnt" />
            <!-- 借用耗材备品发货清单 -->
            <!-- 序号 -->
            <apex:variable value="{!1}" var="lineCnt" />
            <apex:repeat value="{!pdfPageList}" var="eachPdfPage">
                <img style="float:left;width:79px;height:79px;padding:0px;margin-top:1px;z-index:999;position:relative;"
                        src="{!'/servlet/servlet.FileDownload?file=' + targetConsumApply.QRId__c}" />
                <img style="width:79px;height:79px;padding:0px;margin-top:1px;z-index:999;position:absolute;"
                        src="{!QRSrc}" />
                <!-- 表头 -->
                <table class="headTable" style="position:relative;">
                    <colgroup>
@@ -197,10 +247,10 @@
                    </colgroup>
                    <apex:outputPanel layout="none" rendered="{!eachPdfPage.equipSetDetailList.size > 0}">
                        <tr>
                            <th style="text-align:center;" colspan="14" height="25">借用耗材备品发货清单</th>
                            <th style="text-align:center;" colspan="12" height="25">借用耗材备品发货清单</th>
                        </tr>
                        <tr>
                            <th style="text-align:center; font-size:10px;" colspan="14" height="25">共计耗材备品({!consumApplySetDetailListSize})件</th>
                            <th style="text-align:center; font-size:10px;" colspan="12" height="25">共计耗材备品({!consumApplySetDetailListSize})件</th>
                        </tr>
                        <tr>
                            <td style="text-align: center;"><c:PDFWbr targetStr="序号"/></td>
@@ -254,7 +304,7 @@
                            <!-- 病例/动物脏器 -->
                            <td><c:PDFWbr targetStr="{!eachEquipSetDetail.Case_OR_animal_organ__c}"/></td>
                            <!-- 试用者盖章 -->
                            <td><c:PDFWbr targetStr="{!eachEquipSetDetail.Trial_User__c}"/></td>
                            <td aws-data-id="{!eachEquipSetDetail.AWS_Data_Id__c}"><c:PDFWbr targetStr="{!eachEquipSetDetail.Trial_User__c}"/></td>
                            <!-- 跟台者盖章 -->
                            <td><c:PDFWbr targetStr="{!eachEquipSetDetail.Follower_User__r.Name}"/></td>
                            <!-- 备用 -->
@@ -283,8 +333,7 @@
                    <!-- 20211210 ljh SFDC-C923SR add -->
                    <tr>
                        <td colspan="2" style=" border: none;">
                            <img align="left" src="{!'/servlet/servlet.FileDownload?file=' + targetConsumApply.BRId__c}" />
                            <img align="left" src="{!BRSrc}" />
                        </td>
                    </tr>
                    <!-- 20211210 ljh SFDC-C923SR end -->
@@ -294,6 +343,107 @@
                </apex:outputPanel>
                <apex:variable value="{!pageCnt + 1}" var="pageCnt" />
            </apex:repeat>
        </div>
        </body>
        <!-- 20220221 PI改造 by 徐亮 start  -->
<script>
    AWSService.sfSessionId = '{!GETSESSIONID()}';
    var staticResource = JSON.parse('{!staticResource}');
    function Fun(pdf){
        var iframe = document.createElement('iframe');
        iframe.setAttribute('style', 'position:absolute;right:0; top:0; bottom:0; height:100%; width:100%');
        document.body.appendChild(iframe);
        iframe.src = pdf.output('datauristring');
        for(let e of document.body.childNodes){
            if( e != iframe && e.style){
                e.style.display = 'none';
            }
        }
    }
    let id = "pdf-wrapper";
    var target = document.getElementById(id);
    function jsPdfDownload(){
        let pdfName = "测试";
        let id = "pdf-wrapper";
        var target = document.getElementById(id);
        target.style.background = "#FFFFFF";
        if(pdfName==''||pdfName==undefined) pdfName= getNowFormatDate();
        html2canvas(target, {
            scale: 2,
            onrendered:function(canvas) {
                var contentWidth = canvas.width;
                var contentHeight = canvas.height;
                //一页pdf显示html页面生成的canvas高度;
                var pageHeight = contentWidth / 592.28 * 841.89;
                //未生成pdf的html页面高度
                var leftHeight = contentHeight;
                //页面偏移
                var position = 0;
                //a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
                var imgWidth = 515.28;//595.28//左右边距20
                var imgHeight = 515.28/contentWidth * contentHeight;//左右边距20
                var pageData = canvas.toDataURL('image/jpeg', 1.0);
                var pdf = new jsPDF('', 'pt', 'a4');
                //有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
                //当内容未超过pdf一页显示的范围,无需分页
                if (leftHeight < pageHeight) {
                    pdf.addImage(pageData, 'JPEG', 40, 0, imgWidth, imgHeight );//左右边距20
                } else {
                    while(leftHeight > 0) {
                        pdf.addImage(pageData, 'JPEG', 40, position, imgWidth, imgHeight)//左右边距20
                        leftHeight -= pageHeight;
                        position -= 841.89;
                        //避免添加空白页
                        if(leftHeight > 0) {
                            pdf.addPage();
                        }
                    }
                }
                Fun(pdf);
            }
        })
    }
    blockme();
    document.body.onload = function(){
        let aws_ids = [];
        j$("[aws-data-id]").each(function(i,e){
            let id = j$(e).attr('aws-data-id');
            if (id) {
                aws_ids.push(id);
            }
        })
        AWSService.search(staticResource.searchUrl, JSON.stringify({
            dataIds:aws_ids
        }), function(data){
            unblockUI();
            if (data && data.object && data.object.length > 0) {
                for (const d of data.object) {
                    j$("[aws-data-id='"+d.dataId +"']").html(d.trialUser);
                }
            }
            //document.getElementById("Responsible_Person_HP__c").innerHTML = data.object.responsiblePersonHP;
            //document.getElementById("Caller_phone__c").innerHTML = data.object.callerPhone;
            setTimeout(() => {
                jsPdfDownload();
            }, 1500);
        }, staticResource.token);
    }
    document.body.onclick = function(){
        //jsPdfDownload();
    }
</script>
<!-- 20220221 PI改造 by 徐亮 end  -->
    </html>
</apex:page>
force-app/main/default/pages/FixtureRentalPDF.page
@@ -1,350 +1,446 @@
<apex:page applyHtmlTag="false" Controller="FixtureRentalPDFController" showHeader="false" sidebar="false" id="allPage" action="{!init}" renderAs="pdf" ><!-- renderAs="pdf" -->
<html>
    <head>
         <style type="text/css" media="print">
            @page {
                size: A4;
                margin: 1mm 2.5mm 0mm 2.5mm;
<apex:page applyHtmlTag="false" Controller="FixtureRentalPDFController" showHeader="false" sidebar="false" id="allPage" action="{!init}" ><!-- renderAs="pdf" -->
    <html>
        <head>
            <style type="text/css" media="print">
                @page {
                    size: A4;
                    margin: 1mm 2.5mm 0mm 2.5mm;
                }
                /*td{
                    height: 23px;
                }*/
            </style>
            <style>
                body{margin: 0 auto;
                    width: 780px;}
                    #title1{height: 30px;}
                    #title2{height: 110px;}
            </style>
            <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
            <script src="../../soap/ajax/53.0/connection.js" type="text/javascript"></script>
            <apex:stylesheet value="{!URLFOR($Resource.blockUIcss)}"/>
            <apex:includeScript value="{!URLFOR($Resource.jquery183minjs)}"/>
            <apex:includeScript value="{!URLFOR($Resource.PleaseWaitDialog)}"/>
            <apex:includeScript value="{!URLFOR($Resource.jspdf)}"/>
            <apex:includeScript value="{!URLFOR($Resource.html2canvas)}"/>
        </head>
        <body style="font-family: Arial Unicode MS; page-break-inside: auto;font-size: 14px">
            <div id="pdf-wrapper">
                <apex:outputPanel id="showhidden" rendered="true">
                    <!-- 20201119 LJH OCSM_BP5-61 update start 现地管理和现地管理的主单不显示-->
                    <!-- <apex:outputText style="float:left;font-size:22px;margin-top: 25px;" value="{!centreAddress}" /> -->
                    <apex:outputText style="float:left;font-size:22px;margin-top: 25px;" value="{!IF(IsShowLU,centreAddress,'')}" />
                    <!-- 20201119 LJH OCSM_BP5-61 update end 现地管理和现地管理的主单不显示-->
                    <img style="float: right; width: 55px; height: 55px;padding: 0px;margin-top: 12px;" src="{!qrcode}" />
                    <table border="1" width="100%" style="border-collapse: collapse;margin-top: 18mm;">
                        <colgroup>
                            <col width="50%" />
                            <col width="50%" />
                        </colgroup>
                        <tr>
                            <th style="text-align:center;" colspan="2" height="38">奥林巴斯备品签收单
                                <!-- <img style="float: right; width: 35px; height: 35px;padding: 0px;margin-top: -7px;" src="{!'/servlet/servlet.FileDownload?file=' + ApplyHeadShow.QRId__c}" /> -->
                            </th>
                        </tr>
                        <tr>
                            <td style="text-align:left;border-right-style: none;">★填写完整后请自发货日起10天内上传SFDC</td>
                            <td style="text-align:right;border-left-style: none;">备品管理中心申请单号:<apex:outputText value="{!ApplyHeadShow.Name}" /></td>
                        </tr>
                        <!-- <tr style="background-color:#003399;color:white">
                            <th style="text-align:center;" height="40">发货信息</th>
                        </tr> -->
                        <!-- <tr>
                            <td style="text-align:left;font-size:12px">
                1、本发货确认单共两页。首页中到货确认部分为现场必填项目,填写完整后请回传至备品中心(传真或扫描件即可);<br />
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;末页中清洗消毒灭菌确认栏为现场必填项目,备品回寄时请将此页随备品一同寄回备品中心。<br />
                2、请对产品进行清洗消毒或灭菌后再使用。<br />
                3、在使用备品前,敬请仔细阅读背面“备品使用须知”,请明确申请人及申请方责任与义务。
                            </td>
                        </tr> -->
                    </table>
                    <table border="1px" width="100%" style="border-collapse: collapse;">
                        <colgroup>
                            <col width="16%" />
                            <col width="14%" />
                            <col width="36%" />
                            <col width="16%" />
                            <col width="18%" />
                        </colgroup>
                        <tr>
                            <th style="text-align:center;" colspan="5" height="25">发货信息</th>
                        </tr>
                        <tr>
                            <td style="text-align:left;">使用目的</td> <td style="text-align:left;font-size: 13px" colspan="4"><apex:outputText value="{!ApplyHeadShow.Demo_purpose1__c}" /></td>
                        </tr>
                        <tr>
                            <td style="text-align:left;" rowspan="2">申请人信息</td>
                            <td style="text-align:left;">所属本部名</td> <td   style="text-align:left;font-size: 13px">     <apex:outputText value="{!ApplyHeadShow.Salesdept__c}" /></td>
                            <td style="text-align:left;" >所属办事处名</td> <td   style="text-align:left;font-size: 13px">        <apex:outputText value="{!ApplyHeadShow.WorkPlace__c}" /></td>
                        </tr>
                        <tr>
                            <td style="text-align:left;" >姓名 </td> <td  style="text-align:left;font-size: 13px">    <apex:outputText value="{!ApplyHeadShow.Person_In_Charge__r.name}" /></td>
                            <td style="text-align:left;" colspan="1">联系电话</td> <td  style="text-align:left;font-size: 13px">     <apex:outputText value="{!ApplyHeadShow.ApplyPerson_Phone__c}" /></td>
                        </tr>
                        <tr>
                            <td style="text-align:left;" >医疗机构信息</td>
                            <td style="text-align:left;" >医疗机构名</td> <td style="text-align:left;font-size: 13px"> <apex:outputText value="{!HospitalName}" /></td>
                            <td style="text-align:left;" >科室名</td> <td  style="text-align:left;font-size: 13px"><apex:outputText value="{!ApplyHeadShow.Account__r.Department_Name__c}" /></td>
                        </tr>
                        <tr>
                            <td style="text-align:left;" rowspan="3" >发货地址</td> <td colspan="2" rowspan="3" style="text-align:left;font-size: 13px"> <apex:outputText id="Shippmentadress" value="{!Shippmentadress}" /></td>
                            <td style="text-align:left;" colspan="1">邮编</td> <td  style="text-align:left;"> <apex:outputText value="{!IF(ApplyHeadShow.Shipment_address__r.Post_Code__c==null,ApplyHeadShow.Post_Code__c,ApplyHeadShow.Shipment_address__r.Post_Code__c)}" /></td>
                        </tr>
                        <tr>
                            <td style="text-align:left;" colspan="1">接收人姓名</td> <td  style="text-align:left;font-size: 13px">  <apex:outputText value="{!ApplyHeadShow.Loaner_received_staff__c}" /></td>
                        </tr>
                        <tr>
                            <td style="text-align:left;" colspan="1">接收人电话</td> <td style="text-align:left;font-size: 13px">  <apex:outputText value="{!ApplyHeadShow.Loaner_received_staff_phone__c}" /></td>
                        </tr>
                    </table>
                    <table border="1" width="100%" style="border-collapse: collapse;">
                        <tr>
                            <th style="text-align:center;" colspan="4" height="25">医院借用期限</th>
                        </tr>
                        <tr>
                            <td style="text-align:left;"> {!IF(BorrowTimeString='null','',BorrowTimeString)}&nbsp;&nbsp;&nbsp;</td>
                        </tr>
                    </table>
                    <table border="1" width="100%" style="border-collapse: collapse;">
                        <colgroup>
                            <col width="19%" />
                            <col width="29%" />
                            <col width="29%" />
                            <col width="23%" />
                        </colgroup>
                        <tr>
                            <th style="text-align:center;" colspan="4" height="40"> 奥林巴斯备品借用申请・安装人填写栏<small>(必填)</small><br/>到货确认部分为奥林巴斯员工必填项目</th>
                        </tr>
                        <tr>
                            <td style="text-align:left;" >签收者姓名</td> <td style="text-align:left;"></td>
                            <td style="text-align:left;">备品安装者姓名</td> <td  style="text-align:left;"></td>
                        </tr>
                        <tr>
                            <td style="text-align:left;">签收日期</td> <td  style="text-align:left;"></td>
                            <td style="text-align:left;">安装及安装说明日期</td> <td  style="text-align:left;"> </td>
                        </tr>
                    </table>
                    <table border="1" width="100%" style="border-collapse: collapse;">
                        <colgroup>
                            <col width="19%" />
                            <col width="29%" />
                            <col width="29%" />
                            <col width="23%" />
                        </colgroup>
                        <tr>
                            <th style="text-align:center;" colspan="4" height="40"> 医疗机构签收填写栏<small>(必填)</small><br/>敬请使用备品前仔细阅读下方“奥林巴斯备品借用须知”,以明确使用方的责任与义务</th>
                        </tr>
                        <!--根据OLY_OCM-260记载,先注释掉(OLY_OCM-251取消注释) -->
                        <tr><th style="text-align:center;" height="25" colspan="4">《奥林巴斯备品发货清单》所列备品悉数收到,
                        共计主机{!mainCnt}件,附属品{!accessoryCnt}件;并已接受产品使用说明和了解借用须知。</th></tr>
                        <tr>
                            <td style="text-align:left;" >签收者姓名</td> <td style="text-align:left;"></td>
                            <td style="text-align:left;" rowspan="2">接收单位(科室)章 </td>
                            <td style="text-align:left;" rowspan="2"> </td>
                        </tr>
                        <tr>
                            <td style="text-align:left;">签收日期</td> <td  style="text-align:left;"></td>
                        </tr>
                    </table>
                    <table border="1" width="100%" style="border-collapse: collapse;">
                        <colgroup>
                            <col width="100%" />
                        </colgroup>
                        <tr>
                            <th style="text-align:center;" height="25">※奥林巴斯备品借用须知</th>
                        </tr>
                        <tr>
                            <td style="text-align:left;font-size: 12px">
                1,备品:本须知所指的备品,是指本签收单附件《奥林巴斯备品发货清单》所列的由奥林巴斯(北京)销售服务有限公司(以下简称奥林<br/>巴斯)在规定期限内免费提供给借用单位为实施医疗行为或培训等所使用的设备包括产品及相关附属品,附件是本须知有效组成部分,与本<br/>须知具有同等法律效力。<br/>
                2,备品所有权:备品所有权归属于奥林巴斯公司。未经奥林巴斯公司书面同意,借用单位不得以任何理由向任何第三方转借、转让附件所<br/>列备品,或将附件所列备品作为担保抵押给任何第三方。<br/>
                3,备品使用权:借用期限内,借用单位对出借的备品享有独立合理的使用权利。若在使用过程中存在不确定情况时,借用单位应及时通知<br/>奥林巴斯公司,奥林巴斯公司将到场给予指导和协助,借用单位不应擅自处理。<br/>
                4,备品之日常使用与维护:借用单位在使用备品过程中应按照奥林巴斯公司的要求(“产品使用说明书”)内容尽审慎义务正确操作使用、<br/>爱护使用。备品使用前后都应进行必要的清洗消毒(灭菌)及日常检测工作,以确保备品的正常运作。<br/>
                5,备品损坏、遗失之赔偿责任:附件所列备品若因正常损耗而产生的维修或维护费用,由奥林巴斯公司承担;若因借用单位使用不当或超<br/>期借用等原因造成的备品损坏,借用单位应承担相关维修费用。当备品借用中发生故障需要维修时,应联系奥林巴斯进行检测和维修,不得<br/>擅自将相关备品交由任何第三方维修。若因借用单位原因造成备品遗失时,则借用单位应负赔偿责任。<br/>
                6,医疗责任事故:备品是符合国家质量标准并经检验合格的医疗器械产品,借用单位应独立依靠其医疗专业水平和能力利用备品进行医疗<br/>活动或培训。借用单位使用备品时所发生的任何问题均由借用单位自行负责、处理。<br/>
                7,备品返还:借用单位应按照本单注明的使用期限履行按时返还备品的承诺。返回前,借用单位应对备品进行清洗消毒或灭菌,以保证所<br/>有备品接触者的健康安全,同时借用单位有义务为奥林巴斯公司回收备品提供必要协助。<br/>
                8,借用单位知悉且同意,此次备品出借基于正当合理的理由,而非通过出借备品对借用单位购买、推荐奥林巴斯公司产品、服务等产生任<br/>何不正当影响。<br/>
                9,借用单位应严格按本单所载使用目的使用备品,禁止将备品用于本单所载使用目的以外的其他用途。<br/>
                10,若借用单位选择以加盖实际接收备品的借用单位内部部门章或签收者签名方式确认以上内容,实际接收备品的借用单位内部部门或签<br/>收者确认其具备相应资格代表借用单位进行签收和确认。<br/>
                11,其它:其它未尽事宜,双方应本着友好合作的原则进行协商解决。
                            </td>
                            <!-- 20211008 ljh SFDC-C7L4ED 增加8,9,10-->
                        </tr>
                        <tr>
                            <td style="text-align:left;font-size:12px;border-collapse: collapse;" colspan="2" height="80">
                奥林巴斯 北京备品中心地址:北京市朝阳区酒仙桥路10号恒通商务园B12C座西门1F<br />
                邮编:100015     TEL:010-59756006-1871    FAX: 010-59756534<br />
                奥林巴斯 广州备品中心地址:广州市番禺区东环街番禺大道北537号番山创业中心3号楼1F<br />
                邮编:511400     TEL:020-39198888-8876     FAX:020-39198848<br />
                奥林巴斯 上海备品中心地址:上海市浦东新区金吉路778号3号楼1F<br />
                邮编:201206    TEL:021-60391318-8877    FAX:021-60391316<br />
                            </td>
                            <!-- 20210812 SFDC-C5CC5S 修改地址-->
                        </tr>
                    </table>
                    <apex:outputPanel layout="none">
                        <div style="page-break-after: always;"/>
                    </apex:outputPanel>
                <apex:variable value="{!1}" var="pNcnt" />
                <apex:variable value="{!1}" var="pcnt" />
                <apex:repeat value="{!records}" var="record">
                    <div style="{position:absolute;width:100%;height:15px">&nbsp;</div>
                    <!-- 20201119 LJH OCSM_BP5-61 update start 主单是显示办事处和备品中心分来显示且内容不同 -->
                    <!-- <apex:outputText style="float:left;font-size:22px;margin-top: 15px;" value="{!centreAddress}"/> -->
                    <!-- height: 15mm; -->
                    <table border="0" width="100%" style="border-collapse: collapse;margin: 0;">
                        <apex:outputPanel layout="none" rendered="{!IF(!IsShowLU , true, false)}">
                        <tr>
                            <td style="font-size:22px;"><apex:outputText value="{!IF(record.isAgencyOrCenter,record.AgencyAddressName,centreAddress)}"/></td>
                            <td rowspan="2">
                                <img style="float: right; width: 55px; height: 55px;padding: 0px;margin-top: 0mm;" src="{!'/servlet/servlet.FileDownload?file=' + ApplyHeadShow.QRId__c}" />
                            </td>
                        </tr>
                        <tr>
                            <td style="font-size:15px;"><c:PDFWbr targetStr="{!IF(record.AgencyOrCenterAddress=='BeiJingCenter','北京市朝阳区酒仙桥路10号恒通商务园B12C座西门1F 电话:010-59756006-1871',IF(record.AgencyOrCenterAddress=='ShangHaiCenter','上海市浦东新区唐镇创业路183号2幢1F 电话:021-60391318-8877',IF(record.AgencyOrCenterAddress=='GuangZhouCenter','广州市番禺区东环街番禺大道北537号番山创业中心3号楼1F 电话:020-39198888-8876',record.AgencyOrCenterAddress)))}"/></td>
                        </tr>
                        </apex:outputPanel>
                        <apex:outputPanel layout="none" rendered="{!IF(IsShowLU , true, false)}">
                        <tr>
                            <td style="font-size:22px;height: 55px;line-height: 55px;"><apex:outputText value="{!centreAddress}"/>
                            </td>
                            <td>
                                <img style="float: right; width: 55px; height: 55px;padding: 0px;margin-top: 0mm;" src="{!'/servlet/servlet.FileDownload?file=' + ApplyHeadShow.QRId__c}" />
                            </td>
                        </tr>
                        </apex:outputPanel>
                    </table>
                    <!-- 20201119 LJH OCSM_BP5-61 update end 主单是显示办事处和备品中心分来显示且内容不同 -->
                    <!-- margin-top: 15mm; -->
                    <table border="1" width="100%" style="border-collapse: collapse;">
                        <tr>
                            <th style="box-sizing: border-box;text-align:center;font-size:24px;font-weight:900;" height="40">奥林巴斯备品发货清单
                            <!-- <img style="float: right; width: 35px; height: 35px;padding: 0px;" src="{!'/servlet/servlet.FileDownload?file=' + ApplyHeadShow.QRId__c}" /> -->
                            <!-- <td align="right" valign="top"><apex:outputField value="{!ApplyHeadShow.QRImg__c}" /></td>  -->
                            </th>
                        </tr>
                        <tr>
                            <td style="box-sizing: border-box;text-align:right;font-size:13px;" >备品管理中心申请单号:<apex:outputText value="{!ApplyHeadShow.Name}" /></td> <!-- {!RentalApplyName} 20201119 LJH OCSM_BP5-61  update-->
                        </tr>
                        <tr style="background-color:white;">
                            <td style="box-sizing: border-box;text-align:right;font-size:13px;">本单附件第( {!pNcnt})页/共( {!pageCnt})页</td>
                        </tr>
                        <tr>
                            <th style="box-sizing: border-box;text-align:center;font-size:16px;">
                                ※提示
                            </th>
                        </tr>
                        <tr>
                            <td style="box-sizing: border-box;text-align:left;font-size:12.3px;">本《奥林巴斯备品发货清单》一式两份,由奥林巴斯备品借用申请人(备品安装人)和医疗机构借用方各执一份,作为出借和归还时双方进<br/>行清点确认凭证
                            </td>
                        </tr>
                    </table>
                    <table border="1" width="100%" style="border-collapse: collapse;">
                        <colgroup>
                            <col width="4%" />
                            <col width="8%" />
                            <col width="20%" />
                            <col width="11%" />
                            <col width="29%" />
                            <col width="9%" />
                            <col width="9%" />
                            <col width="7%" />
                        </colgroup>
                        <tr>
                            <td style="box-sizing: border-box;text-align:center;font-size:13px;height: 16px;" colspan="2">申请人</td>
                            <td style="box-sizing: border-box;text-align:left;font-size: 13px">
                                <apex:outputText value="{!ApplyHeadShow.Person_In_Charge__r.name}" />
                            </td>
                            <td style="box-sizing: border-box;text-align:center;font-size:13px;border-left: solid 1px;"  rowspan="2">医疗机构</td>
                            <!-- 20220124 ljh SFDC-C4U3PH update colspan="4"  -->
                            <td style="box-sizing: border-box;text-align:left;font-size: 13px;"  colspan="4"  rowspan="2">
                                <apex:outputText value="{!HospitalName}" />
                            </td>
                        </tr>
                        <tr>
                            <td style="box-sizing: border-box;text-align:center;font-size:13px;" colspan="2">使用目的</td>
                            <td style="box-sizing: border-box;text-align:left;font-size: 13px;border-right: solid 1px">
                                <apex:outputText value="{!ApplyHeadShow.Demo_purpose1__c}" />
                            </td>
                        </tr>
                        <tr>
                            <td style="box-sizing: border-box;text-align:center;font-size:13px;height: 16px;" colspan="2">收件者姓名</td>
                            <td style="box-sizing: border-box;text-align:left;font-size: 13px">
                                <apex:outputText value="{!ApplyHeadShow.Loaner_received_staff__c}" />
                            </td>
                            <td style="box-sizing: border-box;text-align:center;font-size:13px;border-left: solid 1px;"  rowspan="2">发货地址</td>
                             <!-- 20220124 ljh SFDC-C4U3PH update colspan="4"  -->
                            <td style="box-sizing: border-box;text-align:left;font-size: 13px;"  colspan="4"  rowspan="2">
                                <apex:outputText value="{!if(isblank(ApplyHeadShow.Shippment_adress_detail__c), ApplyHeadShow.direct_shippment_address__c, ApplyHeadShow.Shippment_adress_detail__c)}" />
                            </td>
                        </tr>
                        <tr>
                            <td style="box-sizing: border-box;text-align:center;font-size:13px;" colspan="2">收件者电话</td>
                            <td style="box-sizing: border-box;text-align:left;font-size: 13px;border-right: solid 1px">
                                <apex:outputText value="{!ApplyHeadShow.Loaner_received_staff_phone__c}" />
                            </td>
                        </tr>
                        <tr>
                              <!-- 20220124 ljh SFDC-C4U3PH update colspan="8" -->
                            <th style="text-align:center;font-size:13px;height: 7pt;" colspan="8" >借用备品发货清单</th>
                        </tr>
                        <tr>
                            <td rowspan="2" style="box-sizing: border-box;text-align:center;font-size: 11px;">序号</td>
                            <td rowspan="2" style="box-sizing: border-box;text-align:center;font-size: 11px;">管理编号</td>
                               <!-- 20220124 ljh SFDC-C4U3PH update colspan="6" -->
                            <td colspan="6" style="box-sizing: border-box;text-align:center;font-size: 11px;">明细</td>
                        </tr>
                        <tr>
                            <!-- <td style="text-align:center;">序号</td>
                            <td style="text-align:center;">备品set型号</td>
                            <td style="text-align:center;">管理编号</td>
                            <td style="text-align:center;">产品型号</td>
                            <td style="text-align:center;">机身号</td>
                            <td style="text-align:center;">附属品明细</td> -->
                            <td style="box-sizing: border-box;text-align:center;font-size: 11px;">明细型号</td>
                            <td style="box-sizing: border-box;text-align:center;font-size: 11px;" colspan="2">中文名称</td>
                            <td style="box-sizing: border-box;text-align:center;font-size: 11px;">机身号</td>
                            <td style="text-align:center;font-size: 11px;">固定资产号</td>
                            <td style="box-sizing: border-box;text-align:center;font-size: 11px;">货位号</td>
                            <!-- 20220124 ljh SFDC-C4U3PH add start -->
                            <td style="box-sizing: border-box;text-align:center;font-size: 11px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;备注&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>
                            <!-- 20220124 ljh SFDC-C4U3PH add end -->
                            <!-- <td style="text-align:center;">二维码</td> -->
                        </tr>
                        <apex:repeat value="{!record.lineList}" var="line">
                            <tr>
                                <td style="box-sizing: border-box;text-align:center;font-size: 10px;height:30px;padding: 0px;"><c:PDFWbr targetStr="{!line.index}" /></td>
                                <td style="box-sizing: border-box;text-align:left;font-size: 10px;padding: 0px;"><c:PDFWbr targetStr="{!line.dManagementnumber}" /></td>
                                <td style="box-sizing: border-box;text-align:left;font-size: 10px;padding: 0px;"><c:PDFWbr targetStr="{!line.dModelNo}" /></td>
                                <td style="box-sizing: border-box;text-align:left;font-size: 10px;padding: 0px;" colspan="2"><c:PDFWbr targetStr="{!line.dChinaName}" /></td>
                                <td style="box-sizing: border-box;text-align:left;font-size: 10px;padding: 0px;"><c:PDFWbr targetStr="{!line.dSerialNumber}" /></td>
                                <td style="box-sizing: border-box;text-align:left;font-size: 10px;padding: 0px;"><c:PDFWbr targetStr="{!line.dLoaner_asset_no}" /></td>
                                <td style="box-sizing: border-box;text-align:left;font-size: 10px;padding: 0px;"><c:PDFWbr targetStr="{!line.wh_location}" /></td>
                                <!-- 20220124 ljh SFDC-C4U3PH add start -->
                                <td style="box-sizing: border-box;text-align:left;font-size: 10px;padding: 0px;"><c:PDFWbr targetStr="" /></td>
                                <!-- {!line.Received_ng_detail} -->
                                <!-- 20220124 ljh SFDC-C4U3PH add end -->
                                <!-- <td style="text-align:center;font-size: 10px"><c:PDFWbr targetStr="{!line.dQRCode}" /></td> -->
                                <!-- <td style="text-align:left;font-size: 13px"><apex:outputText value="{!IF(pcnt < AllSum +1,pcnt,'')}" /></td> -->
                                <!-- <td style="text-align:left;font-size: 13px"><apex:outputText value="{!line.index}" /></td>
                                <td style="text-align:left;font-size: 13px"><apex:outputText value="{!line.setName}" /></td>
                                <td style="text-align:left;font-size: 13px"><apex:outputText value="{!line.name1}" /></td>
                                <td style="text-align:left;font-size: 13px"><apex:outputText value="{!line.LoanerCode}" /></td>
                                <td style="text-align:left;font-size: 13px"><apex:outputText value="{!line.serialNumber1}" /></td>
                                <td style="text-align:left;font-size: 13px"><apex:outputText value="{!line.AssetModelNo}" /></td> -->
                            </tr>
                            <apex:variable value="{!pcnt + 1}" var="pcnt" />
                        </apex:repeat>
                    </table>
                    <!-- 20211209 ljh SFDC-C923SR 条形码 -->
                    <img style="float:left;position:absolute;z-index: 99;" src="{!'/servlet/servlet.FileDownload?file=' + ApplyHeadShow.BRId__c}" />
                    <!-- 20211209 ljh SFDC-C923SR 条形码 -->
                    <div style="{position:absolute;width:100%;height:20px">&nbsp;</div>
                    <apex:outputPanel rendered="{!pNcnt < pageCnt}" layout="none">
                        <!--  <div style="{position:absolute;width:100%;height:30px">&nbsp;</div>
                        <div style="{position:absolute;width:100%;height:30px">&nbsp;</div>-->
                    <div style="page-break-after: always;"/>
                    </apex:outputPanel>
                    <apex:variable value="{!pNcnt+1}" var="pNcnt" />
                </apex:repeat>
                </apex:outputPanel>
            </div>
        </body>
        <script>
            console.log('----start----')
            console.log('----{!ApplyHeadShow.AWS_Data_Id__c}----')
            AWSService.sfSessionId = '{!GETSESSIONID()}';
            //sforce.connection.sessionId = '{!GETSESSIONID()}';
            var staticResources = JSON.parse('{!staticResource}');
            blockme();
            document.body.onload = function(){
                console.log('document.body.onload')
                AWSService.query(staticResources.queryUrl, '{!ApplyHeadShow.AWS_Data_Id__c}', function(data){
                    console.log('data----------')
                    console.log(data);
                    unblockUI();
                    document.getElementById("allPage:Shippmentadress").innerHTML = data.object.directShippmentAddress;
                    //document.getElementById("Caller_phone__c").innerHTML = data.object.callerPhone;
                    setTimeout(() => {
                        jsPdfDownload();
                    }, 1500);
                }, staticResources.token);
            }
            /*td{
                height: 23px;
            }*/
        </style>
    </head>
<body style="font-family: Arial Unicode MS; page-break-inside: auto;font-size: 14px">
<apex:outputPanel id="showhidden" rendered="true">
    <!-- 20201119 LJH OCSM_BP5-61 update start 现地管理和现地管理的主单不显示-->
    <!-- <apex:outputText style="float:left;font-size:22px;margin-top: 25px;" value="{!centreAddress}" /> -->
    <apex:outputText style="float:left;font-size:22px;margin-top: 25px;" value="{!IF(IsShowLU,centreAddress,'')}" />
    <!-- 20201119 LJH OCSM_BP5-61 update end 现地管理和现地管理的主单不显示-->
    <img style="float: right; width: 55px; height: 55px;padding: 0px;margin-top: 12px;" src="{!'/servlet/servlet.FileDownload?file=' + ApplyHeadShow.QRId__c}" />
    <table border="1" width="100%" style="border-collapse: collapse;margin-top: 18mm;">
        <colgroup>
            <col width="50%" />
            <col width="50%" />
        </colgroup>
        <tr>
            <th style="text-align:center;" colspan="2" height="38">奥林巴斯备品签收单
                <!-- <img style="float: right; width: 35px; height: 35px;padding: 0px;margin-top: -7px;" src="{!'/servlet/servlet.FileDownload?file=' + ApplyHeadShow.QRId__c}" /> -->
            </th>
        </tr>
        <tr>
            <td style="text-align:left;border-right-style: none;">★填写完整后请自发货日起10天内上传SFDC</td>
            <td style="text-align:right;border-left-style: none;">备品管理中心申请单号:<apex:outputText value="{!ApplyHeadShow.Name}" /></td>
        </tr>
        <!-- <tr style="background-color:#003399;color:white">
            <th style="text-align:center;" height="40">发货信息</th>
        </tr> -->
        <!-- <tr>
            <td style="text-align:left;font-size:12px">
1、本发货确认单共两页。首页中到货确认部分为现场必填项目,填写完整后请回传至备品中心(传真或扫描件即可);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;末页中清洗消毒灭菌确认栏为现场必填项目,备品回寄时请将此页随备品一同寄回备品中心。<br />
2、请对产品进行清洗消毒或灭菌后再使用。<br />
3、在使用备品前,敬请仔细阅读背面“备品使用须知”,请明确申请人及申请方责任与义务。
            </td>
        </tr> -->
    </table>
    <table border="1px" width="100%" style="border-collapse: collapse;">
        <colgroup>
            <col width="16%" />
            <col width="14%" />
            <col width="36%" />
            <col width="16%" />
            <col width="18%" />
        </colgroup>
        <tr>
            <th style="text-align:center;" colspan="5" height="25">发货信息</th>
        </tr>
        <tr>
            <td style="text-align:left;">使用目的</td> <td style="text-align:left;font-size: 13px" colspan="4"><apex:outputText value="{!ApplyHeadShow.Demo_purpose1__c}" /></td>
        </tr>
        <tr>
            <td style="text-align:left;" rowspan="2">申请人信息</td>
            <td style="text-align:left;">所属本部名</td> <td   style="text-align:left;font-size: 13px">     <apex:outputText value="{!ApplyHeadShow.Salesdept__c}" /></td>
            <td style="text-align:left;" >所属办事处名</td> <td   style="text-align:left;font-size: 13px">        <apex:outputText value="{!ApplyHeadShow.WorkPlace__c}" /></td>
        </tr>
        <tr>
            <td style="text-align:left;" >姓名 </td> <td  style="text-align:left;font-size: 13px">    <apex:outputText value="{!ApplyHeadShow.Person_In_Charge__r.name}" /></td>
            <td style="text-align:left;" colspan="1">联系电话</td> <td  style="text-align:left;font-size: 13px">     <apex:outputText value="{!ApplyHeadShow.ApplyPerson_Phone__c}" /></td>
        </tr>
        <tr>
            <td style="text-align:left;" >医疗机构信息</td>
            <td style="text-align:left;" >医疗机构名</td> <td style="text-align:left;font-size: 13px"> <apex:outputText value="{!HospitalName}" /></td>
            <td style="text-align:left;" >科室名</td> <td  style="text-align:left;font-size: 13px"><apex:outputText value="{!ApplyHeadShow.Account__r.Department_Name__c}" /></td>
        </tr>
        <tr>
            <td style="text-align:left;" rowspan="3" >发货地址</td> <td colspan="2" rowspan="3" style="text-align:left;font-size: 13px"> <apex:outputText value="{!Shippmentadress}" /></td>
            <td style="text-align:left;" colspan="1">邮编</td> <td  style="text-align:left;"> <apex:outputText value="{!IF(ApplyHeadShow.Shipment_address__r.Post_Code__c==null,ApplyHeadShow.Post_Code__c,ApplyHeadShow.Shipment_address__r.Post_Code__c)}" /></td>
        </tr>
        <tr>
            <td style="text-align:left;" colspan="1">接收人姓名</td> <td  style="text-align:left;font-size: 13px">  <apex:outputText value="{!ApplyHeadShow.Loaner_received_staff__c}" /></td>
        </tr>
        <tr>
            <td style="text-align:left;" colspan="1">接收人电话</td> <td style="text-align:left;font-size: 13px">  <apex:outputText value="{!ApplyHeadShow.Loaner_received_staff_phone__c}" /></td>
        </tr>
    </table>
    <table border="1" width="100%" style="border-collapse: collapse;">
        <tr>
            <th style="text-align:center;" colspan="4" height="25">医院借用期限</th>
        </tr>
        <tr>
            <td style="text-align:left;"> {!IF(BorrowTimeString='null','',BorrowTimeString)}&nbsp;&nbsp;&nbsp;</td>
        </tr>
    </table>
    <table border="1" width="100%" style="border-collapse: collapse;">
        <colgroup>
            <col width="19%" />
            <col width="29%" />
            <col width="29%" />
            <col width="23%" />
        </colgroup>
        <tr>
            <th style="text-align:center;" colspan="4" height="40"> 奥林巴斯备品借用申请・安装人填写栏<small>(必填)</small><br/>到货确认部分为奥林巴斯员工必填项目</th>
        </tr>
        <tr>
            <td style="text-align:left;" >签收者姓名</td> <td style="text-align:left;"></td>
            <td style="text-align:left;">备品安装者姓名</td> <td  style="text-align:left;"></td>
        </tr>
        <tr>
            <td style="text-align:left;">签收日期</td> <td  style="text-align:left;"></td>
            <td style="text-align:left;">安装及安装说明日期</td> <td  style="text-align:left;"> </td>
        </tr>
    </table>
    <table border="1" width="100%" style="border-collapse: collapse;">
        <colgroup>
            <col width="19%" />
            <col width="29%" />
            <col width="29%" />
            <col width="23%" />
        </colgroup>
        <tr>
            <th style="text-align:center;" colspan="4" height="40"> 医疗机构签收填写栏<small>(必填)</small><br/>敬请使用备品前仔细阅读下方“奥林巴斯备品借用须知”,以明确使用方的责任与义务</th>
        </tr>
        <!--根据OLY_OCM-260记载,先注释掉(OLY_OCM-251取消注释) -->
        <tr><th style="text-align:center;" height="25" colspan="4">《奥林巴斯备品发货清单》所列备品悉数收到,
           共计主机{!mainCnt}件,附属品{!accessoryCnt}件;并已接受产品使用说明和了解借用须知。</th></tr>
        <tr>
            <td style="text-align:left;" >签收者姓名</td> <td style="text-align:left;"></td>
            <td style="text-align:left;" rowspan="2">接收单位(科室)章 </td>
            <td style="text-align:left;" rowspan="2"> </td>
        </tr>
        <tr>
            <td style="text-align:left;">签收日期</td> <td  style="text-align:left;"></td>
        </tr>
    </table>
    <table border="1" width="100%" style="border-collapse: collapse;">
        <colgroup>
            <col width="100%" />
        </colgroup>
        <tr>
            <th style="text-align:center;" height="25">※奥林巴斯备品借用须知</th>
        </tr>
        <tr>
            <td style="text-align:left;font-size: 12px">
1,备品:本须知所指的备品,是指本签收单附件《奥林巴斯备品发货清单》所列的由奥林巴斯(北京)销售服务有限公司(以下简称奥林<br/>巴斯)在规定期限内免费提供给借用单位为实施医疗行为或培训等所使用的设备包括产品及相关附属品,附件是本须知有效组成部分,与本<br/>须知具有同等法律效力。<br/>
2,备品所有权:备品所有权归属于奥林巴斯公司。未经奥林巴斯公司书面同意,借用单位不得以任何理由向任何第三方转借、转让附件所<br/>列备品,或将附件所列备品作为担保抵押给任何第三方。<br/>
3,备品使用权:借用期限内,借用单位对出借的备品享有独立合理的使用权利。若在使用过程中存在不确定情况时,借用单位应及时通知<br/>奥林巴斯公司,奥林巴斯公司将到场给予指导和协助,借用单位不应擅自处理。<br/>
4,备品之日常使用与维护:借用单位在使用备品过程中应按照奥林巴斯公司的要求(“产品使用说明书”)内容尽审慎义务正确操作使用、<br/>爱护使用。备品使用前后都应进行必要的清洗消毒(灭菌)及日常检测工作,以确保备品的正常运作。<br/>
5,备品损坏、遗失之赔偿责任:附件所列备品若因正常损耗而产生的维修或维护费用,由奥林巴斯公司承担;若因借用单位使用不当或超<br/>期借用等原因造成的备品损坏,借用单位应承担相关维修费用。当备品借用中发生故障需要维修时,应联系奥林巴斯进行检测和维修,不得<br/>擅自将相关备品交由任何第三方维修。若因借用单位原因造成备品遗失时,则借用单位应负赔偿责任。<br/>
6,医疗责任事故:备品是符合国家质量标准并经检验合格的医疗器械产品,借用单位应独立依靠其医疗专业水平和能力利用备品进行医疗<br/>活动或培训。借用单位使用备品时所发生的任何问题均由借用单位自行负责、处理。<br/>
7,备品返还:借用单位应按照本单注明的使用期限履行按时返还备品的承诺。返回前,借用单位应对备品进行清洗消毒或灭菌,以保证所<br/>有备品接触者的健康安全,同时借用单位有义务为奥林巴斯公司回收备品提供必要协助。<br/>
8,借用单位知悉且同意,此次备品出借基于正当合理的理由,而非通过出借备品对借用单位购买、推荐奥林巴斯公司产品、服务等产生任<br/>何不正当影响。<br/>
9,借用单位应严格按本单所载使用目的使用备品,禁止将备品用于本单所载使用目的以外的其他用途。<br/>
10,若借用单位选择以加盖实际接收备品的借用单位内部部门章或签收者签名方式确认以上内容,实际接收备品的借用单位内部部门或签<br/>收者确认其具备相应资格代表借用单位进行签收和确认。<br/>
11,其它:其它未尽事宜,双方应本着友好合作的原则进行协商解决。
            </td>
            <!-- 20211008 ljh SFDC-C7L4ED 增加8,9,10-->
        </tr>
        <tr>
            <td style="text-align:left;font-size:12px;border-collapse: collapse;" colspan="2" height="80">
奥林巴斯 北京备品中心地址:北京市朝阳区酒仙桥路10号恒通商务园B12C座西门1F<br />
邮编:100015     TEL:010-59756006-1871    FAX: 010-59756534<br />
奥林巴斯 广州备品中心地址:广州市番禺区东环街番禺大道北537号番山创业中心3号楼1F<br />
邮编:511400     TEL:020-39198888-8876     FAX:020-39198848<br />
奥林巴斯 上海备品中心地址:上海市浦东新区金吉路778号3号楼1F<br />
邮编:201206    TEL:021-60391318-8877    FAX:021-60391316<br />
            </td>
            <!-- 20210812 SFDC-C5CC5S 修改地址-->
        </tr>
    </table>
    <apex:outputPanel layout="none">
         <div style="page-break-after: always;"/>
    </apex:outputPanel>
<apex:variable value="{!1}" var="pNcnt" />
<apex:variable value="{!1}" var="pcnt" />
<apex:repeat value="{!records}" var="record">
    <div style="{position:absolute;width:100%;height:15px">&nbsp;</div>
    <!-- 20201119 LJH OCSM_BP5-61 update start 主单是显示办事处和备品中心分来显示且内容不同 -->
    <!-- <apex:outputText style="float:left;font-size:22px;margin-top: 15px;" value="{!centreAddress}"/> -->
    <!-- height: 15mm; -->
    <table border="0" width="100%" style="border-collapse: collapse;margin: 0;">
        <apex:outputPanel layout="none" rendered="{!IF(!IsShowLU , true, false)}">
        <tr>
            <td style="font-size:22px;"><apex:outputText value="{!IF(record.isAgencyOrCenter,record.AgencyAddressName,centreAddress)}"/></td>
            <td rowspan="2">
                <img style="float: right; width: 55px; height: 55px;padding: 0px;margin-top: 0mm;" src="{!'/servlet/servlet.FileDownload?file=' + ApplyHeadShow.QRId__c}" />
            </td>
        </tr>
        <tr>
            <td style="font-size:15px;"><c:PDFWbr targetStr="{!IF(record.AgencyOrCenterAddress=='BeiJingCenter','北京市朝阳区酒仙桥路10号恒通商务园B12C座西门1F 电话:010-59756006-1871',IF(record.AgencyOrCenterAddress=='ShangHaiCenter','上海市浦东新区唐镇创业路183号2幢1F 电话:021-60391318-8877',IF(record.AgencyOrCenterAddress=='GuangZhouCenter','广州市番禺区东环街番禺大道北537号番山创业中心3号楼1F 电话:020-39198888-8876',record.AgencyOrCenterAddress)))}"/></td>
        </tr>
        </apex:outputPanel>
        <apex:outputPanel layout="none" rendered="{!IF(IsShowLU , true, false)}">
        <tr>
            <td style="font-size:22px;height: 55px;line-height: 55px;"><apex:outputText value="{!centreAddress}"/>
            </td>
            <td>
                <img style="float: right; width: 55px; height: 55px;padding: 0px;margin-top: 0mm;" src="{!'/servlet/servlet.FileDownload?file=' + ApplyHeadShow.QRId__c}" />
            </td>
        </tr>
        </apex:outputPanel>
    </table>
    <!-- 20201119 LJH OCSM_BP5-61 update end 主单是显示办事处和备品中心分来显示且内容不同 -->
    <!-- margin-top: 15mm; -->
    <table border="1" width="100%" style="border-collapse: collapse;">
        <tr>
            <th style="box-sizing: border-box;text-align:center;font-size:24px;font-weight:900;" height="40">奥林巴斯备品发货清单
            <!-- <img style="float: right; width: 35px; height: 35px;padding: 0px;" src="{!'/servlet/servlet.FileDownload?file=' + ApplyHeadShow.QRId__c}" /> -->
            <!-- <td align="right" valign="top"><apex:outputField value="{!ApplyHeadShow.QRImg__c}" /></td>  -->
            </th>
        </tr>
        <tr>
            <td style="box-sizing: border-box;text-align:right;font-size:13px;" >备品管理中心申请单号:<apex:outputText value="{!ApplyHeadShow.Name}" /></td> <!-- {!RentalApplyName} 20201119 LJH OCSM_BP5-61  update-->
        </tr>
        <tr style="background-color:white;">
            <td style="box-sizing: border-box;text-align:right;font-size:13px;">本单附件第( {!pNcnt})页/共( {!pageCnt})页</td>
        </tr>
        <tr>
            <th style="box-sizing: border-box;text-align:center;font-size:16px;">
                ※提示
            </th>
        </tr>
        <tr>
            <td style="box-sizing: border-box;text-align:left;font-size:12.3px;">本《奥林巴斯备品发货清单》一式两份,由奥林巴斯备品借用申请人(备品安装人)和医疗机构借用方各执一份,作为出借和归还时双方进<br/>行清点确认凭证
            </td>
        </tr>
    </table>
    <table border="1" width="100%" style="border-collapse: collapse;">
        <colgroup>
            <col width="4%" />
            <col width="8%" />
            <col width="20%" />
            <col width="11%" />
            <col width="29%" />
            <col width="9%" />
            <col width="9%" />
            <col width="7%" />
        </colgroup>
        <tr>
            <td style="box-sizing: border-box;text-align:center;font-size:13px;height: 16px;" colspan="2">申请人</td>
            <td style="box-sizing: border-box;text-align:left;font-size: 13px">
                <apex:outputText value="{!ApplyHeadShow.Person_In_Charge__r.name}" />
            </td>
            <td style="box-sizing: border-box;text-align:center;font-size:13px;border-left: solid 1px;"  rowspan="2">医疗机构</td>
            <!-- 20220124 ljh SFDC-C4U3PH update colspan="4"  -->
            <td style="box-sizing: border-box;text-align:left;font-size: 13px;"  colspan="5"  rowspan="2">
                <apex:outputText value="{!HospitalName}" />
            </td>
        </tr>
        <tr>
            <td style="box-sizing: border-box;text-align:center;font-size:13px;" colspan="2">使用目的</td>
            <td style="box-sizing: border-box;text-align:left;font-size: 13px;border-right: solid 1px">
                <apex:outputText value="{!ApplyHeadShow.Demo_purpose1__c}" />
            </td>
        </tr>
        <tr>
            <td style="box-sizing: border-box;text-align:center;font-size:13px;height: 16px;" colspan="2">收件者姓名</td>
            <td style="box-sizing: border-box;text-align:left;font-size: 13px">
                <apex:outputText value="{!ApplyHeadShow.Loaner_received_staff__c}" />
            </td>
            <td style="box-sizing: border-box;text-align:center;font-size:13px;border-left: solid 1px;"  rowspan="2">发货地址</td>
            <!-- 20220124 ljh SFDC-C4U3PH update colspan="4"  -->
            <td style="box-sizing: border-box;text-align:left;font-size: 13px;"  colspan="5"  rowspan="2">
                <apex:outputText value="{!if(isblank(ApplyHeadShow.Shippment_adress_detail__c), ApplyHeadShow.direct_shippment_address__c, ApplyHeadShow.Shippment_adress_detail__c)}" />
            </td>
        </tr>
        <tr>
            <td style="box-sizing: border-box;text-align:center;font-size:13px;" colspan="2">收件者电话</td>
            <td style="box-sizing: border-box;text-align:left;font-size: 13px;border-right: solid 1px">
                <apex:outputText value="{!ApplyHeadShow.Loaner_received_staff_phone__c}" />
            </td>
        </tr>
        <tr>
            <!-- 20220124 ljh SFDC-C4U3PH update colspan="8" -->
            <th style="text-align:center;font-size:13px;height: 7pt;" colspan="9" >借用备品发货清单</th>
        </tr>
        <tr>
            <td rowspan="2" style="box-sizing: border-box;text-align:center;font-size: 11px;">序号</td>
            <td rowspan="2" style="box-sizing: border-box;text-align:center;font-size: 11px;">管理编号</td>
            <!-- 20220124 ljh SFDC-C4U3PH update colspan="6" -->
            <td colspan="7" style="box-sizing: border-box;text-align:center;font-size: 11px;">明细</td>
        </tr>
        <tr>
            <!-- <td style="text-align:center;">序号</td>
            <td style="text-align:center;">备品set型号</td>
            <td style="text-align:center;">管理编号</td>
            <td style="text-align:center;">产品型号</td>
            <td style="text-align:center;">机身号</td>
            <td style="text-align:center;">附属品明细</td> -->
            <td style="box-sizing: border-box;text-align:center;font-size: 11px;">明细型号</td>
            <td style="box-sizing: border-box;text-align:center;font-size: 11px;" colspan="2">中文名称</td>
            <td style="box-sizing: border-box;text-align:center;font-size: 11px;">机身号</td>
            <td style="text-align:center;font-size: 11px;">固定资产号</td>
            <td style="box-sizing: border-box;text-align:center;font-size: 11px;">货位号</td>
            <!-- 20220124 ljh SFDC-C4U3PH add start -->
            <td style="box-sizing: border-box;text-align:center;font-size: 11px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;备注&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>
            <!-- 20220124 ljh SFDC-C4U3PH add end -->
            <!-- <td style="text-align:center;">二维码</td> -->
        </tr>
        <apex:repeat value="{!record.lineList}" var="line">
            <tr>
                <td style="box-sizing: border-box;text-align:center;font-size: 10px;height:30px;padding: 0px;"><c:PDFWbr targetStr="{!line.index}" /></td>
                <td style="box-sizing: border-box;text-align:left;font-size: 10px;padding: 0px;"><c:PDFWbr targetStr="{!line.dManagementnumber}" /></td>
                <td style="box-sizing: border-box;text-align:left;font-size: 10px;padding: 0px;"><c:PDFWbr targetStr="{!line.dModelNo}" /></td>
                <td style="box-sizing: border-box;text-align:left;font-size: 10px;padding: 0px;" colspan="2"><c:PDFWbr targetStr="{!line.dChinaName}" /></td>
                <td style="box-sizing: border-box;text-align:left;font-size: 10px;padding: 0px;"><c:PDFWbr targetStr="{!line.dSerialNumber}" /></td>
                <td style="box-sizing: border-box;text-align:left;font-size: 10px;padding: 0px;"><c:PDFWbr targetStr="{!line.dLoaner_asset_no}" /></td>
                <td style="box-sizing: border-box;text-align:left;font-size: 10px;padding: 0px;"><c:PDFWbr targetStr="{!line.wh_location}" /></td>
                <!-- 20220124 ljh SFDC-C4U3PH add start -->
                <td style="box-sizing: border-box;text-align:left;font-size: 10px;padding: 0px;"><c:PDFWbr targetStr="" /></td>
                <!-- {!line.Received_ng_detail} -->
                <!-- 20220124 ljh SFDC-C4U3PH add end -->
                <!-- <td style="text-align:center;font-size: 10px"><c:PDFWbr targetStr="{!line.dQRCode}" /></td> -->
                <!-- <td style="text-align:left;font-size: 13px"><apex:outputText value="{!IF(pcnt < AllSum +1,pcnt,'')}" /></td> -->
                <!-- <td style="text-align:left;font-size: 13px"><apex:outputText value="{!line.index}" /></td>
                <td style="text-align:left;font-size: 13px"><apex:outputText value="{!line.setName}" /></td>
                <td style="text-align:left;font-size: 13px"><apex:outputText value="{!line.name1}" /></td>
                <td style="text-align:left;font-size: 13px"><apex:outputText value="{!line.LoanerCode}" /></td>
                <td style="text-align:left;font-size: 13px"><apex:outputText value="{!line.serialNumber1}" /></td>
                <td style="text-align:left;font-size: 13px"><apex:outputText value="{!line.AssetModelNo}" /></td> -->
            </tr>
            <apex:variable value="{!pcnt + 1}" var="pcnt" />
        </apex:repeat>
    </table>
    <!-- 20211209 ljh SFDC-C923SR 条形码 -->
    <img style="float:left;position:absolute;z-index: 99;" src="{!'/servlet/servlet.FileDownload?file=' + ApplyHeadShow.BRId__c}" />
    <!-- 20211209 ljh SFDC-C923SR 条形码 -->
     <div style="{position:absolute;width:100%;height:20px">&nbsp;</div>
      <apex:outputPanel rendered="{!pNcnt < pageCnt}" layout="none">
         <!--  <div style="{position:absolute;width:100%;height:30px">&nbsp;</div>
           <div style="{position:absolute;width:100%;height:30px">&nbsp;</div>-->
       <div style="page-break-after: always;"/>
     </apex:outputPanel>
    <apex:variable value="{!pNcnt+1}" var="pNcnt" />
</apex:repeat>
</apex:outputPanel>
</body>
</html>
            function jsPdfDownload(){
                let pdfName = "测试";
                let id = "pdf-wrapper";
                var target = document.getElementById(id);
                target.style.background = "#FFFFFF";
                if(pdfName==''||pdfName==undefined) pdfName= getNowFormatDate();
                html2canvas(target, {
                    scale: 2,
                    onrendered:function(canvas) {
                        var contentWidth = canvas.width;
                        var contentHeight = canvas.height;
                        //一页pdf显示html页面生成的canvas高度;
                        var pageHeight = contentWidth / 592.28 * 841.89;
                        //未生成pdf的html页面高度
                        var leftHeight = contentHeight;
                        //页面偏移
                        var position = 0;
                        //a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
                        var imgWidth = 565.28;//595.28//左右边距20
                        var imgHeight = 605.28/contentWidth * contentHeight;//左右边距20
                        var pageData = canvas.toDataURL('image/jpeg', 1.0);
                        var pdf = new jsPDF('', 'pt', 'a4');
                        //有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
                        //当内容未超过pdf一页显示的范围,无需分页
                        if (leftHeight < pageHeight) {
                            pdf.addImage(pageData, 'JPEG', 15, 0, imgWidth, imgHeight );//左右边距7.5
                        } else {
                            while(leftHeight > 0) {
                                pdf.addImage(pageData, 'JPEG', 15, position, imgWidth, imgHeight)//左右边距7.5
                                leftHeight -= pageHeight;
                                position -= 841.89;
                                //避免添加空白页
                                if(leftHeight > 0) {
                                    pdf.addPage();
                                }
                            }
                        }
                        Fun(pdf);
                    }
                })
            }
            function Fun(pdf){
                var iframe = document.createElement('iframe');
                iframe.setAttribute('style', 'position:absolute;right:0; top:0; bottom:0; height:100%; width:100%');
                document.body.appendChild(iframe);
                iframe.src = pdf.output('datauristring');
                for(let e of document.body.childNodes){
                    if( e != iframe && e.style){
                        e.style.display = 'none';
                    }
                }
            }
        </script>
    </html>
</apex:page>
force-app/main/default/pages/InsReportPDF.page
@@ -1,4 +1,4 @@
<apex:page controller="InsReportPDFController" showHeader="false" sidebar="false" renderAs="PDF" action="{!init}" applyHtmlTag="false">
<apex:page controller="InsReportPDFController" showHeader="false" sidebar="false" action="{!init}" applyHtmlTag="false">
<html>
<apex:stylesheet value="{!URLFOR($Resource.BeforeOPDPDF)}"/>
@@ -14,18 +14,38 @@
            }
        }
        
        table {border-collapse: collapse;}
        table {border-collapse: collapse;border: 0px;}
        
        th {text-align: center;}
        th.border-thick-title { border-width: 1pt 0pt 1pt 0pt; border-style: solid; border-color: black; text-align: center;}
        td.middle {text-align: center;}
        td.topClear {border-top-color: white;}
        /* 20220221 PI改造 by 徐亮 start */
        body{margin: 0 auto;
        width: 780px;}
        #title1{height: 30px;}
        #title2{height: 80px;}
        .dianjian td{border: 1px #000 solid}
        /* 20220221 PI改造 by 徐亮 end */
        </style>
         <!-- 20220221 PI改造 by 徐亮 start  -->
         <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
         <script src="../../soap/ajax/53.0/connection.js" type="text/javascript"></script>
         <apex:stylesheet value="{!URLFOR($Resource.blockUIcss)}"/>
         <apex:includeScript value="{!URLFOR($Resource.jquery183minjs)}"/>
         <apex:includeScript value="{!URLFOR($Resource.PleaseWaitDialog)}"/>
         <apex:includeScript value="{!URLFOR($Resource.jspdf)}"/>
         <apex:includeScript value="{!URLFOR($Resource.html2canvas)}"/>
         <!-- 20220221 PI改造 by 徐亮 end  -->
        <script>
        </script>
    </head>
    
    <body style="font-family: Arial Unicode MS;">
        <div id="pdf-wrapper">
            <div id="title1"></div>
        <table border="0" style="width:100%;">
            <tr>
                <!-- update by rentx 20210707 start -->
@@ -52,7 +72,7 @@
                    <td>点检人</td>
                </tr>
                <tr>
                    <td width="70%">院方负责人 &nbsp;&nbsp;&nbsp;&nbsp;{!ir.Responsible_Person__c}</td>
                    <td width="70%">院方负责人 &nbsp;&nbsp;&nbsp;&nbsp;<span id="Responsible_Person__c">{!ir.Responsible_Person__c}</span></td>
                    <td width="15%"><apex:outputField value="{!ir.Inspection_Date__c}" /></td>
                    <td width="15%">{!usr.Alias__c}</td>
                </tr>
@@ -72,7 +92,7 @@
                    <td> 本次点检对象数 &nbsp;&nbsp;&nbsp;&nbsp; {!ir.Inspection_asset_number__c}</td>
                </tr>
                <tr>
                    <td width="70%"> 院方负责人 &nbsp;&nbsp;&nbsp;&nbsp;{!ir.Responsible_Person__c}</td>
                    <td width="70%"> 院方负责人 &nbsp;&nbsp;&nbsp;&nbsp;<span id="Responsible_Person__c">{!ir.Responsible_Person__c}</span></td>
                    <td > 本次点检日期 &nbsp;&nbsp;&nbsp;&nbsp; <apex:outputField value="{!ir.Inspection_Date__c}" /></td>
                </tr>
                <tr>
@@ -82,7 +102,7 @@
            </apex:outputText>
        </table>
        <br/>
        <table border="1" style="width:100%;">
        <table class="dianjian" border="0" style="width:100%;border-collapse: collapse;border: 0px;">
            <!-- update by rentx 20210707 start -->
            <apex:outputText rendered="{!ir.Contract__c = null}">
                <tr>
@@ -199,6 +219,101 @@
        <table border="0" width="100%">
            <tr><td style="text-align: right"><apex:image value="{!ir.SignUrl__c}" width="300px" height="150px" rendered="{!NOT(ISBLANK(ir.SignUrl__c))}" /></td></tr>
        </table>
    </div>
    </body>
    <!-- 20220221 PI改造 by 徐亮 start  -->
<script>
    AWSService.sfSessionId = '{!GETSESSIONID()}';
    var staticResources = JSON.parse('{!staticResource}');
    function Fun(pdf){
        var iframe = document.createElement('iframe');
        iframe.setAttribute('style', 'position:absolute;right:0; top:0; bottom:0; height:100%; width:100%');
        document.body.appendChild(iframe);
        iframe.src = pdf.output('datauristring');
        for(let e of document.body.childNodes){
            if( e != iframe && e.style){
                e.style.display = 'none';
            }
        }
    }
    let id = "pdf-wrapper";
    var target = document.getElementById(id);
    function jsPdfDownload(){
        let pdfName = "测试";
        let id = "pdf-wrapper";
        var target = document.getElementById(id);
        target.style.background = "#FFFFFF";
        if(pdfName==''||pdfName==undefined) pdfName= getNowFormatDate();
        html2canvas(target, {
            scale: 2,
            onrendered:function(canvas) {
                let landscape = true;
                let pw = 595.28;
                let ph = 841.89;
                const marginw = 40;
                let orientation = '';
                if (landscape) {
                    let temp =ph;
                    ph = pw;
                    pw = temp;
                    orientation = 'l';
                }
                var contentWidth = canvas.width;
                var contentHeight = canvas.height;
                //一页pdf显示html页面生成的canvas高度;
                var pageHeight = contentWidth / pw * ph;
                //未生成pdf的html页面高度
                var leftHeight = contentHeight;
                //页面偏移
                var position = 0;
                //a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
                var imgWidth = pw-2*marginw;//595.28//左右边距20
                var imgHeight = imgWidth/contentWidth * contentHeight;//左右边距20
                var pageData = canvas.toDataURL('image/jpeg', 1.0);
                var pdf = new jsPDF(orientation, 'pt', 'a4');// 第一个参数填字母l,注意不是数字1,为横向pdf
                //有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
                //当内容未超过pdf一页显示的范围,无需分页
                if (leftHeight < pageHeight) {
                    pdf.addImage(pageData, 'JPEG', marginw, 0, imgWidth, imgHeight );//左右边距20
                } else {
                    while(leftHeight > 0) {
                        pdf.addImage(pageData, 'JPEG', marginw, position, imgWidth, imgHeight)//左右边距20
                        leftHeight -= pageHeight;
                        position -= ph;
                        //避免添加空白页
                        if(leftHeight > 0) {
                            pdf.addPage();
                        }
                    }
                }
                Fun(pdf);
            }
        })
    }
    blockme();
    document.body.onload = function(){
        AWSService.query(staticResources.queryUrl, '{!ir.AWS_Data_Id__c}', function(data){
            unblockUI();
            document.getElementById("Responsible_Person__c").innerHTML = data.object.responsiblePerson;
            setTimeout(() => {
                jsPdfDownload();
            }, 1500);
        }, staticResources.token);
    }
</script>
<!-- 20220221 PI改造 by 徐亮 end  -->
</html>
</apex:page>
force-app/main/default/pages/InstructReport.page
@@ -6,14 +6,82 @@
    <apex:includeScript value="/soap/ajax/29.0/connection.js"/>
    <apex:includeScript value="/soap/ajax/29.0/apex.js"/>
    <!-- <apex:includeScript value="{!URLFOR($Resource.OpportunityPCLJs)}"/> -->
    <!-- 20220222 PI改造 by Bright--start -->
    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
    <script src="../../soap/ajax/53.0/connection.js" type="text/javascript"></script>
    <!-- 20220222 PI改造 by Bright--end -->
    <style type="text/css">
        [aws-api] {
            position: relative;
        }
        [aws-api] .decrypt{position: absolute;top: 0;left: 100%;display: none;text-align: left;
            padding-left: 5px;}
        [aws-api]:hover .decrypt{display: block;width: 100px}
    </style>
    <script type="text/javascript">
        function init() {
        }
        // 20220222 PI改造 by Bright--start
        AWSService.sfSessionId = '{!GETSESSIONID()}';
        var staticResource = JSON.parse('{!staticResource}');
        var aws_data = {};
        function Decrypt(dataIds){
            let Foo = function(){
                for (const id of dataIds) {
                    if (aws_data.hasOwnProperty(id)) {
                        let d = aws_data[id];
                        let $e =j$("[aws-id='"+d.dataId+ "']");
                        $e.find(".decrypt").html(d[$e.attr("aws-api")]);
                    }
                }
            }
            let ids = [];
            for (const id of dataIds) {
                if (!aws_data.hasOwnProperty(id)) {
                    ids.push(id);
                }
            }
            if (ids.length > 0) {
                blockme();
                AWSService.search(staticResource.searchUrl,JSON.stringify({
                    "dataIds":ids
                }),function(data){
                    unblockUI();
                    if(data.object && data.object.length > 0){
                        for(let d of data.object){
                            if(d.dataId){
                                aws_data[d.dataId] = d;
                            }
                        }
                        Foo();
                    }
                },staticResource.token);
            }else{
                Foo();
            }
        }
        function DecryptAll(){
            let dataIds = [];
            j$("[aws-id]").each((i,e)=>{
                let v = j$(e).attr('aws-id');
                if (v) {
                    dataIds.push(v);
                }
            });
            Decrypt(dataIds);
        }
        j$(function(){
            DecryptAll();
        })
        // 20220222 PI改造 by Bright--end
        function checkAll(checker) {
             var cnt = j$(escapeVfId('allPage:allForm:allBlock:'+checker.alt+':memberCnt')).val();
             for (var i = 0; i < cnt; i++) {
@@ -110,7 +178,12 @@
                        </apex:column>
                        <!-- 被带教人 -->
                        <apex:column style="width: 2%">
                        <apex:outputLink style="resize:vertical;width: 95%" id="Name" value="/{!checkedIS.CamMem.Contact_ID__c}" target="LINK_{!checkedIS.CamMem.Contact_ID__c}"><apex:outputField value="{!checkedIS.IS.Name}" /></apex:outputLink>
                        <apex:outputLink html-aws-api="lastName" html-aws-id="{!checkedIS.IS.ContactID__r.AWS_Data_Id__c}" style="resize:vertical;width: 95%" id="Name" value="/{!checkedIS.CamMem.Contact_ID__c}" target="LINK_{!checkedIS.CamMem.Contact_ID__c}">
                            <!-- 20220222 PI改造 by Bright--start -->
                            <span class="encrypt">{!checkedIS.IS.Name}</span>
                            <span class="decrypt"></span>
                            <!-- 20220222 PI改造 by Bright--end -->
                        </apex:outputLink>
                        </apex:column>
                        <!-- 客户名 -->
                        <!-- 增加无效科室红色提醒 精琢技术 wql 2021/02/04 start -->
@@ -203,7 +276,7 @@
                <table style="width:100%;">
                    <tr>
                        <td>
                            <apex:commandButton value="刷新选中的参会人员"  action="{!exchangeInstructedstaff}" onclick="blockme();" oncomplete="unblockUI();" rerender="allPage:allForm:allBlock:InstructedStaff,allPage:allForm:allBlock:Campaign_members" />
                            <apex:commandButton value="刷新选中的参会人员"  action="{!exchangeInstructedstaff}" onclick="blockme();" oncomplete="unblockUI();DecryptAll();" rerender="allPage:allForm:allBlock:InstructedStaff,allPage:allForm:allBlock:Campaign_members" />
                        </td>
                    </tr>
                </table>
@@ -237,7 +310,12 @@
                        </apex:column>
                        <apex:column style="width: 10%">
                        <!-- LJPH-BVNBMM 显示当前联系人名称- start -->
                        <apex:outputLink style="resize:vertical;width: 95%" id="Name" value="/{!uncheckedIS.CamMem.Contact_ID__c}" target="LINK_{!uncheckedIS.CamMem.Contact_ID__c}"><apex:outputtext value="{!uncheckedIS.CamMem.ContactName__c}" /></apex:outputLink>
                        <apex:outputLink html-aws-api="lastName" html-aws-id="{!uncheckedIS.CamMem.Contact_ID__r.AWS_Data_Id__c}" style="resize:vertical;width: 95%" id="Name" value="/{!uncheckedIS.CamMem.Contact_ID__c}" target="LINK_{!uncheckedIS.CamMem.Contact_ID__c}">
                        <!-- 20220222 PI改造 by Bright--start -->
                        <span class="encrypt">{!uncheckedIS.CamMem.ContactName__c}</span>
                        <span class="decrypt"></span>
                        <!-- 20220222 PI改造 by Bright--end -->
                        </apex:outputLink>
                        </apex:column>
                        <!-- LJPH-BVNBMM end -->
                        <apex:column style="width: 10%">
force-app/main/default/pages/LeadIntention.page
@@ -1,162 +1,417 @@
<apex:page controller="LeadIntentionController" showHeader="false" sidebar="false" id="allPage" action="{!init}">
<head>
<title>会议询问单确认一览表</title>
<apex:stylesheet value="{!URLFOR($Resource.blockUIcss)}"/>
<apex:includeScript value="{!URLFOR($Resource.jquery183minjs)}"/>
<apex:includeScript value="{!URLFOR($Resource.PleaseWaitDialog)}"/>
<apex:includeScript value="{!URLFOR($Resource.OpportunityPCLJs)}"/>
    <head>
        <title>会议询问单确认一览表</title>
        <!-- 2022/02/15 张华建 dependency start -->
        <apex:stylesheet value="{!URLFOR($Resource.blockUIcss)}"/>
        <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
        <apex:includeScript value="{!URLFOR($Resource.jquery183minjs)}"/>
        <apex:includeScript value="{!URLFOR($Resource.PleaseWaitDialog)}"/>
        <apex:includeScript value="{!URLFOR($Resource.OpportunityPCLJs)}" />
        <!-- 2022/02/15 张华建 dependency end -->
<style>
    td .dateFormat  {
        display: none;
    }
    div.inline { float:left; }
    .clearBoth { clear:both; }
div#out_Div {
  position:relative;
  overflow: hidden;
  float:left;
  width: 100px;
}
div#out_Div_L {
  position:relative;
  overflow: hidden;
  float:left;
  width: 1050px;
}
div#in_Div {
  position:relative;
  overflow: auto;
  float:left;
  width: 100px;
  height: 100px;
}
div#in_Div_L {
  position:relative;
  overflow: hidden;
  float:left;
  width: 1050px;
  height: 100px;
}
        <style>
            td .dateFormat {
                display: none;
            }
body .pbBody table.list tr.headerRow td {
  text-align:center;font-weight:normal;
  padding:0px 0px 0px 1px;
}
body .pbBody table.list tr.headerRow td.header1 {
  text-align:center;font-weight:normal;
  padding:0px 0px 0px 0px;
}
body .pbBody table.list tr.dataRow td {padding:0px 0px 0px 1px; border-width: 0px 0px 1px 0px; vertical-align: middle; word-break:break-all;}
body .pbBody table.list tr.dataRow td.dataCellBorder  {
  /* いらない、使っていない */
  padding:0px 0px 0px 1px; border-width: 0px 0px 1px 0px; vertical-align: middle; word-break:break-all;
}
body .pbBody table.list tr.dataRow td.dataCellBorder1 {
  padding:0px 0px 0px 1px;
  border-width: 0px 0px 1px 1px; vertical-align: middle; word-break:break-all;
}
@-moz-document url-prefix() {
body .pbBody table.list tr.dataRow td.dataCellBorder1 {padding:0px 0px 0px 0px; border-width: 0px 0px 1px 1px; vertical-align: middle; word-break:break-all;}
}
table.list .col_Contract_NO {width:57px;}
table.list .checkbox {width:30px;text-align:center;}
table.list .col_HP_NAME {
width:120px;
}
table.list .col_PCL_NAME {width:80px;}
table.list .col_Agency1 {width:87px;}
table.list .col_SalesDepartment {width:85px;}
table.list .col_Province {width:20px;}
table.list .col_Group {width:65px;}
table.list .col_SalesIncharge {width:80px;}
table.list .col_OrderNo {width:80px;}
table.list .col_Status_1 {width:50px;}
table.list .col_Status_2 {width:80px;}
table.list .col_BookStock {width:50px;}
table.list .col_OCM {width:80px;}
table.list .col_DEPT {
/*width:auto;*/
width:230px;
}
table.list .col_Earch {
/*width:auto;*/
width:200px;
}
table.list .col_OpportunityCategory {width:50px;}
table.list .col_QuotationCode {width:80px;}
table.list .col_NOT_PaymentAmount {width:160px;text-align:right;}
table.list .col_UnshippedAmount_wt {width:100px;text-align:left;}
table.list .col_UnshippedAmount_bingo {width:216px;text-align:right;}
table.list .col_UnshippedAmount_bingo1 {width:216px;text-align:center;}
table.list .col_X5weeksAgo {width:80px;}
table.list .col_X4weeksAgo {width:80px;}
table.list .col_X3weeksAgo {width:80px;}
table.list .col_X2weeksAgo {width:80px;}
table.list .col_X1weeksAgo {width:80px;}
table.list .col_CurrentStatus {width:87px;}
table.list .col_OverviewStatus {width:80px;}
table.list .col_EndUserContract {width:100px;}
table.list .col_PaymentStatus {width:80px;}
table.list .col_AssignmentStatus {width:80px;}
table.list .col_DeliveryStatus {width:80px;}
table.list .col_PacialShipment {width:50px;}
table.list .col_SoLatestDeliveryDate {width:80px;}
table.list .col_FirstDeliveryDate {width:80px;}
table.list .col_CurrentShippingDate {width:80px;}
table.list .col_EndUserContractSubmitDay {width:80px;}
table.list .col_PaymentScheduledDate {width:80px;}
table.list .col_PaymentAllScheduledDate {width:80px;}
table.list .col_ShippingScheduledDate {width:80px;}
table.list .col_MonthlyForecast {width:105px;}
table.list .col_ForecastShipMonthlyMannual {width:75px;}
table.list .col_FollowUpComment {width:100px;}
table.list .col_FollowUpComment1 {width:100px;}
table.list .col_ReasonNotCollectMoney {width:200px;}
table.list .col_ReasonNotShip {width:200px;}
table.list .col_ManagerFeedback {width:200px;}
table.list .col_CreateActivity {width:80px;}
table.list .col_CreateTask {width:80px;}
table.list .col_Key_tipics {width:72px;}
table.list .col_Update_situation {width:72px;}
table.list .col_FirstApproveDate {width:72px;}
            div.inline {
                float: left;
            }
body .pbBody table.list tr.headerRow td.colViewing {
  background-image:url('{!URLFOR($Resource.IconResizeMinus_5)}') ;
  background-repeat:no-repeat;
}
body .pbBody table.list tr.headerRow td.colUnHideIcon {
  background-image:url('{!URLFOR($Resource.IconResizePlus_5)}');
  background-repeat:no-repeat;
  width:7px;
}
body .pbBody table.list tr.headerRow td.col_Scroll {width:0px; padding:0px; border-width:0px;}
body .pbBody table.list tr.dataRow td.col_Scroll {width:0px; padding:0px; border-width:0px;}
</style>
<script type="text/javascript">
            .clearBoth {
                clear: both;
            }
var heightAjustment = 120;
var widthAjustment = 30;
var keyArray = new Array({keyOfOpp:"id_Last_update_UnshippedAmount_without_tax", keyCol:"col_UnshippedAmount_wt"}
                        ,{keyOfOpp:"id_Last_update_OverviewStatus", keyCol:"col_OverviewStatus"}
                        ,{keyOfOpp:"id_Last_update_PaymentStatus", keyCol:"col_PaymentStatus"}
                        ,{keyOfOpp:"id_Last_update_AssignmentStatus", keyCol:"col_AssignmentStatus"}
                        ,{keyOfOpp:"id_Last_update_shipping_status", keyCol:"col_DeliveryStatus"}
                        ,{keyOfOpp:"id_Last_update_EndUser_contract_submit_day", keyCol:"col_EndUserContractSubmitDay"}
                        ,{keyOfOpp:"id_Last_update_Payment_Scheduled_Date", keyCol:"col_PaymentScheduledDate"}
                        ,{keyOfOpp:"id_Last_update_Payment_All_Scheduled_Date", keyCol:"col_PaymentAllScheduledDate"}
                        ,{keyOfOpp:"id_Last_update_forecast_shipping_date", keyCol:"col_ShippingScheduledDate"}
                        ,{keyOfOpp:"id_Last_update_followup_situation", keyCol:"col_FollowUpComment"}
                        ,{keyOfOpp:"id_Last_update_Reason_not_collect_money", keyCol:"col_ReasonNotCollectMoney"}
                        ,{keyOfOpp:"id_Last_update_Reason_not_ship", keyCol:"col_ReasonNotShip"}
                        ,{keyOfOpp:"id_Last_update_manager_feedback", keyCol:"col_ManagerFeedback"}
                        );
</script>
</head>
    <apex:form id="allForm">
            div#out_Div {
                position: relative;
                overflow: hidden;
                float: left;
                width: 100px;
            }
            div#out_Div_L {
                position: relative;
                overflow: hidden;
                float: left;
                width: 1050px;
            }
            div#in_Div {
                position: relative;
                overflow: auto;
                float: left;
                width: 100px;
                height: 100px;
            }
            div#in_Div_L {
                position: relative;
                overflow: hidden;
                float: left;
                width: 1050px;
                height: 100px;
            }
            body .pbBody table.list tr.headerRow td {
                text-align: center;
                font-weight: normal;
                padding: 0px 0px 0px 1px;
            }
            body .pbBody table.list tr.headerRow td.header1 {
                text-align: center;
                font-weight: normal;
                padding: 0px 0px 0px 0px;
            }
            body .pbBody table.list tr.dataRow td {
                padding: 0px 0px 0px 1px;
                border-width: 0px 0px 1px 0px;
                vertical-align: middle;
                word-break: break-all;
            }
            body .pbBody table.list tr.dataRow td.dataCellBorder {
                /* いらない、使っていない */
                padding: 0px 0px 0px 1px;
                border-width: 0px 0px 1px 0px;
                vertical-align: middle;
                word-break: break-all;
            }
            body .pbBody table.list tr.dataRow td.dataCellBorder1 {
                padding: 0px 0px 0px 1px;
                border-width: 0px 0px 1px 1px;
                vertical-align: middle;
                word-break: break-all;
            }
            @-moz-document url-prefix() {
                body .pbBody table.list tr.dataRow td.dataCellBorder1 {
                    padding: 0px 0px 0px 0px;
                    border-width: 0px 0px 1px 1px;
                    vertical-align: middle;
                    word-break: break-all;
                }
            }
            table.list .col_Contract_NO {
                width: 57px;
            }
            table.list .checkbox {
                width: 30px;
                text-align: center;
            }
            table.list .col_HP_NAME {
                width: 120px;
            }
            table.list .col_PCL_NAME {
                width: 80px;
            }
            table.list .col_Agency1 {
                width: 87px;
            }
            table.list .col_SalesDepartment {
                width: 85px;
            }
            table.list .col_Province {
                width: 20px;
            }
            table.list .col_Group {
                width: 65px;
            }
            table.list .col_SalesIncharge {
                width: 80px;
            }
            table.list .col_OrderNo {
                width: 80px;
            }
            table.list .col_Status_1 {
                width: 50px;
            }
            table.list .col_Status_2 {
                width: 80px;
            }
            table.list .col_BookStock {
                width: 50px;
            }
            table.list .col_OCM {
                width: 80px;
            }
            table.list .col_DEPT {
                /*width:auto;*/
                width: 230px;
            }
            table.list .col_Earch {
                /*width:auto;*/
                width: 200px;
            }
            table.list .col_OpportunityCategory {
                width: 50px;
            }
            table.list .col_QuotationCode {
                width: 80px;
            }
            table.list .col_NOT_PaymentAmount {
                width: 160px;
                text-align: right;
            }
            table.list .col_UnshippedAmount_wt {
                width: 100px;
                text-align: left;
            }
            table.list .col_UnshippedAmount_bingo {
                width: 216px;
                text-align: right;
            }
            table.list .col_UnshippedAmount_bingo1 {
                width: 216px;
                text-align: center;
            }
            table.list .col_X5weeksAgo {
                width: 80px;
            }
            table.list .col_X4weeksAgo {
                width: 80px;
            }
            table.list .col_X3weeksAgo {
                width: 80px;
            }
            table.list .col_X2weeksAgo {
                width: 80px;
            }
            table.list .col_X1weeksAgo {
                width: 80px;
            }
            table.list .col_CurrentStatus {
                width: 87px;
            }
            table.list .col_OverviewStatus {
                width: 80px;
            }
            table.list .col_EndUserContract {
                width: 100px;
            }
            table.list .col_PaymentStatus {
                width: 80px;
            }
            table.list .col_AssignmentStatus {
                width: 80px;
            }
            table.list .col_DeliveryStatus {
                width: 80px;
            }
            table.list .col_PacialShipment {
                width: 50px;
            }
            table.list .col_SoLatestDeliveryDate {
                width: 80px;
            }
            table.list .col_FirstDeliveryDate {
                width: 80px;
            }
            table.list .col_CurrentShippingDate {
                width: 80px;
            }
            table.list .col_EndUserContractSubmitDay {
                width: 80px;
            }
            table.list .col_PaymentScheduledDate {
                width: 80px;
            }
            table.list .col_PaymentAllScheduledDate {
                width: 80px;
            }
            table.list .col_ShippingScheduledDate {
                width: 80px;
            }
            table.list .col_MonthlyForecast {
                width: 105px;
            }
            table.list .col_ForecastShipMonthlyMannual {
                width: 75px;
            }
            table.list .col_FollowUpComment {
                width: 100px;
            }
            table.list .col_FollowUpComment1 {
                width: 100px;
            }
            table.list .col_ReasonNotCollectMoney {
                width: 200px;
            }
            table.list .col_ReasonNotShip {
                width: 200px;
            }
            table.list .col_ManagerFeedback {
                width: 200px;
            }
            table.list .col_CreateActivity {
                width: 80px;
            }
            table.list .col_CreateTask {
                width: 80px;
            }
            table.list .col_Key_tipics {
                width: 72px;
            }
            table.list .col_Update_situation {
                width: 72px;
            }
            table.list .col_FirstApproveDate {
                width: 72px;
            }
            body .pbBody table.list tr.headerRow td.colViewing {
                background-image:url('{!URLFOR($Resource.IconResizeMinus_5)}');
                background-repeat: no-repeat;
            }
            body .pbBody table.list tr.headerRow td.colUnHideIcon {
                background-image:url('{!URLFOR($Resource.IconResizePlus_5)}');
                background-repeat: no-repeat;
                width: 7px;
            }
            body .pbBody table.list tr.headerRow td.col_Scroll {
                width: 0px;
                padding: 0px;
                border-width: 0px;
            }
            body .pbBody table.list tr.dataRow td.col_Scroll {
                width: 0px;
                padding: 0px;
                border-width: 0px;
            }
        </style>
        
        <script type="text/javascript">
            //2022 02 25 张华建 display PI Data start
            var staticResource = JSON.parse('{!staticResource}');
            var awsDataIds = JSON.parse('{!awsDataIds}');
            var contact = {};
            queryPIData();
            function queryPIData(){
                blockme();
                let searchCallBack = function searchCallBack(result){
                    console.log('result = ' + JSON.stringify(result))
                    let contacts = result.object;
                    if(contacts == null){
                        return;
                    }
                    let temp = {}
                    temp.email = contacts.email;
                    temp.phone = contacts.phone;
                    if(contacts.lastName!=null){
                        temp.lastName = contacts.lastName;
                    }else{
                        temp.lastName = '';
                    }
                    contact[contacts.dataId] = temp;
                };
                for(var i = 0;i < awsDataIds.length;i++){
                    AWSService.query(staticResource.queryUrl,awsDataIds[i],searchCallBack,staticResource.token);
                }
                unblockUI();
            }
            function showPIDiv(awsDataId){
                console.log('awsDataId Value:'+awsDataId);
                let parentNode = document.getElementById(awsDataId);
                let createDiv = document.createElement("div");
                createDiv.id = awsDataId+"_PI";
                let piInformation = 'eamil:'+contact[awsDataId].email +'\n' +'Phone:'+contact[awsDataId].phone+'\n' +'Name:'+contact[awsDataId].lastName
                //let piInformation = 'Name:'+contact['943114607025717249'].lastName +'\n' +'Phone:'+contact['943114607025717249'].phone
                createDiv.innerText = piInformation;
                let x=window.event.x;
                let y=window.event.y;
                createDiv.style.left=x;
                createDiv.style.top=y;
                createDiv.style.background="#dddddd";
                createDiv.style.position = "absolute";
                parentNode.appendChild(createDiv);
            }
            function hidePIDiv(awsDataId){
                document.getElementById(awsDataId+'_PI').remove();
            }
            //2022 02 25 张华建 display PI Data end
            var heightAjustment = 120;
            var widthAjustment = 30;
            var keyArray = new Array({ keyOfOpp: "id_Last_update_UnshippedAmount_without_tax", keyCol: "col_UnshippedAmount_wt" }
                , { keyOfOpp: "id_Last_update_OverviewStatus", keyCol: "col_OverviewStatus" }
                , { keyOfOpp: "id_Last_update_PaymentStatus", keyCol: "col_PaymentStatus" }
                , { keyOfOpp: "id_Last_update_AssignmentStatus", keyCol: "col_AssignmentStatus" }
                , { keyOfOpp: "id_Last_update_shipping_status", keyCol: "col_DeliveryStatus" }
                , { keyOfOpp: "id_Last_update_EndUser_contract_submit_day", keyCol: "col_EndUserContractSubmitDay" }
                , { keyOfOpp: "id_Last_update_Payment_Scheduled_Date", keyCol: "col_PaymentScheduledDate" }
                , { keyOfOpp: "id_Last_update_Payment_All_Scheduled_Date", keyCol: "col_PaymentAllScheduledDate" }
                , { keyOfOpp: "id_Last_update_forecast_shipping_date", keyCol: "col_ShippingScheduledDate" }
                , { keyOfOpp: "id_Last_update_followup_situation", keyCol: "col_FollowUpComment" }
                , { keyOfOpp: "id_Last_update_Reason_not_collect_money", keyCol: "col_ReasonNotCollectMoney" }
                , { keyOfOpp: "id_Last_update_Reason_not_ship", keyCol: "col_ReasonNotShip" }
                , { keyOfOpp: "id_Last_update_manager_feedback", keyCol: "col_ManagerFeedback" }
            );
        </script>
    </head>
    <apex:form id="allForm">
        <!-- <apex:actionFunction name="saveAndSearch" action="{!save}" rerender="allPanel" oncomplete="unblockUI();">
            <apex:param name="firstParam" assignTo="{!saveType}" value="" />
        </apex:actionFunction> -->
@@ -166,8 +421,8 @@
            <apex:param name="thirdParam" assignTo="{!opp_ID}" value="" />
        </apex:actionFunction>
        <apex:actionFunction name="saveInquiryOpts" action="{!saveInquiryOpts}" rerender="allPanel" oncomplete="unblockUI();">
        <apex:param name="firstParam" assignTo="{!saveType}" value="" />
        <apex:param name="secondParam" assignTo="{!batchReason}" value="" />
            <apex:param name="firstParam" assignTo="{!saveType}" value="" />
            <apex:param name="secondParam" assignTo="{!batchReason}" value="" />
        </apex:actionFunction>
        <!-- <apex:actionFunction name="saveAndSort" action="{!save}" rerender="allPanel" oncomplete="unblockUI();">
            <apex:param name="firstParam" assignTo="{!saveType}" value="" />
@@ -177,13 +432,13 @@
        <apex:actionFunction name="sortTable" action="{!sortTable}" rerender="allPanel" oncomplete="unblockUI();">
            <apex:param name="firstParam" assignTo="{!sortKey}" value="" />
        </apex:actionFunction>
        <apex:outputPanel id="allPanel">
            <apex:pageBlock id="searchBlock" tabStyle="Report">
                <table style="border-bottom-width: 0px; font-size:12px;">
                    <tr>
                        <td width="150px">
                           <!--  <apex:commandButton action="{!save}" value="保存" rerender="allPanel" onclick="blockme();" oncomplete="unblockUI();" style="height:30px;width:50px;"/>&nbsp;&nbsp; -->
                            <!--  <apex:commandButton action="{!save}" value="保存" rerender="allPanel" onclick="blockme();" oncomplete="unblockUI();" style="height:30px;width:50px;"/>&nbsp;&nbsp; -->
                            <apex:commandButton value="检索" onclick="searchOppJs();return false;" style="height:30px;width:70px;"/>
                        </td>
                        <td width="1000px">
@@ -193,12 +448,19 @@
                </table>
                <table style="border-bottom-width: 0px; font-size:12px;">
                    <tr>
                        <td width="250px">科室&nbsp;<apex:inputText value="{!accSearch}" style="width:150px"/> </td>
                        <td width="250px">科室&nbsp;
                            <apex:inputText value="{!accSearch}" style="width:150px" /> </td>
                        <td width="75px">询问单名称&nbsp;&nbsp;&nbsp;&nbsp;</td>
                        <td width="150px"><span><apex:inputText value="{!ownerSearch}" style="width:100px;" /></span></td>
                        <td width="150px">
                            <span>
                                <apex:inputText value="{!ownerSearch}" style="width:100px;" />
                            </span>
                        </td>
                        <td width="10px"></td>
                        <td width="10px"></td>
                        <td>显示 <apex:selectList id="limitNo" value="{!limits}" size="1" onchange="searchOppJs();return false;"><apex:selectOptions value="{!limitOpts}"/></apex:selectList> 条数据</td>
                        <td>显示
                            <apex:selectList id="limitNo" value="{!limits}" size="1" onchange="searchOppJs();return false;">
                                <apex:selectOptions value="{!limitOpts}" /></apex:selectList> 条数据</td>
                        <td width="10px"></td>
                        <!-- 先隐藏批量功能 -->
                        <!-- <td>原因选项 &nbsp;<apex:selectList id="reasons" value="{!reasons}" size="1" onclick="setCheckValue();" ><apex:selectOptions value="{!reasonOpts}" /></apex:selectList> </td>
@@ -212,37 +474,43 @@
                    <tr>
                        <td width="400px">
                            <font>数据字段</font>&nbsp;
                            <apex:selectList value="{!text}" size="1" style="width:110px"><apex:selectOptions value="{!textOpts}"/></apex:selectList> 
                            &nbsp;<apex:selectList value="{!condition}" size="1"><apex:selectOptions value="{!equalOpts}"/></apex:selectList> 
                            &nbsp;<apex:inputText value="{!value}" style="width:100px"/>
                            <apex:selectList value="{!text}" size="1" style="width:110px">
                                <apex:selectOptions value="{!textOpts}" /></apex:selectList>  &nbsp;
                            <apex:selectList value="{!condition}" size="1">
                                <apex:selectOptions value="{!equalOpts}" /></apex:selectList>  &nbsp;
                            <apex:inputText value="{!value}" style="width:100px" />
                        </td>
                        <td width="10px"></td>
                        <td width="400px">
                            <font>AND&nbsp;</font>&nbsp;
                            <apex:selectList value="{!text2}" size="1" style="width:110px"><apex:selectOptions value="{!textOpts2}"/></apex:selectList> 
                            &nbsp;<apex:selectList value="{!condition2}" size="1"><apex:selectOptions value="{!equalOpts2}"/></apex:selectList> 
                            &nbsp;<apex:inputText value="{!value2}" style="width:100px"/>
                            <apex:selectList value="{!text2}" size="1" style="width:110px">
                                <apex:selectOptions value="{!textOpts2}" /></apex:selectList>  &nbsp;
                            <apex:selectList value="{!condition2}" size="1">
                                <apex:selectOptions value="{!equalOpts2}" /></apex:selectList>  &nbsp;
                            <apex:inputText value="{!value2}" style="width:100px" />
                        </td>
                        <td width="10px"></td>
                        <td width="400px">
                            <font>AND&nbsp;</font>&nbsp;
                            <apex:selectList value="{!text3}" size="1" style="width:110px"><apex:selectOptions value="{!textOpts3}"/></apex:selectList> 
                            &nbsp;<apex:selectList value="{!condition3}" size="1"><apex:selectOptions value="{!equalOpts3}"/></apex:selectList> 
                            &nbsp;<apex:inputText value="{!value3}" style="width:100px"/>
                            <apex:selectList value="{!text3}" size="1" style="width:110px">
                                <apex:selectOptions value="{!textOpts3}" /></apex:selectList>  &nbsp;
                            <apex:selectList value="{!condition3}" size="1">
                                <apex:selectOptions value="{!equalOpts3}" /></apex:selectList>  &nbsp;
                            <apex:inputText value="{!value3}" style="width:100px" />
                        </td>
                        <td></td>
                    </tr>
                </table>
            </apex:pageBlock>
            <apex:pageBlock id="oppBlock" tabStyle="Report">
                <apex:outputPanel >
                    <apex:inputHidden id="oppCount" value="{!pclCount}"/>
                    <apex:inputHidden id="oppCount" value="{!pclCount}" />
                    <div id="out_Div_L">
                        <table class="list" style="border-bottom-width: 0px; font-size:11px; border-spacing:0;" border="" id="tableHeader_L">
                            <tr class="headerRow" height="30px">
                                 <td class="checkbox">
                                   <input type="checkbox" id="chk" onchange="updateCheckBox();" />
                                <td class="checkbox">
                                    <input type="checkbox" id="chk" onchange="updateCheckBox();" />
                                </td>
                                <td class="col_Contract_NO">
                                    <a href="#" onclick="sortTableJs('22');return false;" style="text-decoration: underline;">询问单名称</a>{!sortOrder[22]}
@@ -259,7 +527,7 @@
                                <td class="col_UnshippedAmount_wt">
                                    产品信息
                                </td>
                                <td class="col_EndUserContract">
                                    委托事项
                                </td>
@@ -276,7 +544,7 @@
                    <div id="out_Div">
                        <table class="list" style="border-bottom-width: 0px; font-size:11px; border-spacing:0;width:707px;" border="" id="tableHeader">
                            <tr class="headerRow" height="30px">
                                <td class="col_NOT_PaymentAmount">
                                <td class="col_NOT_PaymentAmount">
                                    <a href="#" onclick="sortTableJs('13');return false;" style="text-decoration: underline;">主要学会</a>{!sortOrder[13]}
                                </td>
                                <td class="col_DeliveryStatus">
@@ -302,59 +570,64 @@
                                    <a href="#" onclick="sortTableJs('15');return false;" style="text-decoration: underline;">委托事项详细</a>{!sortOrder[15]}
                                </td>
                                <td id="cell_Scroll" class="col_Scroll"></td>
                            </tr>
                        </table>
                    </div>
                    </div>
                    <div style="clear:both;height:0px;"></div>
                    <div id="in_Div_L">
                        <table class="list" style="border-bottom-width: 0px; font-size:11px; border-spacing:0;" border="" id="tableData_L">
                            <apex:variable value="{!1}" var="cnt" />
                            <apex:repeat value="{!pclInfos}" var="or" id="oppTable_L">
                                <tr class="dataRow {!IF(MOD(cnt, 2)==0, 'odd', 'even')} {!IF(cnt==1, 'first', '')}" onmouseover="if (window.hiOn){hiOn(this);} " onmouseout="if (window.hiOff){hiOff(this);} " onblur="if (window.hiOff){hiOff(this);}" onfocus="if (window.hiOn){hiOn(this);}">
                                <td class="dataCellBorder1 checkbox">
                                   <input type="checkbox" id="{!or.chk}" onchange="editCheckBox();"/>
                                </td>
                                    <td class="dataCellBorder1 col_Contract_NO">
                                         <a href="https://ocsm.my.salesforce.com//{!or.rec.Id}"><apex:outputField id="Name" value="{!or.rec.Name}" /></a>
                                         <apex:inputHidden id="Id" value="{!or.rec.Id}"/>
                                         <apex:inputHidden id="Hospital_Name__c" value="{!or.rec.Hospital_Name__r.Name}"/>
                                        <apex:inputHidden id="Hospital_ID__c" value="{!or.rec.Hospital_ID__c}"/>
                                        <apex:inputHidden id="Contact_Id" value="{!or.rec.Contact_Id__c}"/>
                                <tr class="dataRow {!IF(MOD(cnt, 2)==0, 'odd', 'even')} {!IF(cnt==1, 'first', '')}" onmouseover="if (window.hiOn){hiOn(this);} "
                                    onmouseout="if (window.hiOff){hiOff(this);} " onblur="if (window.hiOff){hiOff(this);}" onfocus="if (window.hiOn){hiOn(this);}">
                                    <td class="dataCellBorder1 checkbox">
                                        <input type="checkbox" id="{!or.chk}" onchange="editCheckBox();" />
                                    </td>
                                    <td class="dataCellBorder1 col_Contract_NO" id="{!or.rec.AWS_Data_Id__c}" onmouseover="showPIDiv('{!or.rec.AWS_Data_Id__c}')" onmouseout="hidePIDiv('{!or.rec.AWS_Data_Id__c}')">
                                        <a href="https://ocsm.my.salesforce.com//{!or.rec.Id}">
                                            <apex:outputField id="Name" value="{!or.rec.Name}" />
                                        </a>
                                        <apex:inputHidden id="Id" value="{!or.rec.Id}" />
                                        <apex:inputHidden id="Hospital_Name__c" value="{!or.rec.Hospital_Name__r.Name}" />
                                        <apex:inputHidden id="Hospital_ID__c" value="{!or.rec.Hospital_ID__c}" />
                                        <apex:inputHidden id="Contact_Id" value="{!or.rec.Contact_Id__c}" />
                                    </td>
                                    <td class="dataCellBorder1 col_DEPT">
                                        <apex:outputField id="Department_Class__c" value="{!or.rec.Department_Class__c}"/>
                                        <apex:inputHidden id="Department_ID__c" value="{!or.rec.Department_ID__c}"/>
                                   </td>
                                   <td class="dataCellBorder1 col_CurrentStatus">
                                        <apex:outputField id="Status__c" style="text-align:center;" value="{!or.rec.Status__c}"/>
                                        <apex:outputField id="Department_Class__c" value="{!or.rec.Department_Class__c}" />
                                        <apex:inputHidden id="Department_ID__c" value="{!or.rec.Department_ID__c}" />
                                    </td>
                                    <td class="dataCellBorder1 col_UnshippedAmount_wt" id="{!cnt-1}:col_UnshippedAmount_wt" >
                                    <td class="dataCellBorder1 col_CurrentStatus">
                                        <apex:outputField id="Status__c" style="text-align:center;" value="{!or.rec.Status__c}" />
                                    </td>
                                    <td class="dataCellBorder1 col_UnshippedAmount_wt" id="{!cnt-1}:col_UnshippedAmount_wt">
                                        <apex:outputField value="{!or.rec.Product1__c}" id="company" />
                                    </td>
                                    <td class="dataCellBorder1 col_EndUserContract">
                                        <apex:outputField id="Request1__c" value="{!or.rec.Request1__c}"/>
                                     </td>
                                    <td class="dataCellBorder1 col_Earch" >
                                        <apex:inputField id="Opp_Name_Search__c" value="{!or.rec.Opp_Name_Search__c}"/>
                                         <apex:inputHidden id="Opp_Name_Search_ID__c" value="{!or.rec.Opp_Name_Search_ID__c}"/>
                                        <apex:outputField id="Request1__c" value="{!or.rec.Request1__c}" />
                                    </td>
                                    <td class="dataCellBorder1 col_Earch">
                                        <apex:inputField id="Opp_Name_Search__c" value="{!or.rec.Opp_Name_Search__c}" />
                                        <apex:inputHidden id="Opp_Name_Search_ID__c" value="{!or.rec.Opp_Name_Search_ID__c}" />
                                    </td>
                                    <td class="dataCellBorder1 col_UnshippedAmount_bingo1">
                                    <span>
                                    <apex:commandButton value="需要" style="width: 40px;" onclick="openEdit('{!or.lineNo}');return false;" />
                                    </span>
                                    <span>
                                    <apex:commandButton value="不需要" style="width: 50px;" onclick="updateStatus('{!or.rec.Id}','{!or.lineNo}');return false;" />
                                    </span>
                                    <span>
                                    <apex:inputField id="Reasons_options__c"  value="{!or.rec.Reasons_options__c}" style="width: 90px;" onchange="setreasonFlg('{!or.lineNo}')" />
                                    </span>
                            </td>
                                        <span>
                                            <apex:commandButton value="需要" style="width: 40px;" onclick="openEdit('{!or.lineNo}');return false;" />
                                        </span>
                                        <span>
                                            <apex:commandButton value="不需要" style="width: 50px;" onclick="updateStatus('{!or.rec.Id}','{!or.lineNo}');return false;"
                                            />
                                        </span>
                                        <span>
                                            <apex:inputField id="Reasons_options__c" value="{!or.rec.Reasons_options__c}" style="width: 90px;" onchange="setreasonFlg('{!or.lineNo}')"
                                            />
                                        </span>
                                    </td>
                                </tr>
                                <apex:variable value="{!cnt + 1}" var="cnt" />
                            </apex:repeat>
@@ -364,332 +637,336 @@
                        <table class="list" style="border-bottom-width: 0px; font-size:11px; border-spacing:0;width:707px;" border="" id="tableData">
                            <apex:variable value="{!1}" var="cnt" />
                            <apex:repeat value="{!pclInfos}" var="or" id="oppTable">
                                <tr class="dataRow {!IF(MOD(cnt, 2)==0, 'odd', 'even')} {!IF(cnt==1, 'first', '')}" onmouseover="if (window.hiOn){hiOn(this);} " onmouseout="if (window.hiOff){hiOff(this);} " onblur="if (window.hiOff){hiOff(this);}" onfocus="if (window.hiOn){hiOn(this);}">
                                <tr class="dataRow {!IF(MOD(cnt, 2)==0, 'odd', 'even')} {!IF(cnt==1, 'first', '')}" onmouseover="if (window.hiOn){hiOn(this);} "
                                    onmouseout="if (window.hiOff){hiOff(this);} " onblur="if (window.hiOff){hiOff(this);}" onfocus="if (window.hiOn){hiOn(this);}">
                                    <td class="dataCellBorder1 col_NOT_PaymentAmount">
                                        <apex:outputField id="Campaign__c" value="{!or.rec.Campaign__c}" style="width:90%;"/>
                                        <apex:inputHidden id="Campaign_ID__c" value="{!or.rec.Campaign_ID__c}"/>
                                        <apex:outputField id="Campaign__c" value="{!or.rec.Campaign__c}" style="width:90%;" />
                                        <apex:inputHidden id="Campaign_ID__c" value="{!or.rec.Campaign_ID__c}" />
                                    </td>
                                    <!-- <td class="dataCellBorder1 col_Name">
                                        <apex:outputField id="Name" value="{!or.rec.Name}" style="width:90%;"/>
                                    </td> -->
                                    <td class="dataCellBorder1 col_DeliveryStatus">
                                        <apex:outputField id="Family_Name__c" value="{!or.rec.Family_Name__c}"/>
                                        <apex:outputField id="Last_Name__c" value="{!or.rec.Last_Name__c}"/>
                                        <!-- <apex:outputField id="Family_Name__c" value="{!or.rec.Family_Name__c}" /> -->
                                        <apex:outputField id="Last_Name__c" value="{!or.rec.Last_Name__c}" />
                                    </td>
                                    <!-- <td class="dataCellBorder1 col_DeliveryStatus">
                                        <apex:outputField id="Phone__c" value="{!or.rec.Phone__c}"/>
                                    </td> -->
                                    <td class="dataCellBorder1 col_SoLatestDeliveryDate">
                                        <apex:outputField id="Phone__c" value="{!or.rec.Phone__c}" style="width:90%;"/>
                                        <apex:outputField id="Phone__c" value="{!or.rec.Phone__c}" style="width:90%;" />
                                    </td>
                                    <td class="dataCellBorder1 col_ShippingScheduledDate"  style="padding:0;">
                                        <apex:outputField value="{!or.rec.Email__c}" id="Email__c" style="width:90%;"/>
                                    <td class="dataCellBorder1 col_ShippingScheduledDate" style="padding:0;">
                                        <apex:outputField value="{!or.rec.Email__c}" id="Email__c" style="width:90%;" />
                                    </td>
                                    <td class="dataCellBorder1 col_Agency1">
                                        <apex:outputField id="Cancel_Reason__c" value="{!or.rec.Cancel_Reason__c}" style="width:90%;"/>
                                        <apex:outputField id="Cancel_Reason__c" value="{!or.rec.Cancel_Reason__c}" style="width:90%;" />
                                    </td>
                                    <td class="dataCellBorder1 col_CreateActivity">
                                        <apex:outputField id="Opportunity_Division__c" value="{!or.rec.Opportunity_Division__c}" />
                                    </td>
                                    </td>
                                    <td class="dataCellBorder1 col_Province">
                                        <apex:outputField value="{!or.rec.Urgent__c}" id="Urgent__c" />
                                    </td>
                                    <td class="dataCellBorder1 col_MonthlyForecast" id="{!cnt-1}:col_MonthlyForecast" style="padding:0;">
                                        <apex:outputField value="{!or.rec.Request_Detail__c}" id="Request_Detail__c" />
                                        <apex:inputHidden id="Inquiry_No__c" value="{!or.rec.Inquiry_No__c}"/>
                                        <apex:inputHidden id="LeadSource__c" value="{!or.rec.LeadSource__c}"/>
                                       <!--  <apex:inputHidden id="Name" value="{!or.rec.Name}"/> -->
                                        <apex:inputHidden id="Id" value="{!or.rec.Id}"/>
                                        <apex:inputHidden id="Inquiry_No__c" value="{!or.rec.Inquiry_No__c}" />
                                        <apex:inputHidden id="LeadSource__c" value="{!or.rec.LeadSource__c}" />
                                        <!--  <apex:inputHidden id="Name" value="{!or.rec.Name}"/> -->
                                        <apex:inputHidden id="Id" value="{!or.rec.Id}" />
                                    </td>
                                    <td id="cell_Scroll" class="col_Scroll">
                                 <apex:inputHidden value="{!or.changeFlg}" id="changeFlg"/>
                                 <apex:inputHidden value="{!or.reasonFlg}" id="reasonFlg"/>
<script type="text/javascript">
//将询问单上的值带到 新建意向页面上
function openEdit(line) {
    //医院名
    var HospitalName = j$(escapeVfId('allPage:allForm:oppBlock:oppTable_L:'+ (line) + ':Hospital_Name__c')).value();
                                        <apex:inputHidden value="{!or.changeFlg}" id="changeFlg" />
                                        <apex:inputHidden value="{!or.reasonFlg}" id="reasonFlg" />
                                        <script type="text/javascript">
                                            //将询问单上的值带到 新建意向页面上
                                            function openEdit(line) {
    var HospitalId = j$(escapeVfId('allPage:allForm:oppBlock:oppTable_L:'+ (line) + ':Hospital_ID__c')).value();
    //战略科室分类
    var DepartmentClass = j$(escapeVfId('allPage:allForm:oppBlock:oppTable_L:'+ (line) + ':Department_Class__c')).text();
                                                //医院名
                                                var HospitalName = j$(escapeVfId('allPage:allForm:oppBlock:oppTable_L:' + (line) + ':Hospital_Name__c')).value();
    var DepartmentID = j$(escapeVfId('allPage:allForm:oppBlock:oppTable_L:'+ (line) + ':Department_ID__c')).value();
                                                var HospitalId = j$(escapeVfId('allPage:allForm:oppBlock:oppTable_L:' + (line) + ':Hospital_ID__c')).value();
                                                //战略科室分类
                                                var DepartmentClass = j$(escapeVfId('allPage:allForm:oppBlock:oppTable_L:' + (line) + ':Department_Class__c')).text();
    //已有询价名称
    var OppNameSearch = j$(escapeVfId('allPage:allForm:oppBlock:oppTable_L:'+ (line) + ':Opp_Name_Search__c')).text();
                                                var DepartmentID = j$(escapeVfId('allPage:allForm:oppBlock:oppTable_L:' + (line) + ':Department_ID__c')).value();
    var OppNameSearchID = j$(escapeVfId('allPage:allForm:oppBlock:oppTable_L:'+ (line) + ':Opp_Name_Search_ID__c')).value();
                                                //已有询价名称
                                                var OppNameSearch = j$(escapeVfId('allPage:allForm:oppBlock:oppTable_L:' + (line) + ':Opp_Name_Search__c')).text();
    //主要学会
    var Campaign = j$(escapeVfId('allPage:allForm:oppBlock:oppTable:'+ (line) + ':Campaign__c')).text();
                                                var OppNameSearchID = j$(escapeVfId('allPage:allForm:oppBlock:oppTable_L:' + (line) + ':Opp_Name_Search_ID__c')).value();
    var CampaignId = j$(escapeVfId('allPage:allForm:oppBlock:oppTable:'+ (line) + ':Campaign_ID__c')).value();
    //询问单名称
    var Name = j$(escapeVfId('allPage:allForm:oppBlock:oppTable_L:'+ (line) + ':Name')).value();
                                                //主要学会
                                                var Campaign = j$(escapeVfId('allPage:allForm:oppBlock:oppTable:' + (line) + ':Campaign__c')).text();
    var Id = j$(escapeVfId('allPage:allForm:oppBlock:oppTable_L:'+ (line) + ':Id')).value();
    //客户姓名
    var contactName = Name;
    var contactId = j$(escapeVfId('allPage:allForm:oppBlock:oppTable_L:'+ (line) + ':Contact_Id')).value();
                                                var CampaignId = j$(escapeVfId('allPage:allForm:oppBlock:oppTable:' + (line) + ':Campaign_ID__c')).value();
                                                //询问单名称
                                                var Name = j$(escapeVfId('allPage:allForm:oppBlock:oppTable_L:' + (line) + ':Name')).value();
    // //询问单编码
    // var InquiryNo = j$(escapeVfId('allPage:allForm:oppBlock:oppTable:'+ (line) + ':Inquiry_No__c')).value();
    //取消文本
    var CancelReason =j$(escapeVfId('allPage:allForm:oppBlock:oppTable:'+ (line) + ':Cancel_Reason__c')).text();
                                                var Id = j$(escapeVfId('allPage:allForm:oppBlock:oppTable_L:' + (line) + ':Id')).value();
    //委托事项详细
    var RequestDetail =j$(escapeVfId('allPage:allForm:oppBlock:oppTable:'+ (line) + ':Request_Detail__c')).text();
                                                //客户姓名
                                                var contactName = Name;
                                                var contactId = j$(escapeVfId('allPage:allForm:oppBlock:oppTable_L:' + (line) + ':Contact_Id')).value();
    //询问单状态
    var Status = j$(escapeVfId('allPage:allForm:oppBlock:oppTable_L:'+ (line) + ':Status__c')).text();
    //公司
    var company = HospitalName;
                                                // //询问单编码
                                                // var InquiryNo = j$(escapeVfId('allPage:allForm:oppBlock:oppTable:'+ (line) + ':Inquiry_No__c')).value();
                                                //取消文本
                                                var CancelReason = j$(escapeVfId('allPage:allForm:oppBlock:oppTable:' + (line) + ':Cancel_Reason__c')).text();
    //电话
    var Phone =j$(escapeVfId('allPage:allForm:oppBlock:oppTable:'+ (line) + ':Phone__c')).value();
    //邮件
    var Email =j$(escapeVfId('allPage:allForm:oppBlock:oppTable:'+ (line) + ':Email__c')).value();
    //姓
    var FamilyName=j$(escapeVfId('allPage:allForm:oppBlock:oppTable:'+ (line) + ':Family_Name__c')).text();
    //名
    var LastName =j$(escapeVfId('allPage:allForm:oppBlock:oppTable:'+ (line) + ':Last_Name__c')).text();
    //询问单来源
    var LeadSource =j$(escapeVfId('allPage:allForm:oppBlock:oppTable:'+ (line) + ':LeadSource__c')).value();
    //意向区分
    var OpportunityDivision =j$(escapeVfId('allPage:allForm:oppBlock:oppTable:'+ (line) + ':Opportunity_Division__c')).text();
    //委托事项
    var Request =j$(escapeVfId('allPage:allForm:oppBlock:oppTable_L:'+ (line) + ':Request1__c')).text();
                                                //委托事项详细
                                                var RequestDetail = j$(escapeVfId('allPage:allForm:oppBlock:oppTable:' + (line) + ':Request_Detail__c')).text();
    //紧急
    var Urgent ='';
    var title2 =j$(escapeVfId('allPage:allForm:oppBlock:oppTable:'+ (line) + ':Urgent__c')).find('img').attr("title");
    if(title2 =='选取的'){
        Urgent = '1';
    }else{
        Urgent = '0';
    }
                                                //询问单状态
                                                var Status = j$(escapeVfId('allPage:allForm:oppBlock:oppTable_L:' + (line) + ':Status__c')).text();
                                                //公司
                                                var company = HospitalName;
    // var Urgent =j$(escapeVfId('allPage:allForm:oppBlock:oppTable:'+ (line) + ':Urgent__c')).value();
        //JZ-20191015 会议询问单确认一览表点击需要带值到新建意向页面
                                                //电话
                                                var Phone = j$(escapeVfId('allPage:allForm:oppBlock:oppTable:' + (line) + ':Phone__c')).value();
                                                //邮件
                                                var Email = j$(escapeVfId('allPage:allForm:oppBlock:oppTable:' + (line) + ':Email__c')).value();
                                                //姓
                                                var FamilyName = j$(escapeVfId('allPage:allForm:oppBlock:oppTable:' + (line) + ':Family_Name__c')).text();
                                                //名
                                                var LastName = j$(escapeVfId('allPage:allForm:oppBlock:oppTable:' + (line) + ':Last_Name__c')).text();
                                                //询问单来源
                                                var LeadSource = j$(escapeVfId('allPage:allForm:oppBlock:oppTable:' + (line) + ':LeadSource__c')).value();
                                                //意向区分
                                                var OpportunityDivision = j$(escapeVfId('allPage:allForm:oppBlock:oppTable:' + (line) + ':Opportunity_Division__c')).text();
                                                //委托事项
                                                var Request = j$(escapeVfId('allPage:allForm:oppBlock:oppTable_L:' + (line) + ':Request1__c')).text();
         var urlStr =       '/00Q/e?RecordType=01210000000QiRa&ent=Lead'+
                            '&CF00N10000006ps6f='+encodeURI(contactName)+
                            '&CF00N10000006ps6f_lkid='+encodeURI(contactId)+
                            '&CF00N10000002CvC5='+encodeURI(HospitalName)+
                            '&CF00N10000002CvC5_lkid='+encodeURI(HospitalId)+
                            '&CF00N10000006qNtt='+encodeURI(DepartmentClass)+
                            '&CF00N10000006qNtt_lkid='+encodeURI(DepartmentID)+
                            '&CF00N10000006qNty='+encodeURI(OppNameSearch)+
                            '&CF00N10000006qNty_lkid='+encodeURI(OppNameSearchID)+
                            '&CF00N10000004oN28='+encodeURI(Campaign)+
                            '&CF00N10000004oN28_lkid='+encodeURI(CampaignId)+
                            '&CF00N1000000962np='+encodeURI(Name)+
                            '&CF00N1000000962np_lkid='+encodeURI(Id)+
                            '&00N10000006qBYk='+encodeURI(CancelReason)+
                            '&00N10000002CvBM='+encodeURI(RequestDetail)+
                            '&lea13='+encodeURI(Status)+
                            '&lea3='+encodeURI(company)+
                            '&lea8='+encodeURI(Phone.trim())+
                            '&lea11='+encodeURI(Email.trim())+
                            '&name_lastlea2='+encodeURI(FamilyName)+
                            '&name_firstlea2='+encodeURI(LastName)+
                            '&lea5='+encodeURI(LeadSource)+
                            '&00N10000002CvBR='+encodeURI(Request)+
                            '&00N10000002CvBC='+encodeURI(OpportunityDivision)+
                            '&00N10000002CvB7='+encodeURI(Urgent)
                            ;
        //JZ-20191015 会议询问单确认一览表点击需要带值到新建意向页面 END
                                                //紧急
                                                var Urgent = '';
                                                var title2 = j$(escapeVfId('allPage:allForm:oppBlock:oppTable:' + (line) + ':Urgent__c')).find('img').attr("title");
                                                if (title2 == '选取的') {
                                                    Urgent = '1';
                                                } else {
                                                    Urgent = '0';
                                                }
        window.open(urlStr);
}
function setreasonFlg(line){
    document.getElementById('allPage:allForm:oppBlock:oppTable:' + line + ':reasonFlg').value = 1;
    var reason = j$(escapeVfId('allPage:allForm:oppBlock:oppTable_L:'+line+':Reasons_options__c')).value();
    var Opp_Name_Search = j$(escapeVfId('allPage:allForm:oppBlock:oppTable_L:'+line+':Opp_Name_Search__c')).value();
                                                // var Urgent =j$(escapeVfId('allPage:allForm:oppBlock:oppTable:'+ (line) + ':Urgent__c')).value();
                                                //JZ-20191015 会议询问单确认一览表点击需要带值到新建意向页面
    if(Opp_Name_Search == ''){
        if (reason == '已经有询价') {
            alert('请您填写已有询价名称后,再点击不需要按钮进行更新!');
             j$(escapeVfId('allPage:allForm:oppBlock:oppTable_L:'+line+':Opp_Name_Search__c_lkwgt')).show();
             j$(escapeVfId('allPage:allForm:oppBlock:oppTable_L:'+line+':Opp_Name_Search__c')).attr('disabled',false);
        }else{
             j$(escapeVfId('allPage:allForm:oppBlock:oppTable_L:'+line+':Opp_Name_Search__c_lkwgt')).hide();
             j$(escapeVfId('allPage:allForm:oppBlock:oppTable_L:'+line+':Opp_Name_Search__c')).attr('disabled',true);
        }
    }
}
//全选或多选时将询问单状态改为不要 (点击页面最上方的不需要按钮)
function changeStatus(){
    var cnt = document.getElementById('allPage:allForm:oppBlock:oppCount').value;
    var arr = [];//将原因和状态 全部遍历放到一个数组中
    for(var i=0 ;i<cnt;i++){
        if (j$(escapeVfId('chk'+i)).attr('checked')) {
            var reason =j$(escapeVfId('allPage:allForm:oppBlock:oppTable_L:'+i+':Reasons_options__c')).value();
            var status = j$(escapeVfId('allPage:allForm:oppBlock:oppTable_L:'+i+':Status__c')).value();
            arr.push(reason);
            arr.push(status);
        }
    }
    //定义一个状态用于判断 原因是否有为空或者 询问单状态是否有不要
    var statusFlg = 0;
    //当页面没有勾选数据时
    if(arr.length == 0){
        statusFlg =3;
    }
    for(var j=0;j<arr.length;j++){
                                                var urlStr = '/00Q/e?RecordType=01210000000QiRa&ent=Lead' +
                                                    '&CF00N10000006ps6f=' + encodeURI(contactName) +
                                                    '&CF00N10000006ps6f_lkid=' + encodeURI(contactId) +
                                                    '&CF00N10000002CvC5=' + encodeURI(HospitalName) +
                                                    '&CF00N10000002CvC5_lkid=' + encodeURI(HospitalId) +
                                                    '&CF00N10000006qNtt=' + encodeURI(DepartmentClass) +
                                                    '&CF00N10000006qNtt_lkid=' + encodeURI(DepartmentID) +
                                                    '&CF00N10000006qNty=' + encodeURI(OppNameSearch) +
                                                    '&CF00N10000006qNty_lkid=' + encodeURI(OppNameSearchID) +
                                                    '&CF00N10000004oN28=' + encodeURI(Campaign) +
                                                    '&CF00N10000004oN28_lkid=' + encodeURI(CampaignId) +
                                                    '&CF00N1000000962np=' + encodeURI(Name) +
                                                    '&CF00N1000000962np_lkid=' + encodeURI(Id) +
                                                    '&00N10000006qBYk=' + encodeURI(CancelReason) +
                                                    '&00N10000002CvBM=' + encodeURI(RequestDetail) +
                                                    '&lea13=' + encodeURI(Status) +
                                                    '&lea3=' + encodeURI(company) +
                                                    '&lea8=' + encodeURI(Phone.trim()) +
                                                    '&lea11=' + encodeURI(Email.trim()) +
                                                    '&name_lastlea2=' + encodeURI(FamilyName) +
                                                    '&name_firstlea2=' + encodeURI(LastName) +
                                                    '&lea5=' + encodeURI(LeadSource) +
                                                    '&00N10000002CvBR=' + encodeURI(Request) +
                                                    '&00N10000002CvBC=' + encodeURI(OpportunityDivision) +
                                                    '&00N10000002CvB7=' + encodeURI(Urgent)
                                                    ;
                                                //JZ-20191015 会议询问单确认一览表点击需要带值到新建意向页面 END
        if(arr[j] == '不需要'){
            statusFlg =1;
        }
        if(!arr[j]){
            statusFlg =2;
        }
    }
//根据状态的不同区分打印的内容 或者 要执行的更新
    if(statusFlg == 0){
        var count = document.getElementById('allPage:allForm:oppBlock:oppCount').value;
        for(var y=0 ;y<count;y++){
            if (j$(escapeVfId('chk'+y)).attr('checked')) {
                var inquiryformId =  j$(escapeVfId('allPage:allForm:oppBlock:oppTable:'+y+ ':Id')).value();
                setreasonFlg(y);
            }
        }
        var batchReason =j$(escapeVfId('allPage:allForm:searchBlock:reasons')).value();
        saveInquiryOpts('',batchReason);
    }else if(statusFlg == 1){
            alert('您勾选的数据中有询问单状态为‘不要’状态,请您勾掉后再进行批量不需要。');
    }else if(statusFlg == 2){
            alert('您勾选的数据中存在没有选择原因选项的数据,请您选择原因选项保存后再操作。');
    }else if(statusFlg == 3){
            alert('请您先勾选要批量修改的数据!');
    }
                                                window.open(urlStr);
                                            }
                                            function setreasonFlg(line) {
                                                document.getElementById('allPage:allForm:oppBlock:oppTable:' + line + ':reasonFlg').value = 1;
                                                var reason = j$(escapeVfId('allPage:allForm:oppBlock:oppTable_L:' + line + ':Reasons_options__c')).value();
                                                var Opp_Name_Search = j$(escapeVfId('allPage:allForm:oppBlock:oppTable_L:' + line + ':Opp_Name_Search__c')).value();
}
//单选时 将询问单状态改为不要 (点击页面table上的不需要按钮)
function updateStatus(id,lineNo) {
    var inquiryformId = id;
    //传入 id和原因选项两个参数
    var reason = j$(escapeVfId('allPage:allForm:oppBlock:oppTable_L:'+lineNo+':Reasons_options__c')).value();
    var opp_Name_Search = j$(escapeVfId('allPage:allForm:oppBlock:oppTable_L:'+lineNo+':Opp_Name_Search__c')).value();
    var opp_ID =j$(escapeVfId('allPage:allForm:oppBlock:oppTable_L:'+lineNo+':Opp_Name_Search__c_lkid')).value();
     if(!reason){
        alert('请您先选择原因选项,再点击按钮。');
        return;
    }else if(reason == '已经有询价' && opp_Name_Search ==''){
        alert('请您填写已有询价名称后,再点击不需要按钮进行更新!');
        return;
    }else{
    //2.修改询问单状态为关闭
        saveInquiryform(inquiryformId,reason,opp_ID);
     //刷新页面
     // location.replace(location.href);
    }
}
                                                if (Opp_Name_Search == '') {
                                                    if (reason == '已经有询价') {
                                                        alert('请您填写已有询价名称后,再点击不需要按钮进行更新!');
                                                        j$(escapeVfId('allPage:allForm:oppBlock:oppTable_L:' + line + ':Opp_Name_Search__c_lkwgt')).show();
                                                        j$(escapeVfId('allPage:allForm:oppBlock:oppTable_L:' + line + ':Opp_Name_Search__c')).attr('disabled', false);
                                                    } else {
                                                        j$(escapeVfId('allPage:allForm:oppBlock:oppTable_L:' + line + ':Opp_Name_Search__c_lkwgt')).hide();
                                                        j$(escapeVfId('allPage:allForm:oppBlock:oppTable_L:' + line + ':Opp_Name_Search__c')).attr('disabled', true);
                                                    }
//全选 checkbox
function updateCheckBox(){
    var limit = j$(escapeVfId('allPage:allForm:searchBlock:limitNo')).value();
    var cnt =document.getElementById('allPage:allForm:oppBlock:oppCount').value;
    if(j$(escapeVfId('chk')).attr('checked')){
        if(cnt >limit){
            var limitno = limit;
            for(var i=0;i<limitno;i++){
                                                }
                                            }
                                            //全选或多选时将询问单状态改为不要 (点击页面最上方的不需要按钮)
                                            function changeStatus() {
                                                var cnt = document.getElementById('allPage:allForm:oppBlock:oppCount').value;
                                                var arr = [];//将原因和状态 全部遍历放到一个数组中
                                                for (var i = 0; i < cnt; i++) {
                                                    if (j$(escapeVfId('chk' + i)).attr('checked')) {
                                                        var reason = j$(escapeVfId('allPage:allForm:oppBlock:oppTable_L:' + i + ':Reasons_options__c')).value();
                                                        var status = j$(escapeVfId('allPage:allForm:oppBlock:oppTable_L:' + i + ':Status__c')).value();
                                                        arr.push(reason);
                                                        arr.push(status);
                                                    }
                                                }
                                                //定义一个状态用于判断 原因是否有为空或者 询问单状态是否有不要
                                                var statusFlg = 0;
                                                //当页面没有勾选数据时
                                                if (arr.length == 0) {
                                                    statusFlg = 3;
                                                }
                                                for (var j = 0; j < arr.length; j++) {
                j$(escapeVfId('chk'+i)).attr('checked',true);
            }
        }else{
            var cntnumber = cnt;
            for(var j =0 ;j<cntnumber;j++){
                                                    if (arr[j] == '不需要') {
                                                        statusFlg = 1;
                                                    }
                                                    if (!arr[j]) {
                                                        statusFlg = 2;
                                                    }
                                                }
                                                //根据状态的不同区分打印的内容 或者 要执行的更新
                                                if (statusFlg == 0) {
                                                    var count = document.getElementById('allPage:allForm:oppBlock:oppCount').value;
                                                    for (var y = 0; y < count; y++) {
                                                        if (j$(escapeVfId('chk' + y)).attr('checked')) {
                                                            var inquiryformId = j$(escapeVfId('allPage:allForm:oppBlock:oppTable:' + y + ':Id')).value();
                                                            setreasonFlg(y);
                                                        }
                                                    }
                                                    var batchReason = j$(escapeVfId('allPage:allForm:searchBlock:reasons')).value();
                                                    saveInquiryOpts('', batchReason);
                                                } else if (statusFlg == 1) {
                                                    alert('您勾选的数据中有询问单状态为‘不要’状态,请您勾掉后再进行批量不需要。');
                                                } else if (statusFlg == 2) {
                                                    alert('您勾选的数据中存在没有选择原因选项的数据,请您选择原因选项保存后再操作。');
                                                } else if (statusFlg == 3) {
                                                    alert('请您先勾选要批量修改的数据!');
                                                }
                j$(escapeVfId('chk'+j)).attr('checked',true);
            }
        }
    }else{
        if(cnt >limit){
            var limitno = limit;
            for(var i=0;i<limitno;i++){
                j$(escapeVfId('chk'+i)).attr('checked',false);
            }
        }else{
            var cntnumber = cnt;
            for(var j =0 ;j<cntnumber;j++){
                j$(escapeVfId('chk'+j)).attr('checked',false);
            }
        }
    }
}
//当选择全选后 取消勾掉其中一个或者多个时 勾掉全选
function editCheckBox (){
    var limit = j$(escapeVfId('allPage:allForm:searchBlock:limitNo')).value();
    var cnt =document.getElementById('allPage:allForm:oppBlock:oppCount').value;
    if(cnt >limit){
        var limitno = limit;
            for(var i=0;i<limitno;i++){
                if(j$(escapeVfId('chk'+i)).attr('checked')){
                    j$(escapeVfId('chk')).attr('checked',false);
                }
            }
        }else{
            var cntnumber = cnt;
            for(var j =0 ;j<cntnumber;j++){
                if(j$(escapeVfId('chk'+j)).attr('checked')){
                        j$(escapeVfId('chk')).attr('checked',false);
                    }
            }
        }
}
//批量选择原因 保存
function setCheckValue(){
    var cnt = document.getElementById('allPage:allForm:oppBlock:oppCount').value;
    for(var i=0 ;i<cnt;i++){
        if (j$(escapeVfId('chk'+i)).attr('checked')) {
            var reason =  j$(escapeVfId('allPage:allForm:searchBlock:reasons')).value();
                                            }
                                            //单选时 将询问单状态改为不要 (点击页面table上的不需要按钮)
                                            function updateStatus(id, lineNo) {
                                                var inquiryformId = id;
                                                //传入 id和原因选项两个参数
                                                var reason = j$(escapeVfId('allPage:allForm:oppBlock:oppTable_L:' + lineNo + ':Reasons_options__c')).value();
                                                var opp_Name_Search = j$(escapeVfId('allPage:allForm:oppBlock:oppTable_L:' + lineNo + ':Opp_Name_Search__c')).value();
                                                var opp_ID = j$(escapeVfId('allPage:allForm:oppBlock:oppTable_L:' + lineNo + ':Opp_Name_Search__c_lkid')).value();
                                                if (!reason) {
                                                    alert('请您先选择原因选项,再点击按钮。');
                                                    return;
                                                } else if (reason == '已经有询价' && opp_Name_Search == '') {
                                                    alert('请您填写已有询价名称后,再点击不需要按钮进行更新!');
                                                    return;
                                                } else {
                                                    //2.修改询问单状态为关闭
                                                    saveInquiryform(inquiryformId, reason, opp_ID);
                                                    //刷新页面
                                                    // location.replace(location.href);
                                                }
            document.getElementById('allPage:allForm:oppBlock:oppTable_L:' + i + ':Reasons_options__c').value = reason;
            setChangeFlg(i);
        }
                                            }
    }
                                            //全选 checkbox
                                            function updateCheckBox() {
                                                var limit = j$(escapeVfId('allPage:allForm:searchBlock:limitNo')).value();
                                                var cnt = document.getElementById('allPage:allForm:oppBlock:oppCount').value;
                                                if (j$(escapeVfId('chk')).attr('checked')) {
                                                    if (cnt > limit) {
                                                        var limitno = limit;
                                                        for (var i = 0; i < limitno; i++) {
}
</script>
            </td>
         </tr>
            <apex:variable value="{!cnt + 1}" var="cnt" />
            </apex:repeat>
        </table>
                                                            j$(escapeVfId('chk' + i)).attr('checked', true);
                                                        }
                                                    } else {
                                                        var cntnumber = cnt;
                                                        for (var j = 0; j < cntnumber; j++) {
                                                            j$(escapeVfId('chk' + j)).attr('checked', true);
                                                        }
                                                    }
                                                } else {
                                                    if (cnt > limit) {
                                                        var limitno = limit;
                                                        for (var i = 0; i < limitno; i++) {
                                                            j$(escapeVfId('chk' + i)).attr('checked', false);
                                                        }
                                                    } else {
                                                        var cntnumber = cnt;
                                                        for (var j = 0; j < cntnumber; j++) {
                                                            j$(escapeVfId('chk' + j)).attr('checked', false);
                                                        }
                                                    }
                                                }
                                            }
                                            //当选择全选后 取消勾掉其中一个或者多个时 勾掉全选
                                            function editCheckBox() {
                                                var limit = j$(escapeVfId('allPage:allForm:searchBlock:limitNo')).value();
                                                var cnt = document.getElementById('allPage:allForm:oppBlock:oppCount').value;
                                                if (cnt > limit) {
                                                    var limitno = limit;
                                                    for (var i = 0; i < limitno; i++) {
                                                        if (j$(escapeVfId('chk' + i)).attr('checked')) {
                                                            j$(escapeVfId('chk')).attr('checked', false);
                                                        }
                                                    }
                                                } else {
                                                    var cntnumber = cnt;
                                                    for (var j = 0; j < cntnumber; j++) {
                                                        if (j$(escapeVfId('chk' + j)).attr('checked')) {
                                                            j$(escapeVfId('chk')).attr('checked', false);
                                                        }
                                                    }
                                                }
                                            }
                                            //批量选择原因 保存
                                            function setCheckValue() {
                                                var cnt = document.getElementById('allPage:allForm:oppBlock:oppCount').value;
                                                for (var i = 0; i < cnt; i++) {
                                                    if (j$(escapeVfId('chk' + i)).attr('checked')) {
                                                        var reason = j$(escapeVfId('allPage:allForm:searchBlock:reasons')).value();
                                                        document.getElementById('allPage:allForm:oppBlock:oppTable_L:' + i + ':Reasons_options__c').value = reason;
                                                        setChangeFlg(i);
                                                    }
                                                }
                                            }
                                        </script>
                                    </td>
                                </tr>
                                <apex:variable value="{!cnt + 1}" var="cnt" />
                            </apex:repeat>
                        </table>
                    </div>
                </apex:outputPanel>
            </apex:pageBlock>
<script type="text/javascript">
j$(function() {
    bindTdToggleWidth();
});
var elements = document.getElementsByTagName("select");
for (i = 0; i < elements.length; i++) {
    var id = elements[i].id;
    if (id.length > 5 && id.substring(id.length - 5, id.length) == 'mlktp') {
        elements[i].style.display = "none";
    }
}
            <script type="text/javascript">
                j$(function() {
                    bindTdToggleWidth();
                });
                var elements = document.getElementsByTagName("select");
                for (i = 0; i < elements.length; i++) {
                    var id = elements[i].id;
                    if (id.length > 5 && id.substring(id.length - 5, id.length) == 'mlktp') {
                        elements[i].style.display = "none";
                    }
                }
</script>
            </script>
        </apex:outputPanel>
    </apex:form>
</apex:page>
force-app/main/default/pages/NewAndEditASEActivity.page
New file
@@ -0,0 +1,526 @@
<apex:page standardController="ASEActivity__c" extensions="NewAndEditASEActivityController" id="page">
    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
    <script src="../../soap/ajax/53.0/connection.js" type="text/javascript"></script>
    <apex:stylesheet value="{!URLFOR($Resource.blockUIcss)}"/>
    <apex:includeScript value="{!URLFOR($Resource.jquery183minjs)}"/>
    <apex:includeScript value="{!URLFOR($Resource.PleaseWaitDialog)}"/>
    <style>
        .disabledbutton {
            pointer-events: none;
            opacity: 0.4;
        }
    </style>
    <script>
        var config = {};
        config = {
            SobjectName : "{!SobjectName}",
            ApiPrefix:"{!ApiPrefix}",
            SaveAndNew:false,
            AWSToSobjectMap:{!AWSToSobjectMapJson},
            AWSToSobjectNonEncryptedMap:{!AWSToSobjectNonEncryptedMapJson},
            AWSToSobjectEncryptedMap:{!AWSToSobjectEncryptedMapJson},
            SobjectToAWSModel:function (sobjJson) {
                let leadPayloadList = [];
                let leadPIData = {};
                for(let f in config.AWSToSobjectMap){
                    if(sobjJson.hasOwnProperty(config.AWSToSobjectMap[f])){
                        leadPIData[f] = sobjJson[config.AWSToSobjectMap[f]]
                    }
                    else{
                        console.log(config.AWSToSobjectMap[f] + 'is not in sobjJson');
                    }
                }
                leadPIData.sfRecordId = '';
                console.log('Sobject PI Data:' + leadPIData);
                leadPayloadList.push(leadPIData);
                console.log(JSON.stringify(leadPayloadList));
                return JSON.stringify(leadPayloadList);
            },
            insertOrUpdateBack:function(payloadJson, r, isNewMode){
                for(let f in config.AWSToSobjectMap){
                    if(r.object[0].hasOwnProperty(f)){
                        payloadJson[config.AWSToSobjectMap[f]] = r.object[0][f];
                    }
                    else{
                        console.log(f + 'is not in r.object[0]');
                    }
                }
                for(let f in config.AWSToSobjectEncryptedMap){
                    if(r.object[0].hasOwnProperty(f)){
                        payloadJson[config.AWSToSobjectEncryptedMap[f]] = r.object[0][f];
                    }
                    else{
                        console.log(f + 'is not in r.object[0]');
                    }
                }
                //payloadJson.AWS_Data_Id__c = r.object[0].dataId;
                payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
                if (isNewMode) {
                    payloadJson.AWS_Data_Id__c = r.object[0].dataId;
                } else {
                    payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
                }
                return payloadJson;
            },
            queryBack:function (data) {
                console.log('data = ' + data);
                if(data.object){
                    for(let f in config.AWSToSobjectNonEncryptedMap){
                        let ele = GetEleByClass(config.ApiPrefix + "_"+ config.AWSToSobjectNonEncryptedMap[f]);
                        if(data.object.hasOwnProperty(f) && ele){
                            // 多选特殊处理
                            if(ele.type == 'select-multiple'){
                               //let me = GetEleByClass(config.ApiPrefix+'_'+field_api_name);
                            if(ele && data.object[f]){
                                let arr = data.object[f].split(';');
                                // 给隐藏的select赋值
                                for(let op of ele.options){
                                    op.selected = arr.indexOf(op.value)>-1;
                                }
                                // 利用按钮给显示的select赋值
                                let ra = document.getElementById(ele.id + '_right_arrow');
                                if(ra){
                                    ra.click();
                                }
                            }
                            }else{
                                ele.value = data.object[f];
                            }
                        }
                        else{
                            console.log(f + 'is not in data.object');
                        }
                    }
                }
                else{
                    console.log('data.object = ' + data.object);
                }
                // document.querySelector("[data-id='LastName']").value = data.object.lastName;
                // document.querySelector("[data-id='Phone']").value = data.object.phone;
                // document.querySelector("[data-id='Email']").value = data.object.email;
            },
            updateMethod:"NewAndEditASEActivityController.saveASEActivity",
            insertMethod:"NewAndEditASEActivityController.saveASEActivity"
        }
        AWSService.sfSessionId = '{!GETSESSIONID()}';
        var requiredFieldAPIList = JSON.parse('{!requiredFieldAPIListStr}');
        var fieldAPIToLabelMap = JSON.parse('{!fieldAPIToLabelMapStr}');
        var staticResources = JSON.parse('{!staticResource}');
        var staticResourcesContact = JSON.parse('{!staticResourceContact}');
        console.log('{!staticResource}');
        var VLookUpFields = {! VLookUpFieldsJson};
        function ProcessPI(sobjJson, payloadForNewPI) {
            blockme();
            if ({!isNewMode}) {
                NewPIToAWS(sobjJson, payloadForNewPI)
            }else {
                UpdatePIToAWS(sobjJson, payloadForNewPI)
            }
        }
        var GetEleByClass = function(class_name){
            let eles = document.getElementsByClassName(class_name);
            if(eles.length > 0) return eles[0];
            return null;
        }
        var GetEleApiName = function(ele){
            for(let c of ele.classList){
                if(c.indexOf(config.ApiPrefix+'_')>-1){
                    return c.replace(config.ApiPrefix+'_','');
                }
            }
            return '';
        }
        function IsFormElement(tag_name){
            return ['input','select','textarea'].indexOf(tag_name)>-1;
        }
        function getPIPayload(sobjJson) {
            return config.SobjectToAWSModel(sobjJson);
        }
        function validateFieldValueFormate() {
            let error_msg = '';
            // let textEmail = "[data-id='Email']";
            let textPhone = "[data-id='CustomerTel__c']";
            // //Email
            // let email = document.querySelector(textEmail);
            // if(email && !/^[\w-]{3,12}@[\da-zA-Z]{2,16}\.[a-zA-Z]+$/.test(email.value)){
            //     error_msg += ';邮件格式错误';
            // }
            let phone = document.querySelector(textPhone);
            if(phone && !/^1[3|5|8|7][0-9]\d{4,8}$/.test(phone.value)){
                error_msg += ';电话号码错误';
            }
            for(let e of document.getElementsByTagName('select')){
                for(let op of e.options){
                    if(op.value == "*****" && op.selected){
                        error_msg += ';下拉框不能主动选择密文选项';
                    }
                }
            }
            if(error_msg.length>0 && error_msg[0]== ';'){
                error_msg = error_msg.substring(1);
            }
            return error_msg;
        }
        function getSobjectInformation() {
            let nodelist = document.getElementsByClassName(config.ApiPrefix);
            let result = {}
            for (let index = 0; index < nodelist.length; index++) {
                let ele = nodelist[index];
                let field_api_name = GetEleApiName(ele);
                let tag_name = ele.tagName.toLowerCase();
                if(!IsFormElement(tag_name)){
                    console.log('tag_name='+tag_name+',field_api_name'+field_api_name+' is not a form element');
                    continue;
                }
                if (VLookUpFields.indexOf(field_api_name)>=0) {
                    console.log(ele.id.indexOf('lkwgt'));
                    if (ele.id.indexOf('lkwgt') == -1) {
                        let vlookUpNodeId = ele.id + '_lkid';
                        let vlook_ele = document.getElementById(vlookUpNodeId);
                        let v = '';
                        if(vlook_ele){
                            v = vlook_ele.value;
                        }else{
                            v = ele.value;
                        }
                        if(v && v != "000000000000000"){
                            result[field_api_name] = v;
                        }
                    }
                } else if (ele.type == 'checkbox') {
                    result[field_api_name] = ele.checked;
                } else if (ele.type == 'select-multiple') {
                    //field_api_name
                    let multiple = field_api_name;
                    let targets = GetEleByClass(config.ApiPrefix+'_'+field_api_name).parentNode.children[1].children[0].children[1].children[2].children[0].innerText;
                    targets = targets.replace(/\n/g, ";");
                    console.log('targets = ' + targets);
                    result[field_api_name] = targets;
                } else {
                    result[field_api_name] = ele.value;
                }
            }
            return result;
        }
        function QuerySobjectFromAWS() {
            AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
        }
        function queryBack(data) {
            console.log('data = ' + data);
            config.queryBack(data);
            unblockUI();
        };
        function insertOrUpdateBack(payloadJson, result, isNewMode) {
            console.log(result);
            let r = result;
            console.log('Result from AWS' + r);
            console.log('payloadJson=' + payloadJson);
            return config.insertOrUpdateBack(payloadJson, r, isNewMode);
        }
        function redirectCallBack(sfId,errorMsg) {
            unblockUI();
            if(errorMsg){
                alertErrorMessage(errorMsg);
            }
            else{
                if(config.SaveAndNew){
                    window.open('{! SaveAndNewButtonUrl }','_self');
                }else{
                    window.open('/' + sfId, '_self');
                }
            }
        }
        function UpdatePIToAWS(sobjJson, payloadForNewPI) {
            let controllerSaveMethod = config.updateMethod;
            let obj = JSON.parse(payloadForNewPI);
            obj[0].dataId = '{!AWSDataId}';
            let payloadForNewPIJson = JSON.stringify(obj);
            AWSService.update(staticResources.updateUrl, sobjJson, payloadForNewPIJson, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, false, insertOrUpdateBack,redirectCallBack);
        }
        function NewPIToAWS(sobjJson, payloadForNewPI) {
            let controllerSaveMethod = config.insertMethod;
            AWSService.insert(staticResources.newUrl, sobjJson, payloadForNewPI, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, true, insertOrUpdateBack,redirectCallBack);
        }
        function checkRequiredFieldMsg(formData) {
            let blankRequiredFields = '';
            for(i = 0;i<requiredFieldAPIList.length;i++){
                if(formData[requiredFieldAPIList[i]]){
                    continue;
                }else{
                    if(blankRequiredFields == ''){
                        blankRequiredFields =blankRequiredFields + fieldAPIToLabelMap[requiredFieldAPIList[i]];
                    }else{
                        blankRequiredFields =blankRequiredFields+',' + fieldAPIToLabelMap[requiredFieldAPIList[i]];
                    }
                }
            }
            return blankRequiredFields;
        }
        function saveSobjectProcess(save_and_new) {
            if(save_and_new){
                config.SaveAndNew = true;
            }
            hiddenErrorMsgNode();
            //1. Get Sobject Information from Form
            let sobjJson = getSobjectInformation();
            //2. Validate the Sobject field value formate, for example the email formate or phone formate
            let validationResultMessage = validateFieldValueFormate();
            console.log(validationResultMessage);
            if (validationResultMessage) {
                //Popup error message.  - To Do After POC
                alertErrorMessage(validationResultMessage);
                return
            }
            // Check Required Field
            let checkRequiredFieldMsgResult = checkRequiredFieldMsg(sobjJson);
            if (checkRequiredFieldMsgResult) {
                alertErrorMessage('requiredErrorMsg' + checkRequiredFieldMsgResult);
                return
            }
            // //3. Prepare the payload for New PI API To AWS - To Do
            let payloadForNewPI = getPIPayload(sobjJson);
            // //4. Get Authentication Information for AWS
            // loadAWSAuthentication();
            // //5. ASEActivity to AWS
            ProcessPI(sobjJson, payloadForNewPI);
            // awsToken = TestToken;
            // NewPIToAWS(sobjJson,awsToken, payloadForNewPI)
        }
        function alertErrorMessage(errorMsg) {
            let errorMsgNode = document.getElementById("page:form:block:msgContent");
            errorMsgNode.innerText = errorMsg;
            errorMsgNode.className = 'pbError';
        }
        function hiddenErrorMsgNode() {
            let errorMsgNode = document.getElementById("page:form:block:msgContent");
            errorMsgNode.innerText = '';
            errorMsgNode.className = '';
        }
        var newSearchContactWindow = null;
        var contactHtmlString = '<img src="/img/s.gif" onclick="searchContact(\'page:form:contactId\')" alt="Reference Document Number Lookup" class="lookupIcon"  title="Reference Document Number Lookup (New Window)"/>';
        function htmlToElement(html) {
            var template = document.createElement('template');
            html = html.trim(); // Never return a text node of whitespace as the result
            template.innerHTML = html;
            return template.content.firstChild;
        }
        function searchContact(contactNodeId){
            // errorMsg 隐藏
            if(document.getElementsByClassName("errorMsg").length > 0){
                document.getElementsByClassName("errorMsg")[0].style.display="none";
            }
            let accountValue = "";
            let suffixUrl = "";
            if (document.querySelector("[data-id='Department__c']")) {
                let accountNodeId = document.querySelector("[data-id='Department__c']").id + '_lkid';
                accountValue = document.getElementById(accountNodeId).value;
            }
            console.log('accountValue = ' + accountValue);
            if(accountValue !='000000000000000'){
                suffixUrl = "?contactId="+contactNodeId+"&accountId="+accountValue;
            }else{
                suffixUrl = "?contactId="+contactNodeId;
            }
            let baseUrl = "/apex/SearchContactPage";
            let newSearchContactParam = 'height=600,width=800,left=100,top=100,dialogHide=true,resizable=no,scrollbars=yes,toolbar=no,status=no';
            newSearchContactWindow = window.open(baseUrl+suffixUrl, 'Popup', newSearchContactParam);
            if (window.focus) {
                newSearchContactWindow.focus();
            }
            return false;
        }
        function closePopupWindow() {
            if (null != newSearchContactWindow) {
                newSearchContactWindow.close();
            }
            let contactInfoStr = document.getElementById('page:form:contactId').value;
            console.log('closePopup:'+contactInfoStr);
            let contactInfo = JSON.parse(contactInfoStr);
            let contactNodeId = document.querySelector("[data-id='ReporterASE__c']").id + '_lkid';
            document.getElementById(contactNodeId).value = contactInfo.ContactId;
            document.querySelector("[data-id='ReporterASE__c']").value = contactInfo.Name;
        }
        function replaceSearchContactLookup() {
            let lookUpNode = htmlToElement(contactHtmlString);
            console.log(lookUpNode);
            if (!{!isNewMode}) {
                //1. Query Contact from AWS by AWSDataId
                queryContactName()
            }
            let parentNode = document.querySelector("[data-id='ReporterASE__c']").parentNode;
            document.querySelector("[data-id='ReporterASE__c']").removeAttribute("onchange");
            parentNode.replaceChild(lookUpNode, document.querySelector("[data-id='ReporterASE__c']").parentNode.children[2]);
        }
        function queryContactName() {
            let sfId = document.getElementById(document.querySelector("[data-id='ReporterASE__c']").id + '_lkid').value;
            let contactsInfo = JSON.parse('{!LookUpOverrideFieldsMapJson}');
            let dataId = contactsInfo[sfId];
            let queryContactBack = function(data){
                //To Do later
                console.log('ContactData = ' + data.object);
                document.querySelector("[data-id='ReporterASE__c']").value = data.object.lastName;
            }
            AWSService.query(staticResourcesContact.queryUrl, dataId, queryContactBack, staticResources.token);
            // let url = staticResourcesContact.queryUrl + '?dataId=' + dataId;
            // fetch(url, {
            //     method: 'GET',
            //     headers: {
            //         'Content-Type': 'application/json',
            //         'pi-token': staticResources.token
            //     }
            // }).then((data) => {
            //     return data.json();
            // }).then((result) => {
            //     document.querySelector("[data-id='ReporterASE__c']").value = result.object.lastName;
            // })
        }
    </script>
    <div class="bPageTitle">
        <div class="ptBody">
            <div class="content">
                <img src="/img/s.gif" alt="{! SobjectLabel}" class="pageTitleIcon" title="{! SobjectLabel}" />
                <h1 class="pageType">{! SobjectLabel}<apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText>
                    <span class="titleSeparatingColon">:</span>
                </h1>
                <h2 class="pageDescription"> <apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText>{! SobjectLabel}</h2>
                <div class="blank">&nbsp;</div>
            </div>
            <div class="links">
                <a href="javascript:openPopupFocusEscapePounds(%27https://help.salesforce.com/apex/htdoor?loc=help&amp;target={!sobjectTypeValue}s_edit.htm&amp;section={!sobjectTypeValue}s&amp;language=zh_CN&amp;release=234.18.8&amp;instance=CS117&amp;showSplash=true%27, %27Help%27, 700, 600, %27width=700,height=600,resizable=yes,toolbar=yes,status=no,scrollbars=yes,menubar=yes,directories=no,location=no,dependant=no%27, false, false);"
                    title="此页面的帮助 (新窗口)">
                    <span class="helpLink">此页面的帮助</span>
                    <img src="/img/s.gif" alt="" class="helpIcon" />
                </a>
            </div>
        </div>
        <div class="ptBreadcrumb"></div>
    </div>
    <apex:form id="form">
        <apex:inputHidden value="{!contactId}" id="contactId"/>
        <apex:pageblock id="block">
            <div class="pbHeader">
                <table cellspacing="0" cellpadding="0" border="0">
                    <tbody>
                        <tr>
                            <td class="pbTitle">
                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />
                                <h2 class="mainTitle">{! SobjectLabel}<apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText></h2>
                            </td>
                            <td class="pbButton" id="topButtonRow">
                                <input class="btn" type="Button" value="{!$Label.Save}" onclick="saveSobjectProcess()" />
                                <input class="btn" type="Button" value="{!$Label.SaveAndNew}" onclick="saveSobjectProcess(1)" />
                                <apex:commandButton action="{!cancel}" value="{!$Label.Cancel}" />
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>
            <!-- Error Msg-->
            <div style="text-align: center;">
                <apex:outputPanel id="errorMsg">
                    <apex:pageMessages id="msgContent" escape="false" />
                </apex:outputPanel>
            </div>
            <!-- Iterate the layoutSections, which is a list of sections -->
            <apex:repeat value="{!layoutSections}" var="layoutSection">
                <apex:pageBlockSection title="{!layoutSection.name}" collapsible="{!layoutSection.allowCollapse}" columns="{!layoutSection.columns}">
                    <!--Each section has layoutFields, let's iterate them as well-->
                    <apex:repeat value="{!layoutSection.layoutFields}" var="layoutField">
                        <apex:inputField styleClass="{!ApiPrefix} {!ApiPrefix}_{!layoutField.fieldAPI}" html-data-id="{!layoutField.fieldAPI}" value="{!ASEActivity__c[layoutField.fieldAPI]}" rendered="{!not(layoutField.isPlaceHOlder)}"
                            required="{!layoutField.isRequired}" />
                        <apex:pageblocksectionitem rendered="{!layoutField.isPlaceHolder}">
                        </apex:pageblocksectionitem>
                    </apex:repeat>
                </apex:pageBlockSection>
            </apex:repeat>
            <script>
                sfdcPage.appendToOnloadQueue(function () {
                    //1. Set Last Name label
                    //document.querySelector("[data-id='LastName']").parentNode.parentNode.parentNode.children[2].children[0].innerText = '姓名';
                    //2. Query AWS Data by dataId
                    console.log('Mode for Sobject Page:' + {!isNewMode});
                    if (!{!isNewMode}) {
                        blockme();
                        QuerySobjectFromAWS();
                    }
                    //Replace Vlookup Field
                    replaceSearchContactLookup();
                    document.querySelectorAll("[data-id='OwnerId']")[0].classList.add("disabledbutton");
                    document.querySelectorAll("[data-id='OwnerId']")[1].classList.add("disabledbutton");
                });
            </script>
            <div class="pbBottomButtons">
                <table cellspacing="0" cellpadding="0" border="0">
                    <tbody>
                        <tr>
                            <td class="pbTitle">
                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />&nbsp;</td>
                            <td class="pbButtonb" id="bottomButtonRow">
                                <input class="btn" type="Button" value="{!$Label.Save}" onclick="saveSobjectProcess()" />
                                <input class="btn" type="Button" value="{!$Label.SaveAndNew}" onclick="saveSobjectProcess()" />
                                <apex:commandButton action="{!cancel}" value="{!$Label.Cancel}" />
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>
        </apex:pageblock>
    </apex:form>
</apex:page>
force-app/main/default/pages/NewAndEditASEActivity.page-meta.xml
New file
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <availableInTouch>false</availableInTouch>
    <confirmationTokenRequired>false</confirmationTokenRequired>
    <label>NewAndEditASEActivity</label>
</ApexPage>
force-app/main/default/pages/NewAndEditAddress.page
New file
@@ -0,0 +1,427 @@
<apex:page standardController="Address__c" extensions="NewAndEditAddressController" id="page">
    <apex:stylesheet value="{!URLFOR($Resource.blockUIcss)}"/>
    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
    <apex:includeScript value="{!URLFOR($Resource.jquery183minjs)}"/>
    <apex:includeScript value="{!URLFOR($Resource.PleaseWaitDialog)}"/>
    <script src="../../soap/ajax/53.0/connection.js" type="text/javascript"></script>
    <style>
        .disabledbutton {
            pointer-events: none;
            opacity: 0.4;
        }
    </style>
    <script>
        AWSService.sfSessionId = '{!GETSESSIONID()}';
        var staticResources = JSON.parse('{!staticResource}');
        var staticResourcesContact = JSON.parse('{!staticResourceContact}');
        var requiredFieldAPIList = JSON.parse('{!requiredFieldAPIListStr}');
        var fieldAPIToLabelMap = JSON.parse('{!fieldAPIToLabelMapStr}');
        var redirectMode = 'Save';//1. Save 2. SaveAndNew
        var requiredAPIToChangedLabelMap = new Map();
        requiredAPIToChangedLabelMap.set('LastName', '{!PIPL_Name_Label}');
        console.log('{!contactsInfo}');
        var VLookUpFields = new Set(['Contacts__c', 'Province__c', 'City__c', 'Customer__c']);
        function ProcessPI(addressJson, payloadForNewPI) {
            blockme();
            if ({!isNewMode}) {
                NewPIToAWS(addressJson, payloadForNewPI)
            }else {
                UpdatePIToAWS(addressJson, payloadForNewPI)
            }
        }
        function enableButton(obj){
            obj.classList.remove("btnDisabled");
        }
        function disableButton(obj){
            obj.classList.add("btnDisabled");
        }
        function disableButtonStatus(){
            let btnList = document.getElementsByClassName('btn');
            for(let i=0;i<btnList.length;i++){
                disableButton(btnList[i]);
            }
        }
        function enableButtonStatus(){
            let btnList = document.getElementsByClassName('btn');
            for(let i=0;i<btnList.length;i++){
                enableButton(btnList[i]);
            }
        }
        function getPIPayload(addressJson) {
            let addressPayloadList = [];
            let Telephone = addressJson.Telephone__c;
            let ZipCode = addressJson.ZipCode__c;
            let DetailedAddress = addressJson.Detailed_Address__c;
            let addressPIData = new Object();
            addressPIData.telephone = Telephone;
            addressPIData.zipCode = ZipCode;
            addressPIData.detailedAddress = DetailedAddress;
            addressPIData.sfRecordId = '';
            console.log('Address PI Data:' + addressPIData);
            addressPayloadList.push(addressPIData);
            console.log(JSON.stringify(addressPayloadList));
            return JSON.stringify(addressPayloadList);
        }
        function validateFieldValueFormate() {
            let error_msg = '';
            // let textEmail = "[data-id='Email']";
            let textPhone = "[data-id='Telephone__c']";
            //Email
            // let email = document.querySelector(textEmail);
            // if(email && !/^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.[a-zA-Z0-9]{2,6}$/.test(email.value)){
            //     error_msg += ';邮件格式错误';
            // }
            let phone = document.querySelector(textPhone);
            if(phone && !/^1[3|5|8|7][0-9]\d{4,8}$/.test(phone.value)){
                error_msg += ';电话号码错误';
            }
            for(let e of document.getElementsByTagName('select')){
                for(let op of e.options){
                    if(op.value == "*****" && op.selected){
                        error_msg += ';下拉框不能主动选择密文选项';
                    }
                }
            }
            if(error_msg.length>0 && error_msg[0]== ';'){
                error_msg = error_msg.substring(1);
            }
            return error_msg;
        }
        function getAddressInformation() {
            let nodelist = document.querySelectorAll("[data-id]");
            let result = {}
            result.RecordTypeId = '{!rtTypeId}';
            for (let index = 0; index < nodelist.length; index++) {
                if (VLookUpFields.has(nodelist[index].getAttribute("data-id"))) {
                    console.log(nodelist[index].id.indexOf('lkwgt'));
                    if (nodelist[index].id.indexOf('lkwgt') == -1) {
                        let vlookUpNodeId = nodelist[index].id + '_lkid';
                        let vlookUpNodeValue = document.getElementById(vlookUpNodeId).value;
                        result[nodelist[index].getAttribute("data-id")] = vlookUpNodeValue;
                    }
                } else if (nodelist[index].type == 'checkbox') {
                    result[nodelist[index].getAttribute("data-id")] = nodelist[index].checked;
                } else if (nodelist[index].type == 'select-multiple') {
                    //nodelist[index].getAttribute("data-id")
                    let multiple = nodelist[index].getAttribute("data-id");
                    let targets = document.querySelector("[data-id=" + multiple + "]").parentNode.children[1].children[0].children[1].children[2].children[0].innerText;
                    targets = targets.replace(/\n/g, ";");
                    console.log('targets = ' + targets);
                    result[nodelist[index].getAttribute("data-id")] = targets;
                } else {
                    result[nodelist[index].getAttribute("data-id")] = nodelist[index].value;
                }
                let x = index + 1;
                if (x <= nodelist.length - 1 && (nodelist[x].getAttribute("data-id") == nodelist[index].getAttribute("data-id"))) {
                    index++;
                }
            }
            return result;
        }
        function QueryAddressFromAWS() {
            AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
        }
        var queryBack = function queryBack(data) {
            console.log('data = ' + data);
            document.querySelector("[data-id='Telephone__c']").value = data.object.telephone;
            document.querySelector("[data-id='ZipCode__c']").value = data.object.zipCode;
            document.querySelector("[data-id='Detailed_Address__c']").value = data.object.detailedAddress;
            unblockUI();
        };
        var insertOrUpdateBack = function insertOrUpdateBack(payloadJson, result, isNewMode) {
            console.log(result);
            let r = result;
            console.log('Result from AWS' + r);
            console.log('payloadJson=' + payloadJson);
            payloadJson.Telephone__c = r.object[0].telephone;
            payloadJson.ZipCode__c = r.object[0].zipCode;
            payloadJson.Detailed_Address__c = r.object[0].detailedAddress;
            payloadJson.Telephone_Encrypted__c = r.object[0].telephoneEncrypt;
            payloadJson.ZipCode_Encrypted__c = r.object[0].zipCodeEncrypt;
            payloadJson.Detailed_Address_Encrypted__c = r.object[0].detailedAddressEncrypt;
            //payloadJson.AWS_Data_Id__c = r.object[0].dataId;
            payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
            if (isNewMode) {
                payloadJson.AWS_Data_Id__c = r.object[0].dataId;
            } else {
                payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
            }
            return payloadJson;
        }
        var redirectCallBack = function redirectCallBack(sfId,errorMessage) {
            if(sfId){
                if(redirectMode == 'Save'){
                    window.open('/' + sfId, '_self');
                }else if(redirectMode == 'SaveAndNew'){
                    window.open('/' + sfId + '/e?retURL=%2F' + sfId + '=%2Fo', '_self');
                }
            }else{
                // alert(errorMessage);
                alertErrorMessage(errorMessage);
            }
        }
        function UpdatePIToAWS(addressJson, payloadForNewPI) {
            let controllerSaveMethod = '{!$RemoteAction.NewAndEditAddressController.saveAddress}';
            let obj = JSON.parse(payloadForNewPI);
            obj[0].dataId = '{!AWSDataId}';
            let payloadForNewPIJson = JSON.stringify(obj);
            AWSService.update(staticResources.updateUrl, addressJson, payloadForNewPIJson, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, false, insertOrUpdateBack,redirectCallBack);
        }
        function NewPIToAWS(addressJson, payloadForNewPI) {
            let controllerSaveMethod = '{!$RemoteAction.NewAndEditAddressController.saveAddress}';
            AWSService.insert(staticResources.newUrl, addressJson, payloadForNewPI, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, true, insertOrUpdateBack,redirectCallBack);
        }
        function checkRequiredFieldMsg(formData) {
            let blankRequiredFields = '';
            for(i = 0;i<requiredFieldAPIList.length;i++){
                if(formData[requiredFieldAPIList[i]]){
                    continue;
                }else{
                    let fieldAPIValue = requiredFieldAPIList[i]
                    let fieldLabelValue = fieldAPIToLabelMap[fieldAPIValue];
                    if (requiredAPIToChangedLabelMap.has(fieldAPIValue)) {
                        fieldLabelValue = requiredAPIToChangedLabelMap.get(fieldAPIValue);
                    }
                    if(blankRequiredFields == ''){
                        blankRequiredFields =blankRequiredFields + fieldAPIToLabelMap[requiredFieldAPIList[i]];
                    }else{
                        blankRequiredFields =blankRequiredFields+',' + fieldAPIToLabelMap[requiredFieldAPIList[i]];
                    }
                }
            }
            return blankRequiredFields;
        }
        function saveAddressProcess(saveMode) {
            disableButtonStatus();
            redirectMode = saveMode;
            console.log('redirectMode'+redirectMode);
            hiddenErrorMsgNode();
            //1. Get Address Information from Form
            let addressJson = getAddressInformation();
            //2. Validate the Address field value formate, for example the email formate or phone formate
            let validationResultMessage = validateFieldValueFormate();
            console.log(validationResultMessage);
            if (validationResultMessage) {
                //Popup error message.  - To Do After POC
                alertErrorMessage(validationResultMessage);
                return
            }
            // Check Required Field
            let checkRequiredFieldMsgResult = checkRequiredFieldMsg(addressJson);
            if (checkRequiredFieldMsgResult) {
                alertErrorMessage('{!Input_Required_Field_Msg}'+checkRequiredFieldMsgResult);
                return
            }
            //3. Prepare the payload for New PI API To AWS - To Do
            let payloadForNewPI = getPIPayload(addressJson);
            //4. Address to AWS
            ProcessPI(addressJson, payloadForNewPI);
        }
        function alertErrorMessage(errorMsg) {
            enableButtonStatus();
            let errorMsgNode = document.getElementById("page:form:block:msgContent");
            errorMsg = '错误:无效数据。'+'\n' + errorMsg;
            errorMsgNode.innerText = errorMsg;
            errorMsgNode.className = 'pbError';
            unblockUI();
        }
        function hiddenErrorMsgNode() {
            let errorMsgNode = document.getElementById("page:form:block:msgContent");
            errorMsgNode.innerText = '';
            errorMsgNode.className = '';
        }
        var newSearchContactWindow = null;
        var contactHtmlString = '<img src="/img/s.gif" onclick="searchContact(\'page:form:contactId\')" alt="Reference Document Number Lookup" class="lookupIcon"  title="Reference Document Number Lookup (New Window)"/>';
        function htmlToElement(html) {
            var template = document.createElement('template');
            html = html.trim(); // Never return a text node of whitespace as the result
            template.innerHTML = html;
            return template.content.firstChild;
        }
        function searchContact(contactNodeId) {
            //1. Check account value
            let accountNodeId = document.querySelector("[data-id='Customer__c']").id + '_lkid';
            let accountValue = document.getElementById(accountNodeId).value;
            console.log(accountValue);
            if (accountValue != '000000000000000') {
                let baseUrl = "/apex/SearchContactPage";
                let suffixUrl = "?contactId=" + contactNodeId + "&accountId=" + accountValue;
                let newSearchContactParam = 'height=600,width=800,left=100,top=100,dialogHide=true,resizable=no,scrollbars=yes,toolbar=no,status=no';
                newSearchContactWindow = window.open(baseUrl + suffixUrl, 'Popup', newSearchContactParam);
                if (window.focus) {
                    newSearchContactWindow.focus();
                }
                return false;
            } else {
                //alertErrorMessage('{!PIPL_Input_Account_Error_Msg}');
                alertErrorMessage('请先选择客户');
            }
        }
        function closePopupWindow() {
            if (null != newSearchContactWindow) {
                newSearchContactWindow.close();
            }
            let contactInfoStr = document.getElementById('page:form:contactId').value;
            console.log('closePopup:'+contactInfoStr);
            let contactInfo = JSON.parse(contactInfoStr);
            let contactNodeId = document.querySelector("[data-id='Contacts__c']").id + '_lkid';
            document.getElementById(contactNodeId).value = contactInfo.ContactId;
            document.querySelector("[data-id='Contacts__c']").value = contactInfo.Name;
        }
        function replaceSearchContactLookup() {
            let lookUpNode = htmlToElement(contactHtmlString);
            console.log(lookUpNode);
            if (!{!isNewMode}) {
                //1. Query Contact from AWS by AWSDataId
                queryContactName()
                // document.querySelector("[data-id='Contacts__c']").value = '王奎';
            }
            let parentNode = document.querySelector("[data-id='Contacts__c']").parentNode;
            document.querySelector("[data-id='Contacts__c']").removeAttribute("onchange");
            parentNode.replaceChild(lookUpNode, document.querySelector("[data-id='Contacts__c']").parentNode.children[2]);
        }
        function queryContactName() {
            let sfId = document.getElementById(document.querySelector("[data-id='Contacts__c']").id + '_lkid').value;
            let contactsInfo = JSON.parse('{!contactsInfo}');
            let dataId = contactsInfo[sfId];
            let queryContactBack = function(data){
                //To Do later
                console.log('ContactData = ' + data.object);
                document.querySelector("[data-id='Contacts__c']").value = data.object.lastName;
            }
            AWSService.query(staticResourcesContact.queryUrl, dataId, queryContactBack, staticResources.token);
            // let url = staticResourcesContact.queryUrl + '?dataId=' + dataId;
            // fetch(url, {
            //     method: 'GET',
            //     headers: {
            //         'Content-Type': 'application/json',
            //         'pi-token': staticResources.token
            //     }
            // }).then((data) => {
            //     return data.json();
            // }).then((result) => {
            //     document.querySelector("[data-id='Contacts__c']").value = result.object.lastName;
            // })
        }
    </script>
    <div class="bPageTitle">
        <div class="ptBody">
            <div class="content">
                <img src="/img/s.gif" alt="收货地址" class="pageTitleIcon" title="收货地址" />
                <h1 class="pageType">收货地址编辑
                    <span class="titleSeparatingColon">:</span>
                </h1>
                <h2 class="pageDescription"> 新建收货地址</h2>
                <div class="blank">&nbsp;</div>
            </div>
            <div class="links">
                <a href="javascript:openPopupFocusEscapePounds(%27https://help.salesforce.com/apex/htdoor?loc=help&amp;target=address_edit.htm&amp;section=Address&amp;language=zh_CN&amp;release=234.18.14&amp;instance=CS58&amp;showSplash=true%27, %27Help%27, 700, 600, %27width=700,height=600,resizable=yes,toolbar=yes,status=no,scrollbars=yes,menubar=yes,directories=no,location=no,dependant=no%27, false, false);"
                    title="此页面的帮助 (新窗口)">
                    <span class="helpLink">此页面的帮助</span>
                    <img src="/img/s.gif" alt="" class="helpIcon" />
                </a>
            </div>
        </div>
        <div class="ptBreadcrumb"></div>
    </div>
    <apex:form id="form">
        <apex:inputHidden value="{!contactId}" id="contactId"/>
        <apex:pageblock id="block">
            <div class="pbHeader">
                <table cellspacing="0" cellpadding="0" border="0">
                    <tbody>
                        <tr>
                            <td class="pbTitle">
                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />
                                <h2 class="mainTitle">收货地址编辑</h2>
                            </td>
                            <td class="pbButton" id="topButtonRow">
                                <input class="btn" type="Button" value="保存" onclick="saveAddressProcess('Save')" />
                                <input class="btn" type="Button" value="保存并新建" onclick="saveAddressProcess('SaveAndNew')" />
                                <apex:commandButton action="{!cancel}" value="取消" />
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>
            <!-- Error Msg-->
            <div style="text-align: center;">
                <apex:outputPanel id="errorMsg">
                    <apex:pageMessages id="msgContent" escape="false" />
                </apex:outputPanel>
            </div>
            <br/>
            <!-- Iterate the layoutSections, which is a list of sections -->
            <apex:repeat value="{!layoutSections}" var="layoutSection">
                <apex:pageBlockSection title="{!layoutSection.name}" showHeader="{!layoutSection.useHeader}" collapsible="{!layoutSection.allowCollapse}"
                    columns="{!layoutSection.columns}">
                    <!--Each section has layoutFields, let's iterate them as well-->
                    <apex:repeat value="{!layoutSection.layoutFields}" var="layoutField">
                        <apex:inputField html-data-id="{!layoutField.fieldAPI}" value="{!Address__c[layoutField.fieldAPI]}" rendered="{!not(layoutField.isPlaceHOlder)}"
                            required="{!layoutField.isRequired}" />
                        <apex:pageblocksectionitem rendered="{!layoutField.isPlaceHolder}">
                        </apex:pageblocksectionitem>
                    </apex:repeat>
                </apex:pageBlockSection>
            </apex:repeat>
            <script>
                sfdcPage.appendToOnloadQueue(function () {
                    //1. Set Last Name label
                    //document.querySelector("[data-id='LastName']").parentNode.parentNode.parentNode.children[2].children[0].innerText = '姓名';
                    //2. Query AWS Data by dataId
                    console.log('Mode for Address Page:' + {!isNewMode});
                    if (!{!isNewMode}) {
                        blockme();//for loading search by Li Jun 20220218
                        QueryAddressFromAWS();
                    }
                    //Replace Vlookup Field
                    replaceSearchContactLookup();
                    //3. Set Readonly Attribute
                // document.querySelector("[data-id='OwnerId']").classList.add("disabledbutton");
                });
            </script>
            <div class="pbBottomButtons">
                <table cellspacing="0" cellpadding="0" border="0">
                    <tbody>
                        <tr>
                            <td class="pbTitle">
                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />&nbsp;</td>
                            <td class="pbButtonb" id="bottomButtonRow">
                                <input class="btn" type="Button" value="保存" onclick="saveAddressProcess('Save')" />
                                <input class="btn" type="Button" value="保存并新建" onclick="saveAddressProcess('SaveAndNew')" />
                                <apex:commandButton action="{!cancel}" value="取消" />
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>
        </apex:pageblock>
    </apex:form>
</apex:page>
force-app/main/default/pages/NewAndEditAddress.page-meta.xml
New file
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>53.0</apiVersion>
    <availableInTouch>false</availableInTouch>
    <confirmationTokenRequired>false</confirmationTokenRequired>
    <label>NewAndEditAddress</label>
</ApexPage>
force-app/main/default/pages/NewAndEditAgencyContact.page
New file
@@ -0,0 +1,511 @@
<apex:page standardController="Agency_Contact__c" extensions="NewAndEditAgencyContactController" id="page">
    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
    <script src="../../soap/ajax/53.0/connection.js" type="text/javascript"></script>
    <apex:stylesheet value="{!URLFOR($Resource.blockUIcss)}"/>
    <apex:includeScript value="{!URLFOR($Resource.jquery183minjs)}"/>
    <apex:includeScript value="{!URLFOR($Resource.PleaseWaitDialog)}"/>
    <script>
        var config = {};
        config = {
            SobjectName : "{!SobjectName}",
            ApiPrefix:"{!ApiPrefix}",
            SaveAndNew:false,
            AWSToSobjectMap:{!AWSToSobjectMapJson},
            AWSToSobjectNonEncryptedMap:{!AWSToSobjectNonEncryptedMapJson},
            AWSToSobjectEncryptedMap:{!AWSToSobjectEncryptedMapJson},
            SobjectToAWSModel:function (sobjJson) {
                let leadPayloadList = [];
                let leadPIData = {};
                for(let f in config.AWSToSobjectMap){
                    if(sobjJson.hasOwnProperty(config.AWSToSobjectMap[f])){
                        leadPIData[f] = sobjJson[config.AWSToSobjectMap[f]]
                    }
                    else{
                        console.log(config.AWSToSobjectMap[f] + 'is not in sobjJson');
                    }
                }
                leadPIData.sfRecordId = '';
                console.log('Sobject PI Data:' + leadPIData);
                leadPayloadList.push(leadPIData);
                console.log(JSON.stringify(leadPayloadList));
                return JSON.stringify(leadPayloadList);
            },
            insertOrUpdateBack:function(payloadJson, r, isNewMode){
                for(let f in config.AWSToSobjectMap){
                    if(r.object[0].hasOwnProperty(f)){
                        payloadJson[config.AWSToSobjectMap[f]] = r.object[0][f];
                    }
                    else{
                        console.log(f + 'is not in r.object[0]');
                    }
                }
                for(let f in config.AWSToSobjectEncryptedMap){
                    if(r.object[0].hasOwnProperty(f)){
                        payloadJson[config.AWSToSobjectEncryptedMap[f]] = r.object[0][f];
                    }
                    else{
                        console.log(f + 'is not in r.object[0]');
                    }
                }
                if('{!rtTypeId}'){
                    payloadJson.RecordTypeId = '{!rtTypeId}';
                }
                //payloadJson.AWS_Data_Id__c = r.object[0].dataId;
                payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
                if (isNewMode) {
                    payloadJson.AWS_Data_Id__c = r.object[0].dataId;
                } else {
                    payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
                }
                return payloadJson;
            },
            queryBack:function (data) {
                console.log('data = ' + data);
                if(data.object){
                    for(let f in config.AWSToSobjectNonEncryptedMap){
                        let ele = GetEleByClass(config.ApiPrefix + "_"+ config.AWSToSobjectNonEncryptedMap[f]);
                        if(data.object.hasOwnProperty(f) && ele){
                            // 多选特殊处理
                            if(ele.type == 'select-multiple'){
                               //let me = GetEleByClass(config.ApiPrefix+'_'+field_api_name);
                               if(ele && data.object[f]){
                                   let arr = data.object[f].split(';');
                                   // 给隐藏的select赋值
                                   for(let op of ele.options){
                                       op.selected = arr.indexOf(op.value)>-1;
                                   }
                                   // 利用按钮给显示的select赋值
                                   let ra = document.getElementById(ele.id + '_right_arrow');
                                   if(ra){
                                       ra.click();
                                   }
                               }
                            }else{
                                ele.value = data.object[f];
                            }
                        }
                        else{
                            console.log(f + 'is not in data.object');
                        }
                    }
                }
                else{
                    console.log('data.object = ' + data.object);
                }
                // document.querySelector("[data-id='LastName']").value = data.object.lastName;
                // document.querySelector("[data-id='Phone']").value = data.object.phone;
                // document.querySelector("[data-id='Email']").value = data.object.email;
            },
            updateMethod:"NewAndEditAgencyContactController.saveContact",
            insertMethod:"NewAndEditAgencyContactController.saveContact"
        }
        var staticResources = JSON.parse('{!staticResource}');
        var requiredFieldAPIList = JSON.parse('{!requiredFieldAPIListStr}');
        var fieldAPIToLabelMap = JSON.parse('{!fieldAPIToLabelMapStr}');
        console.log('{!staticResource}');
        var VLookUpFields = {! VLookUpFieldsJson};
        function ProcessPI(sobjJson, payloadForNewPI) {
            blockme();
            if ({!isNewMode}) {
                NewPIToAWS(sobjJson, payloadForNewPI)
            }else {
                UpdatePIToAWS(sobjJson, payloadForNewPI)
            }
        }
        var GetEleByClass = function(class_name){
            let eles = document.getElementsByClassName(class_name);
            if(eles.length > 0) return eles[0];
            return null;
        }
        var GetEleApiName = function(ele){
            for(let c of ele.classList){
                if(c.indexOf(config.ApiPrefix+'_')>-1){
                    return c.replace(config.ApiPrefix+'_','');
                }
            }
            return '';
        }
        function IsFormElement(tag_name){
            return ['input','select','textarea'].indexOf(tag_name)>-1;
        }
        function getPIPayload(sobjJson) {
            return config.SobjectToAWSModel(sobjJson);
        }
        function validateFieldValueFormate() {
            let error_msg = '';
            let textEmail = "[data-id='Email']";
            let textPhone = "[data-id='Phone']";
            //Email
            let email = document.querySelector(textEmail);
            if(email && !/^[\w-]{3,12}@[\da-zA-Z]{2,16}\.[a-zA-Z]+$/.test(email.value)){
                error_msg += ';邮件格式错误';
            }
            let phone = document.querySelector(textPhone);
            if(phone && !/^1[3|5|8|7][0-9]\d{4,8}$/.test(phone.value)){
                error_msg += ';电话号码错误';
            }
            for(let e of document.getElementsByTagName('select')){
                for(let op of e.options){
                    if(op.value == "*****" && op.selected){
                        error_msg += ';下拉框不能主动选择密文选项';
                    }
                }
            }
            if(error_msg.length>0 && error_msg[0]== ';'){
                error_msg = error_msg.substring(1);
            }
            return error_msg;
        }
        function getSobjectInformation() {
            let nodelist = document.getElementsByClassName(config.ApiPrefix);
            let result = {}
            for (let index = 0; index < nodelist.length; index++) {
                let ele = nodelist[index];
                let field_api_name = GetEleApiName(ele);
                let tag_name = ele.tagName.toLowerCase();
                if(!IsFormElement(tag_name)){
                    console.log('tag_name='+tag_name+',field_api_name'+field_api_name+' is not a form element');
                    continue;
                }
                if (VLookUpFields.indexOf(field_api_name)>=0) {
                    console.log(ele.id.indexOf('lkwgt'));
                    if (ele.id.indexOf('lkwgt') == -1) {
                        let vlookUpNodeId = ele.id + '_lkid';
                        let vlook_ele = document.getElementById(vlookUpNodeId);
                        let v = '';
                        if(vlook_ele){
                            v = vlook_ele.value;
                        }else{
                            v = ele.value;
                        }
                        if(v && v != "000000000000000"){
                            result[field_api_name] = v;
                        }
                    }
                } else if (ele.type == 'checkbox') {
                    result[field_api_name] = ele.checked;
                } else if (ele.type == 'select-multiple') {
                    //field_api_name
                    let multiple = field_api_name;
                    let targets = GetEleByClass(config.ApiPrefix+'_'+field_api_name).parentNode.children[1].children[0].children[1].children[2].children[0].innerText;
                    targets = targets.replace(/\n/g, ";");
                    console.log('targets = ' + targets);
                    result[field_api_name] = targets;
                } else {
                    result[field_api_name] = ele.value;
                }
            }
            return result;
        }
        function QuerySobjectFromAWS() {
            AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
        }
        function queryBack(data) {
            console.log('data = ' + data);
            config.queryBack(data);
            unblockUI();
        };
        function insertOrUpdateBack(payloadJson, result, isNewMode) {
            console.log(result);
            let r = result;
            console.log('Result from AWS' + r);
            console.log('payloadJson=' + payloadJson);
            return config.insertOrUpdateBack(payloadJson, r, isNewMode);
        }
        function redirectCallBack(sfId,errorMsg) {
            unblockUI();
            if(errorMsg){
                alertErrorMessage(errorMsg);
            }
            else{
                if(config.SaveAndNew){
                    window.open('{! SaveAndNewButtonUrl }','_self');
                }else{
                    window.open('/' + sfId, '_self');
                }
            }
        }
        function UpdatePIToAWS(sobjJson, payloadForNewPI) {
            let controllerSaveMethod = config.updateMethod;
            let obj = JSON.parse(payloadForNewPI);
            obj[0].dataId = '{!AWSDataId}';
            let payloadForNewPIJson = JSON.stringify(obj);
            AWSService.update(staticResources.updateUrl, sobjJson, payloadForNewPIJson, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, false, insertOrUpdateBack,redirectCallBack);
        }
        function NewPIToAWS(sobjJson, payloadForNewPI) {
            let controllerSaveMethod = config.insertMethod;
            AWSService.insert(staticResources.newUrl, sobjJson, payloadForNewPI, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, true, insertOrUpdateBack,redirectCallBack);
        }
        function checkRequiredFieldMsg(formData) {
            let blankRequiredFields = '';
            for(i = 0;i<requiredFieldAPIList.length;i++){
                if(formData[requiredFieldAPIList[i]]){
                    continue;
                }else{
                    if(blankRequiredFields == ''){
                        blankRequiredFields =blankRequiredFields + fieldAPIToLabelMap[requiredFieldAPIList[i]];
                    }else{
                        blankRequiredFields =blankRequiredFields+',' + fieldAPIToLabelMap[requiredFieldAPIList[i]];
                    }
                }
            }
            return blankRequiredFields;
        }
        function saveSobjectProcess(save_and_new) {
            if(save_and_new){
                config.SaveAndNew = true;
            }
            hiddenErrorMsgNode();
            //1. Get Sobject Information from Form
            let sobjJson = getSobjectInformation();
            //2. Validate the Sobject field value formate, for example the email formate or phone formate
            let validationResultMessage = validateFieldValueFormate();
            console.log(validationResultMessage);
            if (validationResultMessage) {
                //Popup error message.  - To Do After POC
                alertErrorMessage(validationResultMessage);
                return
            }
            // Check Required Field
            let checkRequiredFieldMsgResult = checkRequiredFieldMsg(sobjJson);
            if (checkRequiredFieldMsgResult) {
                alertErrorMessage('requiredErrorMsg' + checkRequiredFieldMsgResult);
                return
            }
            // //3. Prepare the payload for New PI API To AWS - To Do
            let payloadForNewPI = getPIPayload(sobjJson);
            // //4. Get Authentication Information for AWS
            // loadAWSAuthentication();
            // //5. lead to AWS
            ProcessPI(sobjJson, payloadForNewPI);
            // awsToken = TestToken;
            // NewPIToAWS(sobjJson,awsToken, payloadForNewPI)
        }
        function alertErrorMessage(errorMsg) {
            let errorMsgNode = document.getElementById("page:form:block:msgContent");
            errorMsgNode.innerText = errorMsg;
            errorMsgNode.className = 'pbError';
        }
        function hiddenErrorMsgNode() {
            let errorMsgNode = document.getElementById("page:form:block:msgContent");
            errorMsgNode.innerText = '';
            errorMsgNode.className = '';
        }
        var staticResourcesContact = JSON.parse('{!staticResourceContact}');
        var newSearchContactWindow = null;
        var contactHtmlString = '<img src="/img/s.gif" onclick="searchContact(\'page_form_contactId\')" alt="Reference Document Number Lookup" class="lookupIcon"  title="Reference Document Number Lookup (New Window)"/>';
        function htmlToElement(html) {
            var template = document.createElement('template');
            html = html.trim(); // Never return a text node of whitespace as the result
            template.innerHTML = html;
            return template.content.firstChild;
        }
        //自定义lookup查询
        function searchContact(contactNodeId){
            let accountValue = "";
            // if (document.querySelector("[data-id='Account__c']")) {
            //     let accountNodeId = document.querySelector("[data-id='Account__c']").id + '_lkid';
            //     accountValue = document.getElementById(accountNodeId).value;
            // }
            console.log(accountValue);
            if(true || accountValue !='000000000000000'){
                let baseUrl = "/apex/SearchContactPage";
                let suffixUrl = "?contactId="+contactNodeId+"&accountId="+accountValue;
                let newSearchContactParam = 'height=600,width=800,left=100,top=100,dialogHide=true,resizable=no,scrollbars=yes,toolbar=no,status=no';
                newSearchContactWindow = window.open(baseUrl+suffixUrl, 'Popup', newSearchContactParam);
                if (window.focus) {
                    newSearchContactWindow.focus();
                }
                return false;
            }else{
                alertErrorMessage('{!$Label.PIPL_Input_Account_Error_Msg}');
            }
        }
        //窗口关闭时发生
        function closePopupWindow() {
            if (null != newSearchContactWindow) {
                newSearchContactWindow.close();
            }
            let contactInfoStr = document.getElementById('page_form_contactId').value;
            console.log('closePopup:'+contactInfoStr);
            let contactInfo = JSON.parse(contactInfoStr);
            let contactNodeId = document.querySelector("[data-id='Contact__c']").id + '_lkid';
            document.getElementById(contactNodeId).value = contactInfo.ContactId;
            document.querySelector("[data-id='Contact__c']").value = contactInfo.Name;
        }
        //替换vlookup
        function replaceSearchContactLookup() {
            let lookUpNode = htmlToElement(contactHtmlString);
            console.log(lookUpNode);
            if (!{!isNewMode}) {
                //1. Query Contact from AWS by AWSDataId
                // document.querySelector("[data-id='ContactId']").value = '王奎';
                queryContactName()
            }
            let parentNode = document.querySelector("[data-id='Contact__c']").parentNode;
            document.querySelector("[data-id='Contact__c']").removeAttribute("onchange");
            parentNode.replaceChild(lookUpNode, document.querySelector("[data-id='Contact__c']").parentNode.children[2]);
        }
        function queryContactName() {
            let sfId = document.getElementById(document.querySelector("[data-id='Contact__c']").id + '_lkid').value;
            let contactsInfo = JSON.parse('{!LookUpOverrideFieldsMapJson}');
            let dataId = contactsInfo[sfId];
            let url = staticResourcesContact.queryUrl + '?dataId=' + dataId;
            fetch(url, {
                method: 'GET',
                headers: {
                    'Content-Type': 'application/json',
                    'pi-token': staticResources.token
                }
            }).then((data) => {
                return data.json();
            }).then((result) => {
                document.querySelector("[data-id='Contact__c']").value = result.object.lastName;
            })
        }
    </script>
    <div class="bPageTitle">
        <div class="ptBody">
            <div class="content">
                <img src="/img/s.gif" alt="{! SobjectLabel}" class="pageTitleIcon" title="{! SobjectLabel}" />
                <h1 class="pageType">{! SobjectLabel}<apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText>
                    <span class="titleSeparatingColon">:</span>
                </h1>
                <h2 class="pageDescription"> <apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText>{! SobjectLabel}</h2>
                <div class="blank">&nbsp;</div>
            </div>
            <div class="links">
                <a href="javascript:openPopupFocusEscapePounds(%27https://help.salesforce.com/apex/htdoor?loc=help&amp;target={!sobjectTypeValue}s_edit.htm&amp;section={!sobjectTypeValue}s&amp;language=zh_CN&amp;release=234.18.8&amp;instance=CS117&amp;showSplash=true%27, %27Help%27, 700, 600, %27width=700,height=600,resizable=yes,toolbar=yes,status=no,scrollbars=yes,menubar=yes,directories=no,location=no,dependant=no%27, false, false);"
                    title="此页面的帮助 (新窗口)">
                    <span class="helpLink">此页面的帮助</span>
                    <img src="/img/s.gif" alt="" class="helpIcon" />
                </a>
            </div>
        </div>
        <div class="ptBreadcrumb"></div>
    </div>
    <apex:form id="form">
        <input type="hidden"  id="page_form_contactId"/>
        <apex:pageblock id="block">
            <div class="pbHeader">
                <table cellspacing="0" cellpadding="0" border="0">
                    <tbody>
                        <tr>
                            <td class="pbTitle">
                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />
                                <h2 class="mainTitle">{! SobjectLabel}<apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText></h2>
                            </td>
                            <td class="pbButton" id="topButtonRow">
                                <input class="btn" type="Button" value="{!$Label.Save}" onclick="saveSobjectProcess()" />
                                <input class="btn" type="Button" value="{!$Label.SaveAndNew}" onclick="saveSobjectProcess(1)" />
                                <apex:commandButton action="{!cancel}" value="{!$Label.Cancel}" />
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>
            <!-- Error Msg-->
            <div style="text-align: center;">
                <apex:outputPanel id="errorMsg">
                    <apex:pageMessages id="msgContent" escape="false" />
                </apex:outputPanel>
            </div>
            <!-- Iterate the layoutSections, which is a list of sections -->
            <apex:repeat value="{!layoutSections}" var="layoutSection">
                <apex:pageBlockSection title="{!layoutSection.name}" collapsible="{!layoutSection.allowCollapse}" columns="{!layoutSection.columns}">
                    <!--Each section has layoutFields, let's iterate them as well-->
                    <apex:repeat value="{!layoutSection.layoutFields}" var="layoutField">
                        <apex:inputField styleClass="{!ApiPrefix} {!ApiPrefix}_{!layoutField.fieldAPI}" html-data-id="{!layoutField.fieldAPI}" value="{!Agency_Contact__c[layoutField.fieldAPI]}" rendered="{!not(layoutField.isPlaceHOlder)}"
                            required="{!layoutField.isRequired}" />
                        <apex:pageblocksectionitem rendered="{!layoutField.isPlaceHolder}">
                        </apex:pageblocksectionitem>
                    </apex:repeat>
                </apex:pageBlockSection>
            </apex:repeat>
            <script>
                sfdcPage.appendToOnloadQueue(function () {
                    //1. Set Last Name label
                    //document.querySelector("[data-id='LastName']").parentNode.parentNode.parentNode.children[2].children[0].innerText = '姓名';
                    //2. Query AWS Data by dataId
                    console.log('Mode for Sobject Page:' + {!isNewMode});
                    if (!{!isNewMode}) {
                        blockme();
                        QuerySobjectFromAWS();
                    }
                    //Replace Vlookup Field
                    replaceSearchContactLookup();
                });
            </script>
            <div class="pbBottomButtons">
                <table cellspacing="0" cellpadding="0" border="0">
                    <tbody>
                        <tr>
                            <td class="pbTitle">
                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />&nbsp;</td>
                            <td class="pbButtonb" id="bottomButtonRow">
                                <input class="btn" type="Button" value="{!$Label.Save}" onclick="saveSobjectProcess()" />
                                <input class="btn" type="Button" value="{!$Label.SaveAndNew}" onclick="saveSobjectProcess()" />
                                <apex:commandButton action="{!cancel}" value="{!$Label.Cancel}" />
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>
        </apex:pageblock>
    </apex:form>
</apex:page>
force-app/main/default/pages/NewAndEditAgencyContact.page-meta.xml
New file
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>53.0</apiVersion>
    <availableInTouch>false</availableInTouch>
    <confirmationTokenRequired>false</confirmationTokenRequired>
    <label>NewAndEditAgencyContact</label>
</ApexPage>
force-app/main/default/pages/NewAndEditCampaignMember.page
New file
@@ -0,0 +1,421 @@
<apex:page standardController="CampaignMember__c" extensions="NewAndEditCampaignMemberController" id="page">
    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
    <script src="../../soap/ajax/53.0/connection.js" type="text/javascript"></script>
    <apex:stylesheet value="{!URLFOR($Resource.blockUIcss)}"/>
    <apex:includeScript value="{!URLFOR($Resource.jquery183minjs)}"/>
    <apex:includeScript value="{!URLFOR($Resource.PleaseWaitDialog)}"/>
    <script>
        var config = {};
        config = {
            SobjectName : "{!SobjectName}",
            ApiPrefix:"{!ApiPrefix}",
            SaveAndNew:false,
            AWSToSobjectMap:{!AWSToSobjectMapJson},
            AWSToSobjectNonEncryptedMap:{!AWSToSobjectNonEncryptedMapJson},
            AWSToSobjectEncryptedMap:{!AWSToSobjectEncryptedMapJson},
            SobjectToAWSModel:function (sobjJson) {
                let leadPayloadList = [];
                let leadPIData = {};
                for(let f in config.AWSToSobjectMap){
                    if(sobjJson.hasOwnProperty(config.AWSToSobjectMap[f])){
                        leadPIData[f] = sobjJson[config.AWSToSobjectMap[f]]
                    }
                    else{
                        console.log(config.AWSToSobjectMap[f] + 'is not in sobjJson');
                    }
                }
                leadPIData.sfRecordId = '';
                console.log('Sobject PI Data:' + leadPIData);
                leadPayloadList.push(leadPIData);
                console.log(JSON.stringify(leadPayloadList));
                return JSON.stringify(leadPayloadList);
            },
            insertOrUpdateBack:function(payloadJson, r, isNewMode){
                for(let f in config.AWSToSobjectMap){
                    if(r.object[0].hasOwnProperty(f)){
                        payloadJson[config.AWSToSobjectMap[f]] = r.object[0][f];
                    }
                    else{
                        console.log(f + 'is not in r.object[0]');
                    }
                }
                for(let f in config.AWSToSobjectEncryptedMap){
                    if(r.object[0].hasOwnProperty(f)){
                        payloadJson[config.AWSToSobjectEncryptedMap[f]] = r.object[0][f];
                    }
                    else{
                        console.log(f + 'is not in r.object[0]');
                    }
                }
                //payloadJson.AWS_Data_Id__c = r.object[0].dataId;
                payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
                if (isNewMode) {
                    payloadJson.AWS_Data_Id__c = r.object[0].dataId;
                } else {
                    payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
                }
                return payloadJson;
            },
            queryBack:function (data) {
                console.log('data = ' + data);
                if(data.object){
                    for(let f in config.AWSToSobjectNonEncryptedMap){
                        let ele = GetEleByClass(config.ApiPrefix + "_"+ config.AWSToSobjectNonEncryptedMap[f]);
                        if(data.object.hasOwnProperty(f) && ele){
                            // 多选特殊处理
                            if(ele.type == 'select-multiple'){
                               //let me = GetEleByClass(config.ApiPrefix+'_'+field_api_name);
                               if(ele && data.object[f]){
                                   let arr = data.object[f].split(';');
                                   // 给隐藏的select赋值
                                   for(let op of ele.options){
                                       op.selected = arr.indexOf(op.value)>-1;
                                   }
                                   // 利用按钮给显示的select赋值
                                   let ra = document.getElementById(ele.id + '_right_arrow');
                                   if(ra){
                                       ra.click();
                                   }
                               }
                            }else{
                                ele.value = data.object[f];
                            }
                        }
                        else{
                            console.log(f + 'is not in data.object');
                        }
                    }
                }
                else{
                    console.log('data.object = ' + data.object);
                }
            },
            updateMethod:"NewAndEditCampaignMemberController.saveCampaignMember",
            insertMethod:"NewAndEditCampaignMemberController.saveCampaignMember"
        }
        var staticResources = JSON.parse('{!staticResource}');
        var requiredFieldAPIList = JSON.parse('{!requiredFieldAPIListStr}');
        var fieldAPIToLabelMap = JSON.parse('{!fieldAPIToLabelMapStr}');
        console.log('{!staticResource}');
        var VLookUpFields = {! VLookUpFieldsJson};
        function ProcessPI(sobjJson, payloadForNewPI) {
            blockme();
            if ({!isNewMode}) {
                NewPIToAWS(sobjJson, payloadForNewPI)
            }else {
                UpdatePIToAWS(sobjJson, payloadForNewPI)
            }
        }
        var GetEleByClass = function(class_name){
            let eles = document.getElementsByClassName(class_name);
            if(eles.length > 0) return eles[0];
            return null;
        }
        var GetEleApiName = function(ele){
            for(let c of ele.classList){
                if(c.indexOf(config.ApiPrefix+'_')>-1){
                    return c.replace(config.ApiPrefix+'_','');
                }
            }
            return '';
        }
        function IsFormElement(tag_name){
            return ['input','select','textarea'].indexOf(tag_name)>-1;
        }
        function getPIPayload(sobjJson) {
            return config.SobjectToAWSModel(sobjJson);
        }
        function validateFieldValueFormate() {
            let error_msg = '';
            let textEmail = "[data-id='Email']";
            let textPhone = "[data-id='Phone']";
            //Email
            let email = document.querySelector(textEmail);
            if(email && !/^[\w-]{3,12}@[\da-zA-Z]{2,16}\.[a-zA-Z]+$/.test(email.value)){
                error_msg += ';邮件格式错误';
            }
            let phone = document.querySelector(textPhone);
            if(phone && !/^1[3|5|8|7][0-9]\d{4,8}$/.test(phone.value)){
                error_msg += ';电话号码错误';
            }
            for(let e of document.getElementsByTagName('select')){
                for(let op of e.options){
                    if(op.value == "*****" && op.selected){
                        error_msg += ';下拉框不能主动选择密文选项';
                    }
                }
            }
            if(error_msg.length>0 && error_msg[0]== ';'){
                error_msg = error_msg.substring(1);
            }
            return error_msg;
        }
        function getSobjectInformation() {
            let nodelist = document.getElementsByClassName(config.ApiPrefix);
            let result = {}
            for (let index = 0; index < nodelist.length; index++) {
                let ele = nodelist[index];
                let field_api_name = GetEleApiName(ele);
                let tag_name = ele.tagName.toLowerCase();
                if(!IsFormElement(tag_name)){
                    console.log('tag_name='+tag_name+',field_api_name'+field_api_name+' is not a form element');
                    continue;
                }
                if (VLookUpFields.indexOf(field_api_name)>=0) {
                    console.log(ele.id.indexOf('lkwgt'));
                    if (ele.id.indexOf('lkwgt') == -1) {
                        let vlookUpNodeId = ele.id + '_lkid';
                        let vlook_ele = document.getElementById(vlookUpNodeId);
                        let v = '';
                        if(vlook_ele){
                            v = vlook_ele.value;
                        }else{
                            v = ele.value;
                        }
                        if(v && v != "000000000000000"){
                            result[field_api_name] = v;
                        }
                    }
                } else if (ele.type == 'checkbox') {
                    result[field_api_name] = ele.checked;
                } else if (ele.type == 'select-multiple') {
                    //field_api_name
                    let multiple = field_api_name;
                    let targets = GetEleByClass(config.ApiPrefix+'_'+field_api_name).parentNode.children[1].children[0].children[1].children[2].children[0].innerText;
                    targets = targets.replace(/\n/g, ";");
                    console.log('targets = ' + targets);
                    result[field_api_name] = targets;
                } else {
                    result[field_api_name] = ele.value;
                }
            }
            return result;
        }
        function QuerySobjectFromAWS() {
            AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
        }
        function queryBack(data) {
            console.log('data = ' + data);
            config.queryBack(data);
        };
        function insertOrUpdateBack(payloadJson, result, isNewMode) {
            console.log(result);
            let r = result;
            console.log('Result from AWS' + r);
            console.log('payloadJson=' + payloadJson);
            return config.insertOrUpdateBack(payloadJson, r, isNewMode);
        }
        function redirectCallBack(sfId,errorMsg) {
            unblockUI();
            if(errorMsg){
                alertErrorMessage(errorMsg);
            }
            else{
                if(config.SaveAndNew){
                    window.open('{! SaveAndNewButtonUrl }','_self');
                }else{
                    window.open('/' + sfId, '_self');
                }
            }
        }
        function UpdatePIToAWS(sobjJson, payloadForNewPI) {
            let controllerSaveMethod = config.updateMethod;
            let obj = JSON.parse(payloadForNewPI);
            obj[0].dataId = '{!AWSDataId}';
            let payloadForNewPIJson = JSON.stringify(obj);
            AWSService.update(staticResources.updateUrl, sobjJson, payloadForNewPIJson, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, false, insertOrUpdateBack,redirectCallBack);
        }
        function NewPIToAWS(sobjJson, payloadForNewPI) {
            let controllerSaveMethod = config.insertMethod;
            AWSService.insert(staticResources.newUrl, sobjJson, payloadForNewPI, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, true, insertOrUpdateBack,redirectCallBack);
        }
        function checkRequiredFieldMsg(formData) {
            let blankRequiredFields = '';
            for(i = 0;i<requiredFieldAPIList.length;i++){
                if(formData[requiredFieldAPIList[i]]){
                    continue;
                }else{
                    if(blankRequiredFields == ''){
                        blankRequiredFields =blankRequiredFields + fieldAPIToLabelMap[requiredFieldAPIList[i]];
                    }else{
                        blankRequiredFields =blankRequiredFields+',' + fieldAPIToLabelMap[requiredFieldAPIList[i]];
                    }
                }
            }
            return blankRequiredFields;
        }
        function saveSobjectProcess(save_and_new) {
            if(save_and_new){
                config.SaveAndNew = true;
            }
            hiddenErrorMsgNode();
            //1. Get Sobject Information from Form
            let sobjJson = getSobjectInformation();
            //2. Validate the Sobject field value formate, for example the email formate or phone formate
            let validationResultMessage = validateFieldValueFormate();
            console.log(validationResultMessage);
            if (validationResultMessage) {
                //Popup error message.  - To Do After POC
                alertErrorMessage(validationResultMessage);
                return
            }
            // Check Required Field
            let checkRequiredFieldMsgResult = checkRequiredFieldMsg(sobjJson);
            if (checkRequiredFieldMsgResult) {
                alertErrorMessage('requiredErrorMsg' + checkRequiredFieldMsgResult);
                return
            }
            // //3. Prepare the payload for New PI API To AWS - To Do
            let payloadForNewPI = getPIPayload(sobjJson);
            // //4. Get Authentication Information for AWS
            // loadAWSAuthentication();
            // //5. lead to AWS
            ProcessPI(sobjJson, payloadForNewPI);
            // awsToken = TestToken;
            // NewPIToAWS(sobjJson,awsToken, payloadForNewPI)
        }
        function alertErrorMessage(errorMsg) {
            let errorMsgNode = document.getElementById("page:form:block:msgContent");
            errorMsgNode.innerText = errorMsg;
            errorMsgNode.className = 'pbError';
        }
        function hiddenErrorMsgNode() {
            let errorMsgNode = document.getElementById("page:form:block:msgContent");
            errorMsgNode.innerText = '';
            errorMsgNode.className = '';
        }
    </script>
    <div class="bPageTitle">
        <div class="ptBody">
            <div class="content">
                <img src="/img/s.gif" alt="{! SobjectLabel}" class="pageTitleIcon" title="{! SobjectLabel}" />
                <h1 class="pageType">{! SobjectLabel}<apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText>
                    <span class="titleSeparatingColon">:</span>
                </h1>
                <h2 class="pageDescription"> <apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText>{! SobjectLabel}</h2>
                <div class="blank">&nbsp;</div>
            </div>
            <div class="links">
                <a href="javascript:openPopupFocusEscapePounds(%27https://help.salesforce.com/apex/htdoor?loc=help&amp;target={!sobjectTypeValue}s_edit.htm&amp;section={!sobjectTypeValue}s&amp;language=zh_CN&amp;release=234.18.8&amp;instance=CS117&amp;showSplash=true%27, %27Help%27, 700, 600, %27width=700,height=600,resizable=yes,toolbar=yes,status=no,scrollbars=yes,menubar=yes,directories=no,location=no,dependant=no%27, false, false);"
                    title="此页面的帮助 (新窗口)">
                    <span class="helpLink">此页面的帮助</span>
                    <img src="/img/s.gif" alt="" class="helpIcon" />
                </a>
            </div>
        </div>
        <div class="ptBreadcrumb"></div>
    </div>
    <apex:form id="form">
        <apex:pageblock id="block">
            <div class="pbHeader">
                <table cellspacing="0" cellpadding="0" border="0">
                    <tbody>
                        <tr>
                            <td class="pbTitle">
                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />
                                <h2 class="mainTitle">{! SobjectLabel}<apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText></h2>
                            </td>
                            <td class="pbButton" id="topButtonRow">
                                <input class="btn" type="Button" value="{!$Label.Save}" onclick="saveSobjectProcess()" />
                                <input class="btn" type="Button" value="{!$Label.SaveAndNew}" onclick="saveSobjectProcess(1)" />
                                <apex:commandButton action="{!cancel}" value="{!$Label.Cancel}" />
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>
            <!-- Error Msg-->
            <div style="text-align: center;">
                <apex:outputPanel id="errorMsg">
                    <apex:pageMessages id="msgContent" escape="false" />
                </apex:outputPanel>
            </div>
            <!-- Iterate the layoutSections, which is a list of sections -->
            <apex:repeat value="{!layoutSections}" var="layoutSection">
                <apex:pageBlockSection title="{!layoutSection.name}" collapsible="{!layoutSection.allowCollapse}" columns="{!layoutSection.columns}">
                    <!--Each section has layoutFields, let's iterate them as well-->
                    <apex:repeat value="{!layoutSection.layoutFields}" var="layoutField">
                        <apex:inputField styleClass="{!ApiPrefix} {!ApiPrefix}_{!layoutField.fieldAPI}" html-data-id="{!layoutField.fieldAPI}" value="{!CampaignMember__c[layoutField.fieldAPI]}" rendered="{!not(layoutField.isPlaceHOlder)}"
                            required="{!layoutField.isRequired}" />
                        <apex:pageblocksectionitem rendered="{!layoutField.isPlaceHolder}">
                        </apex:pageblocksectionitem>
                    </apex:repeat>
                </apex:pageBlockSection>
            </apex:repeat>
            <script>
                sfdcPage.appendToOnloadQueue(function () {
                    //1. Set Last Name label
                    //document.querySelector("[data-id='LastName']").parentNode.parentNode.parentNode.children[2].children[0].innerText = '姓名';
                    //2. Query AWS Data by dataId
                    console.log('Mode for Sobject Page:' + {!isNewMode});
                    if (!{!isNewMode}) {
                        QuerySobjectFromAWS();
                    }
                });
            </script>
            <div class="pbBottomButtons">
                <table cellspacing="0" cellpadding="0" border="0">
                    <tbody>
                        <tr>
                            <td class="pbTitle">
                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />&nbsp;</td>
                            <td class="pbButtonb" id="bottomButtonRow">
                                <input class="btn" type="Button" value="{!$Label.Save}" onclick="saveSobjectProcess()" />
                                <input class="btn" type="Button" value="{!$Label.SaveAndNew}" onclick="saveSobjectProcess()" />
                                <apex:commandButton action="{!cancel}" value="{!$Label.Cancel}" />
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>
        </apex:pageblock>
    </apex:form>
</apex:page>
force-app/main/default/pages/NewAndEditCampaignMember.page-meta.xml
New file
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>52.0</apiVersion>
    <availableInTouch>false</availableInTouch>
    <confirmationTokenRequired>false</confirmationTokenRequired>
    <label>NewAndEditCampaignMember</label>
</ApexPage>
force-app/main/default/pages/NewAndEditCase.page
New file
@@ -0,0 +1,442 @@
<apex:page standardController="Case" extensions="NewAndEditCaseController" id="page">
    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
    <apex:includeScript value="{!URLFOR($Resource.jquery183minjs)}"/>
    <apex:includeScript value="{!URLFOR($Resource.PleaseWaitDialog)}"/>
    <script src="../../soap/ajax/53.0/connection.js" type="text/javascript"></script>
    <style>
        .disabledbutton {
            pointer-events: none;
            opacity: 0.4;
        }
    </style>
    <script>
        AWSService.sfSessionId = '{!GETSESSIONID()}';
        var staticResources = JSON.parse('{!staticResource}');
        var staticResourcesContact = JSON.parse('{!staticResourceContact}');
        var requiredFieldAPIList = JSON.parse('{!requiredFieldAPIListStr}');
        var fieldAPIToLabelMap = JSON.parse('{!fieldAPIToLabelMapStr}');
        var redirectMode = "Save";
        var requiredAPIToChangedLabelMap = new Map();
        requiredAPIToChangedLabelMap.set('LastName', '{!PIPL_Name_Label}');
        console.log('{!contactsInfo}');
        var VLookUpFields = new Set(['Account__c', 'ContactId', 'Asset__c', 'prod__c', 'Competitor_info__c', 'AccountId', 'Field1_staff__c']);
        //判断insert or update
        function ProcessPI(caseJson, payloadForNewPI) {
            blockme();
            if ({!isNewMode}) {
                NewPIToAWS(caseJson, payloadForNewPI)
            }else {
                UpdatePIToAWS(caseJson, payloadForNewPI)
            }
        }
        //防止按钮重复点击
        function enableButton(obj){
            obj.classList.remove("btnDisabled");
        }
        function disableButton(obj){
            obj.classList.add("btnDisabled");
        }
        function disableButtonStatus(){
            let btnList = document.getElementsByClassName('btn');
            for(let i=0;i<btnList.length;i++){
                disableButton(btnList[i]);
            }
        }
        function enableButtonStatus(){
            let btnList = document.getElementsByClassName('btn');
            for(let i=0;i<btnList.length;i++){
                enableButton(btnList[i]);
            }
        }
        //获取加密字段
        function getPIPayload(caseJson) {
            let casePayloadList = [];
            let CicTelephone = caseJson.cic_telephone__c;
            let CaseCustomer = caseJson.CASE_CUSTOMER__c;
            let CustomerManual = caseJson.Customer_manual__c;
            let casePIData = new Object();
            casePIData.cicTelephone = CicTelephone;
            casePIData.caseCustomer = CaseCustomer;
            casePIData.customerManual = CustomerManual;
            casePIData.sfRecordId = '';
            console.log('Case PI Data:' + casePIData);
            casePayloadList.push(casePIData);
            console.log(JSON.stringify(casePayloadList));
            return JSON.stringify(casePayloadList);
        }
        //判断数据格式
        function validateFieldValueFormate() {
            //let textEmail = "[data-id='Email']";
            let textPhone = "[data-id='cic_telephone__c']";
            if (!document.querySelector("[data-id='Account__c']")) {
                return true;
            }
            //Email
            //let email = document.querySelector(textEmail).value;
            let phone = document.querySelector(textPhone).value;
            if (phone == "") {
                return true;
            }
            //let regEmail = /^[\w-]{3,12}@[\da-zA-Z]{2,6}\.[a-zA-Z]+$/;
            let regPhone = /^1[3|5|8|7][0-9]\d{4,8}$/;
            //let emailFormate = regEmail.test(email);
            let phoneFormate = regPhone.test(phone);
            //console.log(emailFormate);
            console.log(phoneFormate);
            //if (emailFormate == true && phoneFormate == true) {
            if (phoneFormate == true) {
                return true;
            } else {
                return false;
            }
        }
        //获取表单数据
        function getCaseInformation() {
            let nodelist = document.querySelectorAll("[data-id]");
            let result = {}
            result.RecordTypeId = '{!rtTypeId}'
            for (let index = 0; index < nodelist.length; index++) {
                if (VLookUpFields.has(nodelist[index].getAttribute("data-id"))) {
                    console.log(nodelist[index].id.indexOf('lkwgt'));
                    if (nodelist[index].id.indexOf('lkwgt') == -1) {
                        let vlookUpNodeId = nodelist[index].id + '_lkid';
                        let vlookUpNodeValue = document.getElementById(vlookUpNodeId).value;
                        result[nodelist[index].getAttribute("data-id")] = vlookUpNodeValue;
                    }
                } else if (nodelist[index].type == 'checkbox') {
                    result[nodelist[index].getAttribute("data-id")] = nodelist[index].checked;
                } else if (nodelist[index].type == 'select-multiple') {
                    //nodelist[index].getAttribute("data-id")
                    let multiple = nodelist[index].getAttribute("data-id");
                    let targets = document.querySelector("[data-id=" + multiple + "]").parentNode.children[1].children[0].children[1].children[2].children[0].innerText;
                    targets = targets.replace(/\n/g, ";");
                    console.log('targets = ' + targets);
                    result[nodelist[index].getAttribute("data-id")] = targets;
                } else {
                    result[nodelist[index].getAttribute("data-id")] = nodelist[index].value;
                }
                let x = index + 1;
                if (x <= nodelist.length-1 && (nodelist[x].getAttribute("data-id") == nodelist[index].getAttribute("data-id"))) {
                    index++;
                }
            }
            //针对id的手动添加
            if (document.getElementById("page:form:block:j_id31:0:j_id32:j_id33:1:j_id34_lkid") && (!result.hasOwnProperty("Field1_staff__c") || !result["Field1_staff__c"])){
                if(document.getElementById("page:form:block:j_id31:0:j_id32:j_id33:1:j_id34_lkid").value != '000000000000000'){
                    result["Field1_staff__c"] = document.getElementById("page:form:block:j_id31:0:j_id32:j_id33:1:j_id34_lkid").value;
                }
            }
            return result;
        }
        //查询
        function QueryCaseFromAWS() {
            AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
        }
        //需要解密字段
        var queryBack = function queryBack(data) {
            console.log('data = ' + data);
            document.querySelector("[data-id='cic_telephone__c']").value = data.object.cicTelephone;
            document.querySelector("[data-id='CASE_CUSTOMER__c']").value = data.object.caseCustomer;
            document.querySelector("[data-id='Customer_manual__c']").value = data.object.customerManual;
        };
        var insertOrUpdateBack = function insertOrUpdateBack(payloadJson, result, isNewMode) {
            console.log(result);
            let r = result;
            console.log('Result from AWS' + r);
            console.log('payloadJson=' + payloadJson);
            payloadJson.cic_telephone__c = r.object[0].cicTelephone;
            payloadJson.CASE_CUSTOMER__c = r.object[0].caseCustomer;
            payloadJson.Customer_manual__c = r.object[0].customerManual;
            payloadJson.cic_telephone_Encrypted__c = r.object[0].cicTelephoneEncrypt;
            payloadJson.CASE_CUSTOMER_Encrypted__c = r.object[0].caseCustomerEncrypt;
            payloadJson.Customer_manual_Encrypted__c = r.object[0].customerManualEncrypt;
            //payloadJson.AWS_Data_Id__c = r.object[0].dataId;
            payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
            if (isNewMode) {
                payloadJson.AWS_Data_Id__c = r.object[0].dataId;
            } else {
                payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
            }
            return payloadJson;
        }
        //回调函数,点击后事件
        var redirectCallBack = function redirectCallBack(sfId,errorMessage) {
            if(sfId){
                if(redirectMode == 'Save'){
                    window.open('/' + sfId, '_self');
                }else if(redirectMode == 'SaveAndNew'){
                    window.open('/setup/ui/recordtypeselect.jsp?ent='+'{!sobjecttypeForFrontEnd}'+'&retURL=/'+'{!sobjectPrefix}'+'/o&save_new_url=/'+'{!sobjectPrefix}'+'/e?retURL=%2F'+'{!sobjectPrefix}'+'%2Fo','_self');
                }else if(redirectMode == 'SaveAndClose'){
                    window.open('/' + sfId + '/s?retURL=%2F' + sfId + '&co=1', '_self');
                }
            }else{
                alertErrorMessage(errorMessage);
            }
        }
        //update to AWS
        function UpdatePIToAWS(caseJson, payloadForNewPI) {
            let controllerSaveMethod = '{!$RemoteAction.NewAndEditCaseController.saveCase}';
            let obj = JSON.parse(payloadForNewPI);
            obj[0].dataId = '{!AWSDataId}';
            let payloadForNewPIJson = JSON.stringify(obj);
            AWSService.update(staticResources.updateUrl, caseJson, payloadForNewPIJson, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, false, insertOrUpdateBack, redirectCallBack);
        }
        //insert to AWS
        function NewPIToAWS(caseJson, payloadForNewPI) {
            let controllerSaveMethod = '{!$RemoteAction.NewAndEditCaseController.saveCase}';
            AWSService.insert(staticResources.newUrl, caseJson, payloadForNewPI, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, true, insertOrUpdateBack, redirectCallBack);
        }
        //必填字段
        function checkRequiredFieldMsg(formData) {
            let blankRequiredFields = '';
            for (i = 0; i < requiredFieldAPIList.length; i++) {
                if (formData[requiredFieldAPIList[i]]) {
                    continue;
                } else {
                    let fieldAPIValue = requiredFieldAPIList[i]
                    let fieldLabelValue = fieldAPIToLabelMap[fieldAPIValue];
                    if (requiredAPIToChangedLabelMap.has(fieldAPIValue)) {
                        fieldLabelValue = requiredAPIToChangedLabelMap.get(fieldAPIValue);
                    }
                    if (blankRequiredFields == '') {
                        blankRequiredFields = blankRequiredFields + fieldLabelValue;
                    } else {
                        blankRequiredFields = blankRequiredFields + ',' + fieldLabelValue;
                    }
                }
            }
            return blankRequiredFields;
        }
        //按钮点击事件
        function saveCaseProcess(saveMode) {
            disableButtonStatus();
            redirectMode = saveMode;
            console.log('redirectMode'+redirectMode);
            hiddenErrorMsgNode();
            //1. Get Case Information from Form
            let caseJson = getCaseInformation();
            //2. Validate the Case field value formate, for example the email formate or phone formate
            let validationResultMessage = validateFieldValueFormate();
            console.log(validationResultMessage);
            if (!validationResultMessage) {
                //Popup error message.  - To Do After POC
                //alertErrorMessage('邮箱格式输入有误,请重新输入!');
                alertErrorMessage('手机格式输入有误,请重新输入!');
                return
            }
            // Check Required Field
            let checkRequiredFieldMsgResult = checkRequiredFieldMsg(caseJson);
            if (checkRequiredFieldMsgResult) {
                alertErrorMessage('{!Input_Required_Field_Msg}'+checkRequiredFieldMsgResult);
                return
            }
            //3. Prepare the payload for New PI API To AWS - To Do
            let payloadForNewPI = getPIPayload(caseJson);
            //4. Case to AWS
            ProcessPI(caseJson, payloadForNewPI);
        }
        //error 报错
        function alertErrorMessage(errorMsg) {
            enableButtonStatus();
            let errorMsgNode = document.getElementById("page:form:block:msgContent");
            errorMsg = '错误:无效数据。'+'\n' + errorMsg;
            errorMsgNode.innerText = errorMsg;
            errorMsgNode.className = 'pbError';
            unblockUI();
        }
        function hiddenErrorMsgNode() {
            let errorMsgNode = document.getElementById("page:form:block:msgContent");
            errorMsgNode.innerText = '';
            errorMsgNode.className = '';
        }
        var newSearchContactWindow = null;
        var contactHtmlString = '<img src="/img/s.gif" onclick="searchContact(\'page:form:contactId\')" alt="Reference Document Number Lookup" class="lookupIcon"  title="Reference Document Number Lookup (New Window)"/>';
        function htmlToElement(html) {
            var template = document.createElement('template');
            html = html.trim(); // Never return a text node of whitespace as the result
            template.innerHTML = html;
            return template.content.firstChild;
        }
        //自定义lookup查询
        function searchContact(contactNodeId){
            let accountValue = "";
            if (document.querySelector("[data-id='Account__c']")) {
                let accountNodeId = document.querySelector("[data-id='Account__c']").id + '_lkid';
                accountValue = document.getElementById(accountNodeId).value;
            }
            console.log(accountValue);
            if(accountValue !='000000000000000'){
                let baseUrl = "/apex/SearchContactPage";
                let suffixUrl = "?contactId="+contactNodeId+"&accountId="+accountValue;
                let newSearchContactParam = 'height=600,width=800,left=100,top=100,dialogHide=true,resizable=no,scrollbars=yes,toolbar=no,status=no';
                newSearchContactWindow = window.open(baseUrl+suffixUrl, 'Popup', newSearchContactParam);
                if (window.focus) {
                    newSearchContactWindow.focus();
                }
                return false;
            }else{
                alertErrorMessage('{!PIPL_Input_Account_Error_Msg}');
            }
        }
        //窗口关闭时发生
        function closePopupWindow() {
            if (null != newSearchContactWindow) {
                newSearchContactWindow.close();
            }
            let contactInfoStr = document.getElementById('page:form:contactId').value;
            console.log('closePopup:'+contactInfoStr);
            let contactInfo = JSON.parse(contactInfoStr);
            let contactNodeId = document.querySelector("[data-id='ContactId']").id + '_lkid';
            document.getElementById(contactNodeId).value = contactInfo.ContactId;
            document.querySelector("[data-id='ContactId']").value = contactInfo.Name;
        }
        //替换vlookup
        function replaceSearchContactLookup() {
            let lookUpNode = htmlToElement(contactHtmlString);
            console.log(lookUpNode);
            if (!{!isNewMode}) {
                //1. Query Contact from AWS by AWSDataId
                // document.querySelector("[data-id='ContactId']").value = '王奎';
                queryContactName()
            }
            let parentNode = document.querySelector("[data-id='ContactId']").parentNode;
            document.querySelector("[data-id='ContactId']").removeAttribute("onchange");
            parentNode.replaceChild(lookUpNode, document.querySelector("[data-id='ContactId']").parentNode.children[2]);
        }
        function queryContactName() {
            let sfId = document.getElementById(document.querySelector("[data-id='ContactId']").id + '_lkid').value;
            let contactsInfo = JSON.parse('{!contactsInfo}');
            let dataId = contactsInfo[sfId];
            // let queryContactBack = function(data){
            //     //To Do later
            //     console.log('ContactData = ' + data.object);
            //     document.querySelector("[data-id='ContactId']").value = data.object.lastName;
            // }
            // AWSService.query(staticResourcesContact.queryUrl, dataId, queryContactBack, staticResources.token);
            let url = staticResourcesContact.queryUrl + '?dataId=' + dataId;
            fetch(url, {
                method: 'GET',
                headers: {
                    'Content-Type': 'application/json',
                    'pi-token': staticResources.token
                }
            }).then((data) => {
                return data.json();
            }).then((result) => {
                document.querySelector("[data-id='ContactId']").value = result.object.lastName;
            })
        }
    </script>
    <div class="bPageTitle">
        <div class="ptBody">
            <div class="content">
                <img src="/img/s.gif" alt="CIC" class="pageTitleIcon" title="CIC" />
                <h1 class="pageType">CIC编辑
                    <span class="titleSeparatingColon">:</span>
                </h1>
                <h2 class="pageDescription"> 新建CIC</h2>
                <div class="blank">&nbsp;</div>
            </div>
            <div class="links">
                <a href="javascript:openPopupFocusEscapePounds(%27https://help.salesforce.com/apex/htdoor?loc=help&amp;target=cases_edit.htm&amp;section=Cases&amp;language=zh_CN&amp;release=234.18.14&amp;instance=CS58&amp;showSplash=true%27, %27Help%27, 700, 600, %27width=700,height=600,resizable=yes,toolbar=yes,status=no,scrollbars=yes,menubar=yes,directories=no,location=no,dependant=no%27, false, false);"
                    title="此页面的帮助 (新窗口)">
                    <span class="helpLink">此页面的帮助</span>
                    <img src="/img/s.gif" alt="" class="helpIcon" />
                </a>
            </div>
        </div>
        <div class="ptBreadcrumb"></div>
    </div>
    <apex:form id="form">
        <apex:inputHidden value="{!contactId}" id="contactId"/>
        <apex:pageblock id="block">
            <div class="pbHeader">
                <table cellspacing="0" cellpadding="0" border="0">
                    <tbody>
                        <tr>
                            <td class="pbTitle">
                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />
                                <h2 class="mainTitle">CIC编辑</h2>
                            </td>
                            <td class="pbButton" id="topButtonRow">
                                <input class="btn" type="Button" value="保存" onclick="saveCaseProcess('Save')" />
                                <input class="btn" type="Button" value="保存并关闭" onclick="saveCaseProcess('SaveAndClose')" />
                                <input class="btn" type="Button" value="保存并新建" onclick="saveCaseProcess('SaveAndNew')" />
                                <apex:commandButton action="{!cancel}" value="取消" />
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>
            <!-- Error Msg-->
            <div style="text-align: center;">
                <apex:outputPanel id="errorMsg">
                    <apex:pageMessages id="msgContent" escape="false" />
                </apex:outputPanel>
            </div>
            <br/>
            <!-- Iterate the layoutSections, which is a list of sections -->
            <apex:repeat value="{!layoutSections}" var="layoutSection">
                <apex:pageBlockSection title="{!layoutSection.name}" showHeader="{!layoutSection.useHeader}" collapsible="{!layoutSection.allowCollapse}" columns="{!layoutSection.columns}">
                    <!--Each section has layoutFields, let's iterate them as well-->
                    <apex:repeat value="{!layoutSection.layoutFields}" var="layoutField">
                        <apex:inputField html-data-id="{!layoutField.fieldAPI}" value="{!Case[layoutField.fieldAPI]}" rendered="{!not(layoutField.isPlaceHOlder)}"
                            required="{!layoutField.isRequired}" />
                        <apex:pageblocksectionitem rendered="{!layoutField.isPlaceHolder}">
                        </apex:pageblocksectionitem>
                    </apex:repeat>
                </apex:pageBlockSection>
            </apex:repeat>
            <script>
                sfdcPage.appendToOnloadQueue(function () {
                    //1. Set Last Name label
                    //document.querySelector("[data-id='LastName']").parentNode.parentNode.parentNode.children[2].children[0].innerText = '姓名';
                    //2. Query AWS Data by dataId
                    console.log('Mode for Case Page:' + {!isNewMode});
                    if (!{!isNewMode}) {
                        blockme();
                        QueryCaseFromAWS();
                        unblockUI();
                    }
                    //Replace Vlookup Field
                    replaceSearchContactLookup();
                    //3. Set Readonly Attribute
                    document.querySelector("[data-id='OwnerId']").classList.add("disabledbutton");
                    document.querySelector("[data-id='RecordTypeId']").classList.add("disabledbutton");
                    //需要隐藏
                    // document.querySelector("[data-id='SuppliedEmail']").classList.add("displayblock");
                });
            </script>
            <div class="pbBottomButtons">
                <table cellspacing="0" cellpadding="0" border="0">
                    <tbody>
                        <tr>
                            <td class="pbTitle">
                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />&nbsp;</td>
                            <td class="pbButton" id="bottomButtonRow">
                                <input class="btn" type="Button" value="保存" onclick="saveCaseProcess('Save')" />
                                <input class="btn" type="Button" value="保存并关闭" onclick="saveCaseProcess('SaveAndClose')" />
                                <input class="btn" type="Button" value="保存并新建" onclick="saveCaseProcess('SaveAndNew')" />
                                <apex:commandButton action="{!cancel}" value="取消" />
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>
        </apex:pageblock>
    </apex:form>
</apex:page>
force-app/main/default/pages/NewAndEditCase.page-meta.xml
New file
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>52.0</apiVersion>
    <availableInTouch>false</availableInTouch>
    <confirmationTokenRequired>false</confirmationTokenRequired>
    <label>NewAndEditCase</label>
</ApexPage>
force-app/main/default/pages/NewAndEditContact.page
New file
@@ -0,0 +1,485 @@
<apex:page standardController="Contact" extensions="NewAndEditContactController" id="page">
    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
    <script src="../../soap/ajax/53.0/connection.js" type="text/javascript"></script>
    <apex:stylesheet value="{!URLFOR($Resource.blockUIcss)}"/>
    <apex:includeScript value="{!URLFOR($Resource.jquery183minjs)}"/>
    <apex:includeScript value="{!URLFOR($Resource.PleaseWaitDialog)}"/>
    <script>
        var config = {};
        config = {
            SobjectName : "{!SobjectName}",
            ApiPrefix:"{!ApiPrefix}",
            SaveAndNew:false,
            AWSToSobjectMap:{!AWSToSobjectMapJson},
            AWSToSobjectNonEncryptedMap:{!AWSToSobjectNonEncryptedMapJson},
            AWSToSobjectNonEncryptedMapKeySet:{!AWSToSobjectNonEncryptedMapKeySet},
            AWSToSobjectEncryptedMap:{!AWSToSobjectEncryptedMapJson},
            SobjectToAWSModel:function (sobjJson) {
                let leadPayloadList = [];
                let leadPIData = {};
                for(let f in config.AWSToSobjectMap){
                    if(sobjJson.hasOwnProperty(config.AWSToSobjectMap[f])){
                        leadPIData[f] = sobjJson[config.AWSToSobjectMap[f]]
                    }
                    else{
                        console.log(config.AWSToSobjectMap[f] + 'is not in sobjJson');
                    }
                }
                leadPIData.medicalStaffFullName = leadPIData.lastName;// 完成field update workflow
                leadPIData.sfRecordId = '';
                console.log('Sobject PI Data:' + leadPIData);
                leadPayloadList.push(leadPIData);
                console.log(JSON.stringify(leadPayloadList));
                return JSON.stringify(leadPayloadList);
            },
            insertOrUpdateBack:function(payloadJson, r, isNewMode){
                for(let f in config.AWSToSobjectMap){
                    if(r.object[0].hasOwnProperty(f)){
                        payloadJson[config.AWSToSobjectMap[f]] = r.object[0][f];
                    }
                    else{
                        console.log(f + 'is not in r.object[0]');
                    }
                }
                for(let f in config.AWSToSobjectEncryptedMap){
                    if(r.object[0].hasOwnProperty(f)){
                        payloadJson[config.AWSToSobjectEncryptedMap[f]] = r.object[0][f];
                    }
                    else{
                        console.log(f + 'is not in r.object[0]');
                    }
                }
                if('{!rtTypeId}'){
                    payloadJson.RecordTypeId = '{!rtTypeId}';
                }
                //payloadJson.AWS_Data_Id__c = r.object[0].dataId;
                payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
                if (isNewMode) {
                    payloadJson.AWS_Data_Id__c = r.object[0].dataId;
                } else {
                    payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
                }
                return payloadJson;
            },
            queryBack:function (data) {
                console.log('data = ' + data);
                if(data.object){
                    for(let f of config.AWSToSobjectNonEncryptedMapKeySet){
                        let ele = document.getElementById(api_id_map[config.AWSToSobjectNonEncryptedMap[f]])
                        if(data.object.hasOwnProperty(f) && ele){
                            // 多选特殊处理
                            if(ele.type == 'select-multiple'){
                               //let me = GetEleByClass(config.ApiPrefix+'_'+field_api_name);
                               if(ele ){
                                   //_unselected
                                   let v = '';
                                   if(data.object[f]){
                                       v = data.object[f];
                                   }
                                   let arr = v.split(';');
                                   // 清空已有选项
                                   /*
                                   let sl = document.getElementById(ele.id + '_selected');
                                   if(sl){
                                       for(let op of sl.options){
                                           op.selected = true;
                                       }
                                       let la = document.getElementById(ele.id + '_left_arrow');
                                       if(la){
                                           la.click();
                                       }
                                   }
                                   // 赋值新选项
                                   let us = document.getElementById(ele.id + '_unselected');
                                   if(us){
                                       for(let op of us.options){
                                           op.selected = arr.indexOf(op.value)>-1;
                                       }
                                       let ra = document.getElementById(ele.id + '_right_arrow');
                                       if(ra){
                                           ra.click();
                                       }
                                   }*/
                                   for(let op of ele.options){
                                       op.selected = arr.indexOf(op.value)>-1;
                                   }
                                   let ra = document.getElementById(ele.id + '_right_arrow');
                                   if(ra){
                                       ra.click();
                                   }
                               }
                            }else{
                                ele.value = data.object[f];
                            }
                            if(ele.type.indexOf("select")>-1 && ele.value){
                                jQuery(ele).change()
                            }
                        }
                        else{
                            console.log(f + 'is not in data.object');
                        }
                    }
                }
                else{
                    console.log('data.object = ' + data.object);
                }
                // document.querySelector("[data-id='LastName']").value = data.object.lastName;
                // document.querySelector("[data-id='Phone']").value = data.object.phone;
                // document.querySelector("[data-id='Email']").value = data.object.email;
            },
            updateMethod:"NewAndEditContactController.saveContact",
            insertMethod:"NewAndEditContactController.saveContact"
        }
        AWSService.sfSessionId = '{!GETSESSIONID()}';
        var staticResources = JSON.parse('{!staticResource}');
        var requiredFieldAPIList = JSON.parse('{!requiredFieldAPIListStr}');
        var fieldAPIToLabelMap = JSON.parse('{!fieldAPIToLabelMapStr}');
        console.log('{!staticResource}');
        var VLookUpFields = {! VLookUpFieldsJson};
        function ProcessPI(sobjJson, payloadForNewPI) {
            blockme();
            if ({!isNewMode}) {
                NewPIToAWS(sobjJson, payloadForNewPI)
            }else {
                UpdatePIToAWS(sobjJson, payloadForNewPI)
            }
        }
        var GetEleByClass = function(class_name){
            let eles = document.getElementsByClassName(class_name);
            if(eles.length > 0) return eles[0];
            return null;
        }
        var GetEleApiName = function(ele){
            for(let c of ele.classList){
                if(c.indexOf(config.ApiPrefix+'_')>-1){
                    return c.replace(config.ApiPrefix+'_','');
                }
            }
            return '';
        }
        function IsFormTag(tag_name){
            return ['input','select','textarea'].indexOf(tag_name.toLowerCase())>-1;
        }
        function IsFormElement(e){
            return IsFormTag(e.tagName);
        }
        function getPIPayload(sobjJson) {
            return config.SobjectToAWSModel(sobjJson);
        }
        function validateFieldValueFormate() {
            let error_msg = '';
            let textEmail = "[data-id='Email']";
            let textPhone = "[data-id='Phone']";
            //Email
            let email = document.querySelector(textEmail);
            if(email && !/^[\w-]{3,12}@[\da-zA-Z]{2,16}\.[a-zA-Z]+$/.test(email.value)){
                error_msg += ';邮件格式错误';
            }
            let phone = document.querySelector(textPhone);
            if(phone && !/^1[3|5|8|7][0-9]\d{4,8}$/.test(phone.value)){
                error_msg += ';电话号码错误';
            }
            for(let e of document.getElementsByTagName('select')){
                for(let op of e.options){
                    if(op.value == "*****" && op.selected){
                        error_msg += ';下拉框不能主动选择密文选项';
                    }
                }
            }
            if(error_msg.length>0 && error_msg[0]== ';'){
                error_msg = error_msg.substring(1);
            }
            return error_msg;
        }
        function getSobjectInformation() {
            //api_id_map
//let nodelist = document.getElementsByClassName(config.ApiPrefix);
            let result = {}
            for (let index in api_id_map) {
                let ele = document.getElementById(api_id_map[index]);
                let field_api_name = index;
                let tag_name = ele.tagName.toLowerCase();
                if(!IsFormTag(tag_name)){
                    console.log('tag_name='+tag_name+',field_api_name'+field_api_name+' is not a form element');
                    continue;
                }
                if (VLookUpFields.indexOf(field_api_name)>=0) {
                    console.log(ele.id.indexOf('lkwgt'));
                    if (ele.id.indexOf('lkwgt') == -1) {
                        let vlookUpNodeId = ele.id + '_lkid';
                        let vlook_ele = document.getElementById(vlookUpNodeId);
                        let v = '';
                        if(vlook_ele){
                            v = vlook_ele.value;
                        }else{
                            v = ele.value;
                        }
                        if(v && v != "000000000000000"){
                            result[field_api_name] = v;
                        }
                    }
                } else if (ele.type == 'checkbox') {
                    result[field_api_name] = ele.checked;
                } else if (ele.type == 'select-multiple') {
                    //field_api_name
                    let multiple = field_api_name;
                    let targets = GetEleByClass(config.ApiPrefix+'_'+field_api_name).parentNode.children[1].children[0].children[1].children[2].children[0].innerText;
                    targets = targets.replace(/\n/g, ";");
                    console.log('targets = ' + targets);
                    result[field_api_name] = targets;
                } else {
                    result[field_api_name] = ele.value;
                }
                // let e1 = document.getElementById(api_id_map[field_api_name]);
                // if(!result[field_api_name] && e1 && e1.value){
                //     result[field_api_name] = e1.value;
                // }
            }
            return result;
        }
        function QuerySobjectFromAWS() {
            AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
        }
        function queryBack(data) {
            console.log('data = ' + data);
            config.queryBack(data);
            unblockUI();
        };
        function insertOrUpdateBack(payloadJson, result, isNewMode) {
            console.log(result);
            let r = result;
            console.log('Result from AWS' + r);
            console.log('payloadJson=' + payloadJson);
            return config.insertOrUpdateBack(payloadJson, r, isNewMode);
        }
        function redirectCallBack(sfId,errorMsg) {
            unblockUI();
            if(errorMsg){
                alertErrorMessage(errorMsg);
            }
            else{
                if(config.SaveAndNew){
                    window.open('{! SaveAndNewButtonUrl }','_self');
                }else{
                    window.open('/' + sfId, '_self');
                }
            }
        }
        function UpdatePIToAWS(sobjJson, payloadForNewPI) {
            let controllerSaveMethod = config.updateMethod;
            let obj = JSON.parse(payloadForNewPI);
            obj[0].dataId = '{!AWSDataId}';
            let payloadForNewPIJson = JSON.stringify(obj);
            AWSService.update(staticResources.updateUrl, sobjJson, payloadForNewPIJson, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, false, insertOrUpdateBack,redirectCallBack);
        }
        function NewPIToAWS(sobjJson, payloadForNewPI) {
            let controllerSaveMethod = config.insertMethod;
            AWSService.insert(staticResources.newUrl, sobjJson, payloadForNewPI, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, true, insertOrUpdateBack,redirectCallBack);
        }
        function checkRequiredFieldMsg(formData) {
            let blankRequiredFields = '';
            for(i = 0;i<requiredFieldAPIList.length;i++){
                if(formData[requiredFieldAPIList[i]]){
                    continue;
                }else{
                    if(blankRequiredFields == ''){
                        blankRequiredFields =blankRequiredFields + fieldAPIToLabelMap[requiredFieldAPIList[i]];
                    }else{
                        blankRequiredFields =blankRequiredFields+',' + fieldAPIToLabelMap[requiredFieldAPIList[i]];
                    }
                }
            }
            return blankRequiredFields;
        }
        function saveSobjectProcess(save_and_new) {
            if(save_and_new){
                config.SaveAndNew = true;
            }
            hiddenErrorMsgNode();
            //1. Get Sobject Information from Form
            let sobjJson = getSobjectInformation();
            //2. Validate the Sobject field value formate, for example the email formate or phone formate
            let validationResultMessage = validateFieldValueFormate();
            console.log(validationResultMessage);
            if (validationResultMessage) {
                //Popup error message.  - To Do After POC
                alertErrorMessage(validationResultMessage);
                return
            }
            // Check Required Field
            let checkRequiredFieldMsgResult = checkRequiredFieldMsg(sobjJson);
            if (checkRequiredFieldMsgResult) {
                alertErrorMessage('requiredErrorMsg' + checkRequiredFieldMsgResult);
                return
            }
            // //3. Prepare the payload for New PI API To AWS - To Do
            let payloadForNewPI = getPIPayload(sobjJson);
            // //4. Get Authentication Information for AWS
            // loadAWSAuthentication();
            // //5. lead to AWS
            ProcessPI(sobjJson, payloadForNewPI);
            // awsToken = TestToken;
            // NewPIToAWS(sobjJson,awsToken, payloadForNewPI)
        }
        function alertErrorMessage(errorMsg) {
            let errorMsgNode = document.getElementById("page:form:block:msgContent");
            errorMsgNode.innerText = errorMsg;
            errorMsgNode.className = 'pbError';
        }
        function hiddenErrorMsgNode() {
            let errorMsgNode = document.getElementById("page:form:block:msgContent");
            errorMsgNode.innerText = '';
            errorMsgNode.className = '';
        }
    </script>
    <div class="bPageTitle">
        <div class="ptBody">
            <div class="content">
                <img src="/img/s.gif" alt="{! SobjectLabel}" class="pageTitleIcon" title="{! SobjectLabel}" />
                <h1 class="pageType">{! SobjectLabel}<apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText>
                    <span class="titleSeparatingColon">:</span>
                </h1>
                <h2 class="pageDescription"> <apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText>{! SobjectLabel}</h2>
                <div class="blank">&nbsp;</div>
            </div>
            <div class="links">
                <a href="javascript:openPopupFocusEscapePounds(%27https://help.salesforce.com/apex/htdoor?loc=help&amp;target={!sobjectTypeValue}s_edit.htm&amp;section={!sobjectTypeValue}s&amp;language=zh_CN&amp;release=234.18.8&amp;instance=CS117&amp;showSplash=true%27, %27Help%27, 700, 600, %27width=700,height=600,resizable=yes,toolbar=yes,status=no,scrollbars=yes,menubar=yes,directories=no,location=no,dependant=no%27, false, false);"
                    title="此页面的帮助 (新窗口)">
                    <span class="helpLink">此页面的帮助</span>
                    <img src="/img/s.gif" alt="" class="helpIcon" />
                </a>
            </div>
        </div>
        <div class="ptBreadcrumb"></div>
    </div>
    <apex:form id="form">
        <apex:pageblock id="block">
            <div class="pbHeader">
                <table cellspacing="0" cellpadding="0" border="0">
                    <tbody>
                        <tr>
                            <td class="pbTitle">
                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />
                                <h2 class="mainTitle">{! SobjectLabel}<apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText></h2>
                            </td>
                            <td class="pbButton" id="topButtonRow">
                                <input class="btn" type="Button" value="{!$Label.Save}" onclick="saveSobjectProcess()" />
                                <input class="btn" type="Button" value="{!$Label.SaveAndNew}" onclick="saveSobjectProcess(1)" />
                                <apex:commandButton action="{!cancel}" value="{!$Label.Cancel}" />
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>
            <!-- Error Msg-->
            <div style="text-align: center;">
                <apex:outputPanel id="errorMsg">
                    <apex:pageMessages id="msgContent" escape="false" />
                </apex:outputPanel>
            </div>
            <!-- Iterate the layoutSections, which is a list of sections -->
            <apex:repeat value="{!layoutSections}" var="layoutSection">
                <apex:pageBlockSection title="{!layoutSection.name}" collapsible="{!layoutSection.allowCollapse}" columns="{!layoutSection.columns}">
                    <!--Each section has layoutFields, let's iterate them as well-->
                    <apex:repeat value="{!layoutSection.layoutFields}" var="layoutField">
                        <apex:inputField styleClass="{!ApiPrefix} {!ApiPrefix}_{!layoutField.fieldAPI}" html-data-id="{!layoutField.fieldAPI}" value="{!Contact[layoutField.fieldAPI]}" rendered="{!not(layoutField.isPlaceHOlder)}"
                                         required="{!layoutField.isRequired}" />
                        <apex:pageblocksectionitem rendered="{!layoutField.isPlaceHolder}">
                        </apex:pageblocksectionitem>
                    </apex:repeat>
                </apex:pageBlockSection>
            </apex:repeat>
            <script>
            var init_nodes = document.getElementsByClassName("PIBackApi");
            var api_id_map={};
            for(let e of init_nodes){
                if(IsFormElement(e)){
                    if(e.getAttribute("multiple") != 'multiple' || e.style.display == 'none' && e.id.indexOf('selected') < 0){
                        api_id_map[GetEleApiName(e)] = e.id;
                    }
                }
            }
            console.log(api_id_map);
            sfdcPage.appendToOnloadQueue(function () {
                //1. Set Last Name label
                //document.querySelector("[data-id='LastName']").parentNode.parentNode.parentNode.children[2].children[0].innerText = '姓名';
                //2. Query AWS Data by dataId
                console.log('Mode for Sobject Page:' + {!isNewMode});
                if (!{!isNewMode}) {
                    blockme();
                    QuerySobjectFromAWS();
                }
            });
            </script>
            <div class="pbBottomButtons">
                <table cellspacing="0" cellpadding="0" border="0">
                    <tbody>
                        <tr>
                            <td class="pbTitle">
                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />&nbsp;</td>
                            <td class="pbButtonb" id="bottomButtonRow">
                                <input class="btn" type="Button" value="{!$Label.Save}" onclick="saveSobjectProcess()" />
                                <input class="btn" type="Button" value="{!$Label.SaveAndNew}" onclick="saveSobjectProcess()" />
                                <apex:commandButton action="{!cancel}" value="{!$Label.Cancel}" />
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>
        </apex:pageblock>
    </apex:form>
</apex:page>
force-app/main/default/pages/NewAndEditContact.page-meta.xml
New file
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>53.0</apiVersion>
    <availableInTouch>false</availableInTouch>
    <confirmationTokenRequired>false</confirmationTokenRequired>
    <label>NewAndEditContact</label>
</ApexPage>
force-app/main/default/pages/NewAndEditInquiryForm.page
New file
@@ -0,0 +1,607 @@
<apex:page standardController="Inquiry_form__c" extensions="NewAndEditInquiryFormController" id="page">
    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
    <script src="../../soap/ajax/53.0/connection.js" type="text/javascript"></script>
    <apex:stylesheet value="{!URLFOR($Resource.blockUIcss)}"/>
    <apex:includeScript value="{!URLFOR($Resource.jquery183minjs)}"/>
    <apex:includeScript value="{!URLFOR($Resource.PleaseWaitDialog)}"/>
    <style>
        .disabledbutton {
            pointer-events: none;
            opacity: 0.4;
        }
    </style>
    <script>
        AWSService.sfSessionId = '{!GETSESSIONID()}';
        //配置方法
        var config = {};
        config = {
            SobjectName : "{!SobjectName}",
            ApiPrefix:"{!ApiPrefix}",
            SaveAndNew:false,
            AWSToSobjectMap:{!AWSToSobjectMapJson},
            AWSToSobjectNonEncryptedMap:{!AWSToSobjectNonEncryptedMapJson},
            AWSToSobjectEncryptedMap:{!AWSToSobjectEncryptedMapJson},
            SobjectToAWSModel:function (sobjJson) {
                let leadPayloadList = [];
                let leadPIData = {};
                for(let f in config.AWSToSobjectMap){
                    if(sobjJson.hasOwnProperty(config.AWSToSobjectMap[f])){
                        leadPIData[f] = sobjJson[config.AWSToSobjectMap[f]]
                    }
                    else{
                        console.log(config.AWSToSobjectMap[f] + 'is not in sobjJson');
                    }
                }
                leadPIData.sfRecordId = '';
                console.log('Sobject PI Data:' + leadPIData);
                leadPayloadList.push(leadPIData);
                console.log(JSON.stringify(leadPayloadList));
                return JSON.stringify(leadPayloadList);
            },
            insertOrUpdateBack:function(payloadJson, r, isNewMode){
                for(let f in config.AWSToSobjectMap){
                    if(r.object[0].hasOwnProperty(f)){
                        payloadJson[config.AWSToSobjectMap[f]] = r.object[0][f];
                    }
                    else{
                        console.log(f + 'is not in r.object[0]');
                    }
                }
                for(let f in config.AWSToSobjectEncryptedMap){
                    if(r.object[0].hasOwnProperty(f)){
                        payloadJson[config.AWSToSobjectEncryptedMap[f]] = r.object[0][f];
                    }
                    else{
                        console.log(f + 'is not in r.object[0]');
                    }
                }
                //payloadJson.AWS_Data_Id__c = r.object[0].dataId;
                payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
                if (isNewMode) {
                    payloadJson.AWS_Data_Id__c = r.object[0].dataId;
                } else {
                    payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
                }
                return payloadJson;
            },
            queryBack:function (data) {
                console.log('data = ' + data);
                if(data.object){
                    for(let f in config.AWSToSobjectNonEncryptedMap){
                        let ele = GetEleByClass(config.ApiPrefix + "_"+ config.AWSToSobjectNonEncryptedMap[f]);
                        if(data.object.hasOwnProperty(f) && ele){
                            // 多选特殊处理
                            if(ele.type == 'select-multiple'){
                               //let me = GetEleByClass(config.ApiPrefix+'_'+field_api_name);
                               if(ele && data.object[f]){
                                   let arr = data.object[f].split(';');
                                   // 给隐藏的select赋值
                                   for(let op of ele.options){
                                       op.selected = arr.indexOf(op.value)>-1;
                                   }
                                   // 利用按钮给显示的select赋值
                                   let ra = document.getElementById(ele.id + '_right_arrow');
                                   if(ra){
                                       ra.click();
                                   }
                               }
                            }else{
                                ele.value = data.object[f];
                            }
                        }
                        else{
                            console.log(f + 'is not in data.object');
                        }
                    }
                }
                else{
                    console.log('data.object = ' + data.object);
                }
                // document.querySelector("[data-id='LastName']").value = data.object.lastName;
                // document.querySelector("[data-id='Phone']").value = data.object.phone;
                // document.querySelector("[data-id='Email']").value = data.object.email;
            },
            updateMethod:"NewAndEditInquiryFormController.saveInquiryForm",
            insertMethod:"NewAndEditInquiryFormController.saveInquiryForm"
        }
        var requiredFieldAPIList = JSON.parse('{!requiredFieldAPIListStr}');
        var fieldAPIToLabelMap = JSON.parse('{!fieldAPIToLabelMapStr}');
        var staticResources = JSON.parse('{!staticResource}');
        var staticResourcesContact = JSON.parse('{!staticResourceContact}');
        var staticResourcesLead = JSON.parse('{!staticResourceLead}');
        console.log('{!staticResource}');
        var VLookUpFields = {! VLookUpFieldsJson};
        function ProcessPI(sobjJson, payloadForNewPI) {
            blockme();
            if ({!isNewMode}) {
                NewPIToAWS(sobjJson, payloadForNewPI)
            }else {
                UpdatePIToAWS(sobjJson, payloadForNewPI)
            }
        }
        var GetEleByClass = function(class_name){
            let eles = document.getElementsByClassName(class_name);
            if(eles.length > 0) return eles[0];
            return null;
        }
        var GetEleApiName = function(ele){
            for(let c of ele.classList){
                if(c.indexOf(config.ApiPrefix+'_')>-1){
                    return c.replace(config.ApiPrefix+'_','');
                }
            }
            return '';
        }
        function IsFormElement(tag_name){
            return ['input','select','textarea'].indexOf(tag_name)>-1;
        }
        function getPIPayload(sobjJson) {
            return config.SobjectToAWSModel(sobjJson);
        }
        function validateFieldValueFormate() {
            let error_msg = '';
            let textEmail = "[data-id='Email__c']";
            let textPhone = "[data-id='Phone__c']";
            if (document.querySelector("[data-id='Email__c']").value != "" && document.querySelector("[data-id='Email__c']").value != null) {
                //Email
                let email = document.querySelector(textEmail);
                if(email && !/^[\w-]{3,12}@[\da-zA-Z]{2,16}\.[a-zA-Z]+$/.test(email.value)){
                    error_msg += ';邮件格式错误';
                }
            }
            if (document.querySelector("[data-id='Phone__c']").value != "" && document.querySelector("[data-id='Phone__c']").value != null) {
                let phone = document.querySelector(textPhone);
                if(phone && !/^1[3|5|8|7][0-9]\d{4,8}$/.test(phone.value)){
                    error_msg += ';电话号码错误';
                }
            }
            for(let e of document.getElementsByTagName('select')){
                for(let op of e.options){
                    if(op.value == "*****" && op.selected){
                        error_msg += ';下拉框不能主动选择密文选项';
                    }
                }
            }
            if(error_msg.length>0 && error_msg[0]== ';'){
                error_msg = error_msg.substring(1);
            }
            return error_msg;
        }
        function getSobjectInformation() {
            let nodelist = document.getElementsByClassName(config.ApiPrefix);
            let result = {}
            for (let index = 0; index < nodelist.length; index++) {
                let ele = nodelist[index];
                let field_api_name = GetEleApiName(ele);
                let tag_name = ele.tagName.toLowerCase();
                if(!IsFormElement(tag_name)){
                    console.log('tag_name='+tag_name+',field_api_name '+field_api_name+' is not a form element');
                    continue;
                }
                if (VLookUpFields.indexOf(field_api_name)>=0) {
                    console.log(ele.id.indexOf('lkwgt'));
                    if (ele.id.indexOf('lkwgt') == -1) {
                        let vlookUpNodeId = ele.id + '_lkid';
                        let vlook_ele = document.getElementById(vlookUpNodeId);
                        let v = '';
                        if(vlook_ele){
                            v = vlook_ele.value;
                        }else{
                            v = ele.value;
                        }
                        if(v && v != "000000000000000"){
                            result[field_api_name] = v;
                        }
                    }
                } else if (ele.type == 'checkbox') {
                    result[field_api_name] = ele.checked;
                } else if (ele.type == 'select-multiple') {
                    //field_api_name
                    let multiple = field_api_name;
                    let targets = "";
                    //InquiryForm特殊处理
                    if(multiple == "Product1__c" || multiple == "Request1__c"){
                        targets = GetEleByClass(config.ApiPrefix+'_'+field_api_name).parentNode.children[2].rows[1].cells[2].innerText;
                    }else{
                        targets = GetEleByClass(config.ApiPrefix+'_'+field_api_name).parentNode.children[1].children[0].children[1].children[2].children[0].innerText;
                    }
                    targets = targets.replace(/\n/g, ";");
                    console.log('targets = ' + targets);
                    result[field_api_name] = targets;
                } else {
                    result[field_api_name] = ele.value;
                }
            }
            return result;
        }
        //查询 解密
        function QuerySobjectFromAWS() {
            AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
        }
        //查询 返回
        function queryBack(data) {
            console.log('data = ' + data);
            config.queryBack(data);
        };
        //新建/更改 返回
        function insertOrUpdateBack(payloadJson, result, isNewMode) {
            console.log(result);
            let r = result;
            console.log('Result from AWS' + r);
            console.log('payloadJson=' + payloadJson);
            return config.insertOrUpdateBack(payloadJson, r, isNewMode);
        }
        function redirectCallBack(sfId,errorMsg) {
            unblockUI();
            if(errorMsg){
                alertErrorMessage(errorMsg);
            }
            else{
                if(config.SaveAndNew){
                    window.open('{! SaveAndNewButtonUrl }','_self');
                }else{
                    window.open('/' + sfId, '_self');
                }
            }
        }
        //更新 to AWS
        function UpdatePIToAWS(sobjJson, payloadForNewPI) {
            let controllerSaveMethod = config.updateMethod;
            let obj = JSON.parse(payloadForNewPI);
            obj[0].dataId = '{!AWSDataId}';
            let payloadForNewPIJson = JSON.stringify(obj);
            AWSService.update(staticResources.updateUrl, sobjJson, payloadForNewPIJson, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, false, insertOrUpdateBack,redirectCallBack);
        }
        //新建 to AWS
        function NewPIToAWS(sobjJson, payloadForNewPI) {
            let controllerSaveMethod = config.insertMethod;
            AWSService.insert(staticResources.newUrl, sobjJson, payloadForNewPI, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, true, insertOrUpdateBack,redirectCallBack);
        }
        //必填字段
        function checkRequiredFieldMsg(formData) {
            let blankRequiredFields = '';
            for(i = 0;i<requiredFieldAPIList.length;i++){
                if(formData[requiredFieldAPIList[i]]){
                    continue;
                }else{
                    if(blankRequiredFields == ''){
                        blankRequiredFields =blankRequiredFields + fieldAPIToLabelMap[requiredFieldAPIList[i]];
                    }else{
                        blankRequiredFields =blankRequiredFields+',' + fieldAPIToLabelMap[requiredFieldAPIList[i]];
                    }
                }
            }
            return blankRequiredFields;
        }
        //按钮点击方法
        function saveSobjectProcess(save_and_new) {
            if(save_and_new){
                config.SaveAndNew = true;
            }
            hiddenErrorMsgNode();
            //1. Get Sobject Information from Form
            let sobjJson = getSobjectInformation();
            //2. Validate the Sobject field value formate, for example the email formate or phone formate
            let validationResultMessage = validateFieldValueFormate();
            console.log(validationResultMessage);
            if (validationResultMessage) {
                //Popup error message.  - To Do After POC
                alertErrorMessage(validationResultMessage);
                return
            }
            // Check Required Field
            let checkRequiredFieldMsgResult = checkRequiredFieldMsg(sobjJson);
            if (checkRequiredFieldMsgResult) {
                alertErrorMessage('requiredErrorMsg' + checkRequiredFieldMsgResult);
                return
            }
            // //3. Prepare the payload for New PI API To AWS - To Do
            let payloadForNewPI = getPIPayload(sobjJson);
            // //4. Get Authentication Information for AWS
            // loadAWSAuthentication();
            // //5. Inquiry to AWS
            ProcessPI(sobjJson, payloadForNewPI);
            // awsToken = TestToken;
            // NewPIToAWS(sobjJson,awsToken, payloadForNewPI)
        }
        function alertErrorMessage(errorMsg) {
            let errorMsgNode = document.getElementById("page:form:block:msgContent");
            errorMsgNode.innerText = errorMsg;
            errorMsgNode.className = 'pbError';
        }
        function hiddenErrorMsgNode() {
            let errorMsgNode = document.getElementById("page:form:block:msgContent");
            errorMsgNode.innerText = '';
            errorMsgNode.className = '';
        }
        var newSearchContactWindow = null;
        var contactHtmlString = '<img src="/img/s.gif" onclick="searchContact(\'page:form:contactId\')" alt="Reference Document Number Lookup" class="lookupIcon"  title="Reference Document Number Lookup (New Window)"/>';
        function htmlToElement(html) {
            var template = document.createElement('template');
            html = html.trim(); // Never return a text node of whitespace as the result
            template.innerHTML = html;
            return template.content.firstChild;
        }
        //自定义lookup查询
        function searchContact(contactNodeId){
            // errorMsg 隐藏
            if(document.getElementsByClassName("errorMsg").length > 0){
                document.getElementsByClassName("errorMsg")[0].style.display="none";
            }
            let accountValue = "";
            let suffixUrl = "";
            if (document.querySelector("[data-id='Hospital_Name__c']")) {
                let accountNodeId = document.querySelector("[data-id='Hospital_Name__c']").id + '_lkid';
                accountValue = document.getElementById(accountNodeId).value;
            }
            console.log(accountValue);
            if(accountValue !='000000000000000'){
                suffixUrl = "?contactId="+contactNodeId+"&accountId="+accountValue;
            }else{
                suffixUrl = "?contactId="+contactNodeId;
            }
            let baseUrl = "/apex/SearchContactPage";
            let newSearchContactParam = 'height=600,width=800,left=100,top=100,dialogHide=true,resizable=no,scrollbars=yes,toolbar=no,status=no';
            newSearchContactWindow = window.open(baseUrl+suffixUrl, 'Popup', newSearchContactParam);
            if (window.focus) {
                newSearchContactWindow.focus();
            }
            return false;
        }
        //窗口关闭时发生
        function closePopupWindow() {
            if (null != newSearchContactWindow) {
                newSearchContactWindow.close();
            }
            let contactInfoStr = document.getElementById('page:form:contactId').value;
            console.log('closePopup:'+contactInfoStr);
            let contactInfo = JSON.parse(contactInfoStr);
            let contactNodeId = document.querySelector("[data-id='Contact_Name__c']").id + '_lkid';
            document.getElementById(contactNodeId).value = contactInfo.ContactId;
            document.querySelector("[data-id='Contact_Name__c']").value = contactInfo.Name;
        }
        //替换vlookup
        function replaceSearchContactLookup() {
            let lookUpNode = htmlToElement(contactHtmlString);
            console.log(lookUpNode);
            if (!{!isNewMode}) {
                //1. Query Contact from AWS by AWSDataId
                queryContactName()
            }
            let parentNode = document.querySelector("[data-id='Contact_Name__c']").parentNode;
            document.querySelector("[data-id='Contact_Name__c']").removeAttribute("onchange");
            parentNode.replaceChild(lookUpNode, document.querySelector("[data-id='Contact_Name__c']").parentNode.children[2]);
        }
        function queryContactName() {
            let sfId = document.getElementById(document.querySelector("[data-id='Contact_Name__c']").id + '_lkid').value;
            let contactsInfo = JSON.parse('{!LookUpOverrideFieldsMapJson}');
            let dataId = contactsInfo[sfId];
            // let queryContactBack = function(data){
            //     //To Do later
            //     console.log('ContactData = ' + data.object);
            //     document.querySelector("[data-id='Contact_Name__c']").value = data.object.lastName;
            // }
            // AWSService.query(staticResourcesContact.queryUrl, dataId, queryContactBack, staticResources.token);
            let url = staticResourcesContact.queryUrl + '?dataId=' + dataId;
            fetch(url, {
                method: 'GET',
                headers: {
                    'Content-Type': 'application/json',
                    'pi-token': staticResources.token
                }
            }).then((data) => {
                return data.json();
            }).then((result) => {
                document.querySelector("[data-id='Contact_Name__c']").value = result.object.lastName;
            })
        }
        //For Lead Search
        var leadHtmlString = '<img src="/img/s.gif" onclick="searchLead(\'page:form:leadId\')" alt="Reference Document Number Lookup" class="lookupIcon"  title="Reference Document Number Lookup (New Window)"/>';
        var newSearchLeadWindow = null;
        //窗口关闭时发生
        function closeLeadPopupWindow() {
            if (null != newSearchLeadWindow) {
                newSearchLeadWindow.close();
            }
            let leadInfoStr = document.getElementById('page:form:leadId').value;
            console.log('closePopup:'+leadInfoStr);
            let leadInfo = JSON.parse(leadInfoStr);
            let leadNodeId = document.querySelector("[data-id='Lead_link__c']").id + '_lkid';
            document.getElementById(leadNodeId).value = leadInfo.LeadId;
            document.querySelector("[data-id='Lead_link__c']").value = leadInfo.Name;
        }
        function searchLead(leadNodeId){
            // let accountValue = "";
            // let suffixUrl = "";
            let suffixUrl = "?leadId="+leadNodeId;
            let baseUrl = "/apex/SearchLeadPage";
            let newSearchLeadParam = 'height=600,width=800,left=100,top=100,dialogHide=true,resizable=no,scrollbars=yes,toolbar=no,status=no';
            newSearchLeadWindow = window.open(baseUrl+suffixUrl, 'Popup', newSearchLeadParam);
            if (window.focus) {
                newSearchLeadWindow.focus();
            }
            return false;
        }
        //替换查找Lead
        function replaceSearchLeadLookup() {
            let lookUpNode = htmlToElement(leadHtmlString);
            console.log(lookUpNode);
            if (!{!isNewMode}) {
                //1. Query Lead from AWS by AWSDataId
                queryLeadName()
            }
            let parentNode = document.querySelector("[data-id='Lead_link__c']").parentNode;
            document.querySelector("[data-id='Lead_link__c']").removeAttribute("onchange");
            parentNode.replaceChild(lookUpNode, document.querySelector("[data-id='Lead_link__c']").parentNode.children[2]);
        }
        function queryLeadName() {
            let sfId = document.getElementById(document.querySelector("[data-id='Lead_link__c']").id + '_lkid').value;
            let leadsInfo = JSON.parse('{!LookUpOverrideFieldsMapJson}');
            let dataId = leadsInfo[sfId];
            // let queryLeadBack = function(data){
            //     //To Do later
            //     console.log('ContactData = ' + data.object);
            //     document.querySelector("[data-id='Lead_link__c']").value = data.object.lastName;
            // }
            // AWSService.query(staticResourcesLead.queryUrl, dataId, queryLeadBack, staticResources.token);
            let url = staticResourcesLead.queryUrl + '?dataId=' + dataId;
            fetch(url, {
                method: 'GET',
                headers: {
                    'Content-Type': 'application/json',
                    'pi-token': staticResources.token
                }
            }).then((data) => {
                return data.json();
            }).then((result) => {
                document.querySelector("[data-id='Lead_link__c']").value = result.object.lastName;
            })
        }
    </script>
    <div class="bPageTitle">
        <div class="ptBody">
            <div class="content">
                <img src="/img/s.gif" alt="{! SobjectLabel}" class="pageTitleIcon" title="{! SobjectLabel}" />
                <h1 class="pageType">{! SobjectLabel}<apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText>
                    <span class="titleSeparatingColon">:</span>
                </h1>
                <h2 class="pageDescription"> <apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText>{! SobjectLabel}</h2>
                <div class="blank">&nbsp;</div>
            </div>
            <div class="links">
                <a href="javascript:openPopupFocusEscapePounds(%27https://help.salesforce.com/apex/htdoor?loc=help&amp;target={!sobjectTypeValue}s_edit.htm&amp;section={!sobjectTypeValue}s&amp;language=zh_CN&amp;release=234.18.8&amp;instance=CS117&amp;showSplash=true%27, %27Help%27, 700, 600, %27width=700,height=600,resizable=yes,toolbar=yes,status=no,scrollbars=yes,menubar=yes,directories=no,location=no,dependant=no%27, false, false);"
                    title="此页面的帮助 (新窗口)">
                    <span class="helpLink">此页面的帮助</span>
                    <img src="/img/s.gif" alt="" class="helpIcon" />
                </a>
            </div>
        </div>
        <div class="ptBreadcrumb"></div>
    </div>
    <apex:form id="form">
        <apex:inputHidden value="{!contactId}" id="contactId"/>
        <apex:inputHidden value="{!leadId}" id="leadId"/>
        <apex:pageblock id="block">
            <div class="pbHeader">
                <table cellspacing="0" cellpadding="0" border="0">
                    <tbody>
                        <tr>
                            <td class="pbTitle">
                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />
                                <h2 class="mainTitle">{! SobjectLabel}<apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText></h2>
                            </td>
                            <td class="pbButton" id="topButtonRow">
                                <input class="btn" type="Button" value="{!$Label.Save}" onclick="saveSobjectProcess()" />
                                <input class="btn" type="Button" value="{!$Label.SaveAndNew}" onclick="saveSobjectProcess(1)" />
                                <apex:commandButton action="{!cancel}" value="{!$Label.Cancel}" />
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>
            <!-- Error Msg-->
            <div style="text-align: center;">
                <apex:outputPanel id="errorMsg">
                    <apex:pageMessages id="msgContent" escape="false" />
                </apex:outputPanel>
            </div>
            <!-- Iterate the layoutSections, which is a list of sections -->
            <apex:repeat value="{!layoutSections}" var="layoutSection">
                <apex:pageBlockSection title="{!layoutSection.name}" collapsible="{!layoutSection.allowCollapse}" columns="{!layoutSection.columns}">
                    <!--Each section has layoutFields, let's iterate them as well-->
                    <apex:repeat value="{!layoutSection.layoutFields}" var="layoutField">
                        <apex:inputField styleClass="{!ApiPrefix} {!ApiPrefix}_{!layoutField.fieldAPI}" html-data-id="{!layoutField.fieldAPI}" value="{!Inquiry_form__c[layoutField.fieldAPI]}" rendered="{!not(layoutField.isPlaceHOlder)}"
                            required="{!layoutField.isRequired}" />
                        <apex:pageblocksectionitem rendered="{!layoutField.isPlaceHolder}">
                        </apex:pageblocksectionitem>
                    </apex:repeat>
                </apex:pageBlockSection>
            </apex:repeat>
            <script>
                sfdcPage.appendToOnloadQueue(function () {
                    //1. Set Last Name label
                    //document.querySelector("[data-id='LastName']").parentNode.parentNode.parentNode.children[2].children[0].innerText = '姓名';
                    //2. Query AWS Data by dataId
                    console.log('Mode for Sobject Page:' + {!isNewMode});
                    if (!{!isNewMode}) {
                        blockme();
                        QuerySobjectFromAWS();
                        unblockUI();
                    }
                    //Replace Contact Vlookup Field
                    replaceSearchContactLookup();
                    //Replace Lead Vlookup Field
                    replaceSearchLeadLookup();
                    document.querySelectorAll("[data-id='OwnerId']")[0].classList.add("disabledbutton");
                    document.querySelectorAll("[data-id='OwnerId']")[1].classList.add("disabledbutton");
                });
            </script>
            <div class="pbBottomButtons">
                <table cellspacing="0" cellpadding="0" border="0">
                    <tbody>
                        <tr>
                            <td class="pbTitle">
                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />&nbsp;</td>
                            <td class="pbButtonb" id="bottomButtonRow">
                                <input class="btn" type="Button" value="{!$Label.Save}" onclick="saveSobjectProcess()" />
                                <input class="btn" type="Button" value="{!$Label.SaveAndNew}" onclick="saveSobjectProcess()" />
                                <apex:commandButton action="{!cancel}" value="{!$Label.Cancel}" />
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>
        </apex:pageblock>
    </apex:form>
</apex:page>
force-app/main/default/pages/NewAndEditInquiryForm.page-meta.xml
New file
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>52.0</apiVersion>
    <availableInTouch>false</availableInTouch>
    <confirmationTokenRequired>false</confirmationTokenRequired>
    <label>NewAndEditInquiryForm</label>
</ApexPage>
force-app/main/default/pages/NewAndEditInspectionReport.page
New file
@@ -0,0 +1,436 @@
<apex:page standardController="Inspection_Report__c" extensions="NewAndEditInspectionReportController" id="page">
    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
    <script src="../../soap/ajax/53.0/connection.js" type="text/javascript"></script>
    <apex:stylesheet value="{!URLFOR($Resource.blockUIcss)}"/>
    <apex:includeScript value="{!URLFOR($Resource.jquery183minjs)}"/>
    <apex:includeScript value="{!URLFOR($Resource.PleaseWaitDialog)}"/>
    <script>
        var config = {};
        config = {
            SobjectName : "{!SobjectName}",
            ApiPrefix:"{!ApiPrefix}",
            SaveAndNew:false,
            AWSToSobjectMap:{!AWSToSobjectMapJson},
            AWSToSobjectNonEncryptedMap:{!AWSToSobjectNonEncryptedMapJson},
            AWSToSobjectEncryptedMap:{!AWSToSobjectEncryptedMapJson},
            SobjectToAWSModel:function (sobjJson) {
                let leadPayloadList = [];
                let leadPIData = {};
                for(let f in config.AWSToSobjectMap){
                    if(sobjJson.hasOwnProperty(config.AWSToSobjectMap[f])){
                        leadPIData[f] = sobjJson[config.AWSToSobjectMap[f]]
                    }
                    else{
                        console.log(config.AWSToSobjectMap[f] + 'is not in sobjJson');
                    }
                }
                leadPIData.sfRecordId = '';
                console.log('Sobject PI Data:' + leadPIData);
                leadPayloadList.push(leadPIData);
                console.log(JSON.stringify(leadPayloadList));
                return JSON.stringify(leadPayloadList);
            },
            insertOrUpdateBack:function(payloadJson, r, isNewMode){
                for(let f in config.AWSToSobjectMap){
                    if(r.object[0].hasOwnProperty(f)){
                        payloadJson[config.AWSToSobjectMap[f]] = r.object[0][f];
                    }
                    else{
                        console.log(f + 'is not in r.object[0]');
                    }
                }
                for(let f in config.AWSToSobjectEncryptedMap){
                    if(r.object[0].hasOwnProperty(f)){
                        payloadJson[config.AWSToSobjectEncryptedMap[f]] = r.object[0][f];
                    }
                    else{
                        console.log(f + 'is not in r.object[0]');
                    }
                }
                //payloadJson.AWS_Data_Id__c = r.object[0].dataId;
                payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
                if (isNewMode) {
                    payloadJson.AWS_Data_Id__c = r.object[0].dataId;
                } else {
                    payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
                }
                return payloadJson;
            },
            queryBack:function (data) {
                console.log('data = ' + data);
                if(data.object){
                    for(let f in config.AWSToSobjectNonEncryptedMap){
                        let ele = GetEleByClass(config.ApiPrefix + "_"+ config.AWSToSobjectNonEncryptedMap[f]);
                        if(data.object.hasOwnProperty(f) && ele){
                            // 多选特殊处理
                            if(ele.type == 'select-multiple'){
                               //let me = GetEleByClass(config.ApiPrefix+'_'+field_api_name);
                               if(ele && data.object[f]){
                                   let arr = data.object[f].split(';');
                                   // 给隐藏的select赋值
                                   for(let op of ele.options){
                                       op.selected = arr.indexOf(op.value)>-1;
                                   }
                                   // 利用按钮给显示的select赋值
                                   let ra = document.getElementById(ele.id + '_right_arrow');
                                   if(ra){
                                       ra.click();
                                   }
                               }
                            }else{
                                ele.value = data.object[f];
                            }
                        }
                        else{
                            console.log(f + 'is not in data.object');
                        }
                    }
                }
                else{
                    console.log('data.object = ' + data.object);
                }
                //document.querySelector("[data-id='Responsible_Person__c']").value = data.object.responsiblePersonHP;
                //document.querySelector("[data-id='phone__c']").value = data.object.callerPhone;
                //document.querySelector("[data-id='Email']").value = data.object.email;
            },
            updateMethod:"NewAndEditInspectionReportController.saveInspectionReport",
            insertMethod:"NewAndEditInspectionReportController.saveInspectionReport"
        }
        AWSService.sfSessionId = '{!GETSESSIONID()}';
        var staticResources = JSON.parse('{!staticResource}');
        var requiredFieldAPIList = JSON.parse('{!requiredFieldAPIListStr}');
        var fieldAPIToLabelMap = JSON.parse('{!fieldAPIToLabelMapStr}');
        console.log('{!staticResource}');
        var VLookUpFields = {! VLookUpFieldsJson};
        function ProcessPI(sobjJson, payloadForNewPI) {
            blockme();
            if ({!isNewMode}) {
                NewPIToAWS(sobjJson, payloadForNewPI)
            }else {
                UpdatePIToAWS(sobjJson, payloadForNewPI)
            }
        }
        var GetEleByClass = function(class_name){
            let eles = document.getElementsByClassName(class_name);
            if(eles.length > 0) return eles[0];
            return null;
        }
        var GetEleApiName = function(ele){
            for(let c of ele.classList){
                if(c.indexOf(config.ApiPrefix+'_')>-1){
                    return c.replace(config.ApiPrefix+'_','');
                }
            }
            return '';
        }
        function IsFormElement(tag_name){
            return ['input','select','textarea'].indexOf(tag_name)>-1;
        }
        function getPIPayload(sobjJson) {
            return config.SobjectToAWSModel(sobjJson);
        }
        function validateFieldValueFormate() {
            let error_msg = '';
            let textEmail = "[data-id='Email']";
            let textPhone = "[data-id='Phone']";
            //Email
            let email = document.querySelector(textEmail);
            if(email && !/^[\w-]{3,12}@[\da-zA-Z]{2,16}\.[a-zA-Z]+$/.test(email.value)){
                error_msg += ';邮件格式错误';
            }
            let phone = document.querySelector(textPhone);
            if(phone && !/^1[3|5|8|7][0-9]\d{4,8}$/.test(phone.value)){
                error_msg += ';电话号码错误';
            }
            for(let e of document.getElementsByTagName('select')){
                for(let op of e.options){
                    if(op.value == "*****" && op.selected){
                        error_msg += ';下拉框不能主动选择密文选项';
                    }
                }
            }
            if(error_msg.length>0 && error_msg[0]== ';'){
                error_msg = error_msg.substring(1);
            }
            return error_msg;
        }
        function getSobjectInformation() {
            let nodelist = document.getElementsByClassName(config.ApiPrefix);
            let result = {}
            for (let index = 0; index < nodelist.length; index++) {
                let ele = nodelist[index];
                console.log('ele:'+ele)
                let field_api_name = GetEleApiName(ele);
                console.log('field_api_name:'+field_api_name)
                let tag_name = ele.tagName.toLowerCase();
                if(!IsFormElement(tag_name)){
                    console.log('tag_name='+tag_name+',field_api_name'+field_api_name+' is not a form element');
                    continue;
                }
                if (VLookUpFields.indexOf(field_api_name)>=0) {
                    console.log(ele.id.indexOf('lkwgt'));
                    if (ele.id.indexOf('lkwgt') == -1) {
                        let vlookUpNodeId = ele.id + '_lkid';
                        let vlook_ele = document.getElementById(vlookUpNodeId);
                        let v = '';
                        if(vlook_ele){
                            v = vlook_ele.value;
                        }else{
                            v = ele.value;
                        }
                        if(v && v != "000000000000000"){
                            result[field_api_name] = v;
                        }
                    }
                } else if (ele.type == 'checkbox') {
                    result[field_api_name] = ele.checked;
                } else if (ele.type == 'select-multiple') {
                    //field_api_name
                    let multiple = field_api_name;
                    let targets = GetEleByClass(config.ApiPrefix+'_'+field_api_name).parentNode.children[1].children[0].children[1].children[2].children[0].innerText;
                    targets = targets.replace(/\n/g, ";");
                    console.log('targets = ' + targets);
                    result[field_api_name] = targets;
                } else {
                    result[field_api_name] = ele.value;
                }
            }
            //let reporter = GetEleApiName(nodelist[5])
            //console.log('reporter:'+reporter);
            result['Reporter__c'] = document.getElementById('page:form:block:j_id50:0:j_id51:j_id52:4:j_id53_lkid').value;
            return result;
        }
        function QuerySobjectFromAWS() {
            AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
        }
        function queryBack(data) {
            console.log('data = ' + data);
            config.queryBack(data);
            unblockUI();
        };
        function insertOrUpdateBack(payloadJson, result, isNewMode) {
            console.log(result);
            let r = result;
            console.log('Result from AWS' + r);
            console.log('payloadJson=' + payloadJson);
            return config.insertOrUpdateBack(payloadJson, r, isNewMode);
        }
        function redirectCallBack(sfId,errorMsg) {
            unblockUI();
            if(errorMsg){
                alertErrorMessage(errorMsg);
            }
            else{
                if(config.SaveAndNew){
                    window.open('{! SaveAndNewButtonUrl }','_self');
                }else{
                    window.open('/' + sfId, '_self');
                }
            }
        }
        function UpdatePIToAWS(sobjJson, payloadForNewPI) {
            let controllerSaveMethod = config.updateMethod;
            let obj = JSON.parse(payloadForNewPI);
            obj[0].dataId = '{!AWSDataId}';
            let payloadForNewPIJson = JSON.stringify(obj);
            AWSService.update(staticResources.updateUrl, sobjJson, payloadForNewPIJson, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, false, insertOrUpdateBack,redirectCallBack);
        }
        function NewPIToAWS(sobjJson, payloadForNewPI) {
            let controllerSaveMethod = config.insertMethod;
            AWSService.insert(staticResources.newUrl, sobjJson, payloadForNewPI, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, true, insertOrUpdateBack,redirectCallBack);
        }
        function checkRequiredFieldMsg(formData) {
            let blankRequiredFields = '';
            for(i = 0;i<requiredFieldAPIList.length;i++){
                if(formData[requiredFieldAPIList[i]]){
                    continue;
                }else{
                    if(blankRequiredFields == ''){
                        blankRequiredFields =blankRequiredFields + fieldAPIToLabelMap[requiredFieldAPIList[i]];
                    }else{
                        blankRequiredFields =blankRequiredFields+',' + fieldAPIToLabelMap[requiredFieldAPIList[i]];
                    }
                }
            }
            return blankRequiredFields;
        }
        function saveSobjectProcess(save_and_new) {
            if(save_and_new){
                config.SaveAndNew = true;
            }
            hiddenErrorMsgNode();
            //1. Get Sobject Information from Form
            let sobjJson = getSobjectInformation();
            //2. Validate the Sobject field value formate, for example the email formate or phone formate
            let validationResultMessage = validateFieldValueFormate();
            console.log(validationResultMessage);
            if (validationResultMessage) {
                //Popup error message.  - To Do After POC
                alertErrorMessage(validationResultMessage);
                return
            }
            // Check Required Field
            let checkRequiredFieldMsgResult = checkRequiredFieldMsg(sobjJson);
            console.log('sobjJson:'+sobjJson);
            console.log('check:'+checkRequiredFieldMsgResult);
            if (checkRequiredFieldMsgResult) {
                alertErrorMessage('requiredErrorMsg' + checkRequiredFieldMsgResult);
                return
            }
            // //3. Prepare the payload for New PI API To AWS - To Do
            let payloadForNewPI = getPIPayload(sobjJson);
            // //4. Get Authentication Information for AWS
            // loadAWSAuthentication();
            // //5. lead to AWS
            ProcessPI(sobjJson, payloadForNewPI);
            // awsToken = TestToken;
            // NewPIToAWS(sobjJson,awsToken, payloadForNewPI)
        }
        function alertErrorMessage(errorMsg) {
            let errorMsgNode = document.getElementById("page:form:block:msgContent");
            errorMsgNode.innerText = errorMsg;
            errorMsgNode.className = 'pbError';
        }
        function hiddenErrorMsgNode() {
            let errorMsgNode = document.getElementById("page:form:block:msgContent");
            errorMsgNode.innerText = '';
            errorMsgNode.className = '';
        }
    </script>
    <div class="bPageTitle">
        <div class="ptBody">
            <div class="content">
                <img src="/img/s.gif" alt="{! SobjectLabel}" class="pageTitleIcon" title="{! SobjectLabel}" />
                <h1 class="pageType">{! SobjectLabel}<apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText>
                    <span class="titleSeparatingColon">:</span>
                </h1>
                <h2 class="pageDescription"> <apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText>{! SobjectLabel}</h2>
                <div class="blank">&nbsp;</div>
            </div>
            <div class="links">
                <a href="javascript:openPopupFocusEscapePounds(%27https://help.salesforce.com/apex/htdoor?loc=help&amp;target={!sobjectTypeValue}s_edit.htm&amp;section={!sobjectTypeValue}s&amp;language=zh_CN&amp;release=234.18.8&amp;instance=CS117&amp;showSplash=true%27, %27Help%27, 700, 600, %27width=700,height=600,resizable=yes,toolbar=yes,status=no,scrollbars=yes,menubar=yes,directories=no,location=no,dependant=no%27, false, false);"
                    title="此页面的帮助 (新窗口)">
                    <span class="helpLink">此页面的帮助</span>
                    <img src="/img/s.gif" alt="" class="helpIcon" />
                </a>
            </div>
        </div>
        <div class="ptBreadcrumb"></div>
    </div>
    <apex:form id="form">
        <apex:pageblock id="block">
            <div class="pbHeader">
                <table cellspacing="0" cellpadding="0" border="0">
                    <tbody>
                        <tr>
                            <td class="pbTitle">
                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />
                                <h2 class="mainTitle">{! SobjectLabel}<apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText></h2>
                            </td>
                            <td class="pbButton" id="topButtonRow">
                                <input class="btn" type="Button" value="{!$Label.Save}" onclick="saveSobjectProcess()" />
                                <input class="btn" type="Button" value="{!$Label.SaveAndNew}" onclick="saveSobjectProcess(1)" />
                                <apex:commandButton action="{!cancel}" value="{!$Label.Cancel}" />
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>
            <!-- Error Msg-->
            <div style="text-align: center;">
                <apex:outputPanel id="errorMsg">
                    <apex:pageMessages id="msgContent" escape="false" />
                </apex:outputPanel>
            </div>
            <!-- Iterate the layoutSections, which is a list of sections -->
            <apex:repeat value="{!layoutSections}" var="layoutSection">
                <apex:pageBlockSection title="{!layoutSection.name}" collapsible="{!layoutSection.allowCollapse}" columns="{!layoutSection.columns}">
                    <!--Each section has layoutFields, let's iterate them as well-->
                    <apex:repeat value="{!layoutSection.layoutFields}" var="layoutField">
                        <apex:inputField styleClass="{!ApiPrefix} {!ApiPrefix}_{!layoutField.fieldAPI}" html-data-id="{!layoutField.fieldAPI}" value="{!Inspection_Report__c[layoutField.fieldAPI]}" rendered="{!not(layoutField.isPlaceHOlder)}"
                            required="{!layoutField.isRequired}" />
                        <apex:pageblocksectionitem rendered="{!layoutField.isPlaceHolder}">
                        </apex:pageblocksectionitem>
                    </apex:repeat>
                </apex:pageBlockSection>
            </apex:repeat>
            <script>
                sfdcPage.appendToOnloadQueue(function () {
                    //1. Set Last Name label
                    //document.querySelector("[data-id='LastName']").parentNode.parentNode.parentNode.children[2].children[0].innerText = '姓名';
                    //2. Query AWS Data by dataId
                    console.log('Mode for Sobject Page:' + {!isNewMode});
                    if (!{!isNewMode}) {
                        blockme();
                        QuerySobjectFromAWS();
                    }
                });
            </script>
            <div class="pbBottomButtons">
                <table cellspacing="0" cellpadding="0" border="0">
                    <tbody>
                        <tr>
                            <td class="pbTitle">
                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />&nbsp;</td>
                            <td class="pbButtonb" id="bottomButtonRow">
                                <input class="btn" type="Button" value="{!$Label.Save}" onclick="saveSobjectProcess()" />
                                <input class="btn" type="Button" value="{!$Label.SaveAndNew}" onclick="saveSobjectProcess()" />
                                <apex:commandButton action="{!cancel}" value="{!$Label.Cancel}" />
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>
        </apex:pageblock>
    </apex:form>
</apex:page>
force-app/main/default/pages/NewAndEditInspectionReport.page-meta.xml
New file
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>53.0</apiVersion>
    <availableInTouch>false</availableInTouch>
    <confirmationTokenRequired>false</confirmationTokenRequired>
    <label>NewAndEditInspectionReport</label>
</ApexPage>
force-app/main/default/pages/NewAndEditLead.page
@@ -1,49 +1,55 @@
<apex:page standardController="Lead" extensions="NewAndEditLeadController">
<apex:page standardController="Lead" extensions="NewAndEditLeadController" id="page">
    <apex:stylesheet value="{!URLFOR($Resource.blockUIcss)}"/>
    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
    <apex:includeScript value="{!URLFOR($Resource.jquery183minjs)}"/>
    <apex:includeScript value="{!URLFOR($Resource.PleaseWaitDialog)}"/>
    <script src="../../soap/ajax/53.0/connection.js" type="text/javascript"></script>
    <style>
        .disabledbutton {
            pointer-events: none;
            opacity: 0.4;
        }
    </style>
    <script>
        var TestToken = 'eyJhbGciOiJIUzUxMiJ9.eyJjcmVhdGVkIjoxNjQzMDk5NDgyNjA2LCJhcHBpZCI6IjZMeml6Y1JmN2g4eUx4MjgiLCJleHAiOjE2NDM3MDQyODJ9.V_94zxiDwEa1jZpOphw9W4QfjmqqKQcjCZ4z31KsDe7SjCF9sxKSKiZe6rp8ML6-namlVSyzqpTeZQ6NJi88Og';
        var AWSAppId = '6LzizcRf7h8yLx28';
        var AWSAppSecret = 'UkLohQcHNjg164SdRc7gnS4rgu4d7FjINM3mtzRbyTS6IrUP5V';
        var NewLeadURL = 'https://52.83.101.205/api/lead/insert';
        var UpdateLeadURL = '';
        var QueryLeadURL = 'https://52.83.101.205/api/lead/query';
        var TransactionURL = "https://52.83.101.205/api/tx/confirm";
        AWSService.sfSessionId = '{!GETSESSIONID()}';
        var staticResources = JSON.parse('{!staticResource}');
        var staticResourcesContact = JSON.parse('{!staticResourceContact}');
        var requiredFieldAPIList = JSON.parse('{!requiredFieldAPIListStr}');
        var fieldAPIToLabelMap = JSON.parse('{!fieldAPIToLabelMapStr}');
        var redirectMode = 'Save';//1. Save 2. SaveAndNew
        var requiredAPIToChangedLabelMap = new Map();
        requiredAPIToChangedLabelMap.set('LastName', '{!PIPL_Name_Label}');
        console.log('{!contactsInfo}');
        var VLookUpFields = new Set(['Hospital_Name__c', 'Department_Class__c', 'Contact_Name__c', 'Campaign__c']);
        var LeadIdPage = "https://ocsm--stagefull--c.visualforce.com/apex/NewAndEditLead?RecordType=01210000000QiRa";
        // function ProcessPI(payloadForNewPI) {
        //     let TokenURL = "https://52.83.101.205/api/token/getToken?app_id=" + AWSAppId + "&app_secret=" + AWSAppSecret;
        //     console.log('Get Token Process');
        //     fetch(TokenURL, {
        //         method: 'GET',
        //         mode: 'no-cors',
        //         headers: {
        //             'Content-Type': 'application/json'
        //         }
        //     }).then((data) => {
        //         console.log(data.text())
        //         return data.text()
        //     }).then((awsToken) => {
        //         if({!isNewMode}){
        //             NewPIToAWS(awsToken, payloadForNewPI)
        //         }else{
        //             UpdatePIToAWS(awsToken, payloadForNewPI)
        //         }
        //     });
        // }
        function ProcessPI(leadJson, payloadForNewPI) {
            blockme();
            if ({!isNewMode}) {
            NewPIToAWS(leadJson, payloadForNewPI)
        }else {
            UpdatePIToAWS(leadJson, payloadForNewPI)
        }
        }
        function loadAWSAuthentication() {
            console.log('Get Sesion Session');
            sforce.connection.sessionId = '{!GETSESSIONID()}';
            let awsConfiguration = "SELECT App_Id__c,App_Secret__c,New_Lead_URL__c FROM AWS_Integration_Info__mdt  WHERE DeveloperName = 'AWS_Integration_Configuration'";
            let awsConfigurationResult = sforce.connection.query(awsConfiguration);
            let recordsAWSConfiguration = awsConfigurationResult.getArray("records");
            if (recordsAWSConfiguration && recordsAWSConfiguration.length > 0) {
                recordAWSConfiguration = recordsAWSConfiguration[0];
                AWSAppId = recordAWSConfiguration.App_Id__c;
                AWSAppSecret = recordAWSConfiguration.App_Secret__c;
                NewLeadURL = recordAWSConfiguration.New_Lead_URL__c;
        function enableButton(obj) {
            obj.classList.remove("btnDisabled");
        }
        function disableButton(obj) {
            obj.classList.add("btnDisabled");
        }
        function disableButtonStatus() {
            let btnList = document.getElementsByClassName('btn');
            for (let i = 0; i < btnList.length; i++) {
                disableButton(btnList[i]);
            }
            console.log('AWS Configuration:' + AWSAppId + '----- APP Secret:' + AWSAppSecret);
        }
        function enableButtonStatus() {
            let btnList = document.getElementsByClassName('btn');
            for (let i = 0; i < btnList.length; i++) {
                enableButton(btnList[i]);
            }
        }
        function getPIPayload(leadJson) {
@@ -63,44 +69,40 @@
        }
        function validateFieldValueFormate() {
            let error_msg = '';
            let textEmail = "[data-id='Email']";
            let textPhone = "[data-id='Phone']";
            //Email
            let email = document.querySelector(textEmail).value;
            let phone = document.querySelector(textPhone).value;
            let email = document.querySelector(textEmail);
            if(email.value!='' && !/^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.[a-zA-Z0-9]{2,6}$/.test(email.value)){
                error_msg += ';邮件格式错误';
            }
            let phone = document.querySelector(textPhone);
            let regEmail = /^[\w-]{3,12}@[\da-zA-Z]{2,6}\.[a-zA-Z]+$/;
            let regPhone = /^1[3|5|8|7][0-9]\d{4,8}$/;
            if(phone.value!='' && !/^1[3|5|8|7][0-9]\d{4,8}$/.test(phone.value)){
                error_msg += ';电话号码错误';
            }
            let emailFormate = regEmail.test(email);
            let phoneFormate = regPhone.test(phone);
            console.log(emailFormate);
            console.log(phoneFormate);
            email.oninput = function () {
                //email
                if (emailFormate) {
                    //phone
                    phone.oninput = function () {
                        if (phoneFormate) {
                            return true;
                        } else {
                            return false;
                        }
            for(let e of document.getElementsByTagName('select')){
                for(let op of e.options){
                    if(op.value == "*****" && op.selected){
                        error_msg += ';下拉框不能主动选择密文选项';
                    }
                } else {
                    return false;
                }
            }
            return true;
            if(error_msg.length>0 && error_msg[0]== ';'){
                error_msg = error_msg.substring(1);
            }
            return error_msg;
        }
        function getLeadInformation() {
            let nodelist = document.querySelectorAll("[data-id]");
            let result = {}
            result.RecordTypeId = '{!rtTypeId}';
            for (let index = 0; index < nodelist.length; index++) {
                if (VLookUpFields.has(nodelist[index].getAttribute("data-id"))) {
                    console.log(nodelist[index].id.indexOf('lkwgt'));
@@ -109,220 +111,214 @@
                        let vlookUpNodeValue = document.getElementById(vlookUpNodeId).value;
                        result[nodelist[index].getAttribute("data-id")] = vlookUpNodeValue;
                    }
                } else if (nodelist[index].type == 'checkbox') {
                    result[nodelist[index].getAttribute("data-id")] = nodelist[index].checked;
                } else if (nodelist[index].type == 'select-multiple') {
                    //nodelist[index].getAttribute("data-id")
                    let multiple = nodelist[index].getAttribute("data-id");
                    let targets = document.querySelector("[data-id=" + multiple + "]").parentNode.children[1].children[0].children[1].children[2].children[0].innerText;
                    targets = targets.replace(/\n/g, ";");
                    console.log('targets = ' + targets);
                    result[nodelist[index].getAttribute("data-id")] = targets;
                } else {
                    result[nodelist[index].getAttribute("data-id")] = nodelist[index].value;
                }
                let x = index + 1;
                if (x <= nodelist.length - 1 && (nodelist[x].getAttribute("data-id") == nodelist[index].getAttribute("data-id"))) {
                    index++;
                }
            }
            console.log(JSON.stringify(result));
            console.log('lead Number:' + result.Lead_No__c);
            let leadJson = JSON.stringify(result);
            let transId = "11111";
            let AWSDataId = "22222";
            // Visualforce.remoting.Manager.invokeAction(
            //     '{!$RemoteAction.NewAndEditLeadController.saveLead}',
            //     leadJson, transId,{!isNewMode},
            //     function (result, event) {
            //         console.log("result: " + result);
            //         window.open('/' + result.recordId, "_self");
            //     },
            //     { escape: true }
            // );
            return result;
            //第二种
            // let leadJson = {};
            // let fieldApiList = '{!fieldApiListStr}'.substring(1, '{!fieldApiListStr}'.length - 1).replace(/\"/g, "").split(',');
            // for (var i in fieldApiList) {
            //     if(document.querySelector("[data-id=\"" + fieldApiList[i] + "\"]") != null){
            //         leadJson[fieldApiList[i]] = document.querySelector("[data-id=\"" + fieldApiList[i] + "\"]").value;
            //     }else{
            //         leadJson[fieldApiList[i]] = '';
            //     }
            // }
            // return leadJson;
        }
        function QueryLeadFromAWS(awsDataId) {
            fetch(QueryLeadURL + '?dataId=' + awsDataId, {
                method: 'GET',
                headers: {
                    'Content-Type': 'application/json',
                    'pi_token': TestToken
                }
            }).then((data) => {
                console.log('data = ' + data);
                document.querySelector("[data-id='LastName']").value = data.object[0].lastName;
                document.querySelector("[data-id='phone']").value = data.object[0].phone;
                document.querySelector("[data-id='email']").value = data.object[0].email;
            })
        function QueryLeadFromAWS() {
            AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
        }
        function UpdatePIToAWS(awsToken, payloadForNewPI) {
            fetch(UpdateLeadURL, {
                method: 'POST',
                body: payloadForNewPI,
                headers: {
                    'Content-Type': 'application/json',
                    //'token': awsToken
        var queryBack = function queryBack(data) {
            console.log('data = ' + data);
            document.querySelector("[data-id='LastName']").value = data.object.lastName.replace(/"/g,"");
            document.querySelector("[data-id='Phone']").value = data.object.phone.replace(/"/g,"");
            document.querySelector("[data-id='Email']").value = data.object.email.replace(/"/g,"");
            unblockUI();
        };
        var insertOrUpdateBack = function insertOrUpdateBack(payloadJson, result, isNewMode) {
            console.log(result);
            let r = result;
            console.log('Result from AWS' + r);
            console.log('payloadJson=' + payloadJson);
            payloadJson.LastName = r.object[0].lastName;
            payloadJson.Phone = r.object[0].phone;
            payloadJson.Email = r.object[0].email;
            payloadJson.Name_Encrypted__c = r.object[0].lastNameEncrypt;
            payloadJson.Phone_Encrypted__c = r.object[0].phoneEncrypt;
            payloadJson.Email_Encrypted__c = r.object[0].emailEncrypt;
            //payloadJson.AWS_Data_Id__c = r.object[0].dataId;
            payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
            if (isNewMode) {
                payloadJson.AWS_Data_Id__c = r.object[0].dataId;
            } else {
                payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
            }
            return payloadJson;
        }
        var redirectCallBack = function redirectCallBack(sfId, errorMessage) {
            if (sfId) {
                if (redirectMode == 'Save') {
                    window.open('/' + sfId, '_self');
                } else if (redirectMode == 'SaveAndNew') {
                    window.open('/setup/ui/recordtypeselect.jsp?ent=' + '{!sobjecttypeForFrontEnd}' + '&retURL=/' + '{!sobjectPrefix}' + '/o&save_new_url=/' + '{!sobjectPrefix}' + '/e?retURL=%2F' + '{!sobjectPrefix}' + '%2Fo', '_self');
                }
            }).then((data) => { return data.json() }).then((result) => {
                let r = JSON.parse(result);
                console.log('Result from AWS' + r);
                leadJson.lastName = r.object[0].lastName;
                leadJson.phone = r.object[0].phone;
                leadJson.email = r.object[0].email;
                leadJson.Name_Encrypted__c = r.object[0].lastNameEncrypt;
                leadJson.Phone_Encrypted__c = r.object[0].phoneEncrypt;
                leadJson.Email_Encrypted__c = r.object[0].emailEncrypt;
                leadJson.AWS_Data_Id__c = '{!AWSDataId}';
                let transId = result.txId;
                let AWSDataId = r.object[0].dataId;
            } else {
                // alert(errorMessage);
                alertErrorMessage(errorMessage);
            }
        }
                // Assign the value to NonPII Data Payload
                //7. New NonPII Data To Salesforce
                Visualforce.remoting.Manager.invokeAction(
                    '{!$RemoteAction.NewAndEditLeadController.saveLead}',
                    leadJson, transId, {!isNewMode},
                function (result, event) {
                    if (event.status) {
                        if (result.stauts == 'success') {
                            //get Lead Id from sf backend
                            let leadId = result.recordId;
                            //8. Confirm Trans to AWS
                            transParameters = {
                                txId: transId,
                                isSuccess: event.status
                            };
                            fetch(TransactionURL, {
                                method: 'POST',
                                body: JSON.stringify(transParameters),
                                headers: {
                                    'Content-Type': 'application/json',
                                    // 'token': awsToken
                                }
                            }).then((result) => {
                                if (JSON.parse(result).status == 0) {
                                    //9. Redirect to lead Id page.
                                    window.location.href = LeadIdPage;
                                    // let data = {
                                    //     transId:result.txId,
                                    //     dataId:dataId,
                                    //     status:result.status
                                    // }
                                    // return JSON.stringify(data);
                                }
                            })
                            // window.open(LeadIdPage);
                            // console.log(result);
                            // window.location.href = LeadIdPage;
                        } else {
                            //result.stauts == 'fail'
                        }
        function UpdatePIToAWS(leadJson, payloadForNewPI) {
            let controllerSaveMethod = '{!$RemoteAction.NewAndEditLeadController.saveLead}';
            let obj = JSON.parse(payloadForNewPI);
            obj[0].dataId = '{!AWSDataId}';
            let payloadForNewPIJson = JSON.stringify(obj);
            AWSService.update(staticResources.updateUrl, leadJson, payloadForNewPIJson, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, false, insertOrUpdateBack, redirectCallBack);
        }
        function NewPIToAWS(leadJson, payloadForNewPI) {
            let controllerSaveMethod = '{!$RemoteAction.NewAndEditLeadController.saveLead}';
            AWSService.insert(staticResources.newUrl, leadJson, payloadForNewPI, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, true, insertOrUpdateBack, redirectCallBack);
        }
        function checkRequiredFieldMsg(formData) {
            let blankRequiredFields = '';
            for (i = 0; i < requiredFieldAPIList.length; i++) {
                if (formData[requiredFieldAPIList[i]]) {
                    continue;
                } else {
                    let fieldAPIValue = requiredFieldAPIList[i]
                    let fieldLabelValue = fieldAPIToLabelMap[fieldAPIValue];
                    if (requiredAPIToChangedLabelMap.has(fieldAPIValue)) {
                        fieldLabelValue = requiredAPIToChangedLabelMap.get(fieldAPIValue);
                    }
                },
                { escape: true }
            );
        }).catch (error => {
            console.log(error);
        });
        }
        function NewPIToAWS(leadJson,awsToken, payloadForNewPI) {
            console.log('Process New PI Data');
            console.log(JSON.stringify(payloadForNewPI));
            fetch(NewLeadURL, {
                method: 'POST',
                body: payloadForNewPI,
                headers: {
                    'Content-Type': 'application/json',
                    'pi_token': awsToken
                }
            }).then((data) => { console.log('data='+data);return data.json() }).then((result) => {
                console.log(result);
                let r = result;
                console.log('Result from AWS' + r);
                console.log('leadJson='+leadJson);
                leadJson.lastName = r.object[0].lastName;
                leadJson.phone = r.object[0].phone;
                leadJson.email = r.object[0].email;
                leadJson.Name_Encrypted__c = r.object[0].lastNameEncrypt;
                leadJson.Phone_Encrypted__c = r.object[0].phoneEncrypt;
                leadJson.Email_Encrypted__c = r.object[0].emailEncrypt;
                leadJson.AWS_Data_Id__c = 'testAWSID';
                let transId = result.txId + '';
                let AWSDataId = r.object[0].dataId;
                // Assign the value to NonPII Data Payload
                //7. New NonPII Data To Salesforce
                Visualforce.remoting.Manager.invokeAction(
                    '{!$RemoteAction.NewAndEditLeadController.saveLead}',
                    JSON.stringify(leadJson), transId, {!isNewMode},
                function (result, event) {
                    if (event.status) {
                        console.log('Lead Id from SF Backend:'+JSON.stringify(result));
                        if (result.status == 'success') {
                            //get Lead Id from sf backend
                            let leadId = result.recordId;
                            window.open('/'+leadId,'_self');
                            //8. Confirm Trans to AWS
                            // transParameters = {
                            //     txId: transId,
                            //     isSuccess: result.status
                            // };
                            // fetch(TransactionURL, {
                            //     method: 'POST',
                            //     body: JSON.stringify(transParameters),
                            //     headers: {
                            //         'Content-Type': 'application/json',
                            //         'pi_token': TestToken
                            //     }
                            // }).then((result) => {
                            //     if (JSON.parse(result).status == 0) {
                            //         //9. Redirect to lead Id page.
                            //         window.location.href = LeadIdPage;
                            //         // let data = {
                            //         //     transId:result.txId,
                            //         //     dataId:dataId,
                            //         //     status:result.status
                            //         // }
                            //         // return JSON.stringify(data);
                            //     }
                            // })
                            // window.open(LeadIdPage);
                            // console.log(result);
                            // window.location.href = LeadIdPage;
                        } else {
                            //result.stauts == 'fail'
                        }
                    if (blankRequiredFields == '') {
                        blankRequiredFields = blankRequiredFields + fieldLabelValue;
                    } else {
                        blankRequiredFields = blankRequiredFields + ',' + fieldLabelValue;
                    }
                },
                { escape: true }
            );
        }).catch (error => {
            console.log(error);
        });
                }
            }
            return blankRequiredFields;
        }
        function saveLeadProcess() {
        function saveLeadProcess(saveMode) {
            disableButtonStatus();
            redirectMode = saveMode;
            console.log('redirectMode' + redirectMode);
            hiddenErrorMsgNode();
            //1. Get Lead Information from Form
            let leadJson = getLeadInformation();
            //2. Validate the Lead field value formate, for example the email formate or phone formate
            // let validationResultMessage = validateFieldValueFormate();
            // console.log(validationResultMessage);
            // if (!validationResultMessage) {
            //     //Popup error message.  - To Do After POC
            //     alert('邮箱或电话号码格式有误');
            // }
            // //3. Prepare the payload for New PI API To AWS - To Do
            let validationResultMessage = validateFieldValueFormate();
            console.log(validationResultMessage);
            if (validationResultMessage) {
                //Popup error message.  - To Do After POC
                alertErrorMessage(validationResultMessage);
                return
            }
            // Check Required Field
            let checkRequiredFieldMsgResult = checkRequiredFieldMsg(leadJson);
            if (checkRequiredFieldMsgResult) {
                alertErrorMessage('{!Input_Required_Field_Msg}' + checkRequiredFieldMsgResult);
                return
            }
            //3. Prepare the payload for New PI API To AWS - To Do
            let payloadForNewPI = getPIPayload(leadJson);
            // //4. Get Authentication Information for AWS
            // loadAWSAuthentication();
            //4. lead to AWS
            ProcessPI(leadJson, payloadForNewPI);
        }
            // //5. lead to AWS
            //ProcessPI(payloadForNewPI);
            awsToken = TestToken;
            NewPIToAWS(leadJson,awsToken, payloadForNewPI)
        function alertErrorMessage(errorMsg) {
            enableButtonStatus();
            let errorMsgNode = document.getElementById("page:form:block:msgContent");
            errorMsg = '错误:无效数据。' + '\n' + errorMsg;
            errorMsgNode.innerText = errorMsg;
            errorMsgNode.className = 'pbError';
            unblockUI();
        }
        function hiddenErrorMsgNode() {
            let errorMsgNode = document.getElementById("page:form:block:msgContent");
            errorMsgNode.innerText = '';
            errorMsgNode.className = '';
        }
        var newSearchContactWindow = null;
        var contactHtmlString = '<img src="/img/s.gif" onclick="searchContact(\'page:form:contactId\')" alt="Reference Document Number Lookup" class="lookupIcon"  title="Reference Document Number Lookup (New Window)"/>';
        function htmlToElement(html) {
            var template = document.createElement('template');
            html = html.trim(); // Never return a text node of whitespace as the result
            template.innerHTML = html;
            return template.content.firstChild;
        }
        function searchContact(contactNodeId) {
            //1. Check account value
            let accountNodeId = document.querySelector("[data-id='Hospital_Name__c']").id + '_lkid';
            let accountValue = document.getElementById(accountNodeId).value;
            console.log(accountValue);
            if (accountValue != '000000000000000') {
                let baseUrl = "/apex/SearchContactPage";
                let suffixUrl = "?contactId=" + contactNodeId + "&accountId=" + accountValue;
                let newSearchContactParam = 'height=600,width=800,left=100,top=100,dialogHide=true,resizable=no,scrollbars=yes,toolbar=no,status=no';
                newSearchContactWindow = window.open(baseUrl + suffixUrl, 'Popup', newSearchContactParam);
                if (window.focus) {
                    newSearchContactWindow.focus();
                }
                return false;
            } else {
                //alertErrorMessage('{!PIPL_Input_Account_Error_Msg}');
                alertErrorMessage('请先选择医院名');
            }
        }
        function closePopupWindow() {
            if (null != newSearchContactWindow) {
                newSearchContactWindow.close();
            }
            let contactInfoStr = document.getElementById('page:form:contactId').value;
            console.log('closePopup:' + contactInfoStr);
            let contactInfo = JSON.parse(contactInfoStr);
            let contactNodeId = document.querySelector("[data-id='Contact_Name__c']").id + '_lkid';
            document.getElementById(contactNodeId).value = contactInfo.ContactId;
            document.querySelector("[data-id='Contact_Name__c']").value = contactInfo.Name;
        }
        function replaceSearchContactLookup() {
            let lookUpNode = htmlToElement(contactHtmlString);
            console.log(lookUpNode);
            if (!{!isNewMode}) {
                //1. Query Contact from AWS by AWSDataId
                queryContactName()
                //document.querySelector("[data-id='Contact_Name__c']").value = '王奎';
            }
            let parentNode = document.querySelector("[data-id='Contact_Name__c']").parentNode;
            document.querySelector("[data-id='Contact_Name__c']").removeAttribute("onchange");
            parentNode.replaceChild(lookUpNode, document.querySelector("[data-id='Contact_Name__c']").parentNode.children[2]);
        }
        function queryContactName() {
            let sfId = document.getElementById(document.querySelector("[data-id='Contact_Name__c']").id + '_lkid').value;
            let contactsInfo = JSON.parse('{!contactsInfo}');
            let dataId = contactsInfo[sfId];
            let url = staticResourcesContact.queryUrl + '?dataId=' + dataId;
            fetch(url, {
                method: 'GET',
                headers: {
                    'Content-Type': 'application/json',
                    'pi-token': staticResources.token
                }
            }).then((data) => {
                return data.json();
            }).then((result) => {
                document.querySelector("[data-id='Contact_Name__c']").value = result.object.lastName;
            })
        }
    </script>
    <div class="bPageTitle">
@@ -345,10 +341,9 @@
        </div>
        <div class="ptBreadcrumb"></div>
    </div>
    <apex:form >
        <!-- Error Msg-->
        <apex:pageMessages />
        <apex:pageblock >
    <apex:form id="form">
        <apex:inputHidden value="{!contactId}" id="contactId" />
        <apex:pageblock id="block">
            <div class="pbHeader">
                <table cellspacing="0" cellpadding="0" border="0">
                    <tbody>
@@ -358,17 +353,25 @@
                                <h2 class="mainTitle">意向编辑</h2>
                            </td>
                            <td class="pbButton" id="topButtonRow">
                                <input class="btn" type="Button" value="保存" onclick="saveLeadProcess()" />
                                <input class="btn" type="Button" value="保存并新建" onclick="saveLeadProcess()" />
                                <input class="btn" type="Button" value="保存" onclick="saveLeadProcess('Save')" />
                                <input class="btn" type="Button" value="保存并新建" onclick="saveLeadProcess('SaveAndNew')" />
                                <apex:commandButton action="{!cancel}" value="取消" />
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>
            <!-- Error Msg-->
            <div style="text-align: center;">
                <apex:outputPanel id="errorMsg">
                    <apex:pageMessages id="msgContent" escape="false" />
                </apex:outputPanel>
            </div>
            <br/>
            <!-- Iterate the layoutSections, which is a list of sections -->
            <apex:repeat value="{!layoutSections}" var="layoutSection">
                <apex:pageBlockSection title="{!layoutSection.name}" collapsible="{!layoutSection.allowCollapse}" columns="{!layoutSection.columns}">
                <apex:pageBlockSection title="{!layoutSection.name}" showHeader="{!layoutSection.useHeader}" collapsible="{!layoutSection.allowCollapse}"
                    columns="{!layoutSection.columns}">
                    <!--Each section has layoutFields, let's iterate them as well-->
                    <apex:repeat value="{!layoutSection.layoutFields}" var="layoutField">
@@ -383,15 +386,18 @@
            <script>
                sfdcPage.appendToOnloadQueue(function () {
                    //1. Set Last Name label
                    document.querySelector("[data-id='LastName']").parentNode.parentNode.parentNode.children[2].children[0].innerText = '姓名';
                    console.log('NameLabel = ' + '{!PIPL_Name_Label}')
                    document.querySelector("[data-id='LastName']").parentNode.parentNode.parentNode.children[0].children[0].innerText = '{!PIPL_Name_Label}';
                    //2. Query AWS Data by dataId 
                    console.log('Mode for Lead Page:' + {!isNewMode});
                if (!{!isNewMode}) {
                    //2.1. Query AWS Data by
                    let leadPIData = QueryLeadFromAWS({!awsDataId});
                        //2.2. Update the value to Front-End
                        //document.querySelector("[data-id='LastName']").value = '234234';
                    }
                    if (!{!isNewMode}) {
                        blockme();//for loading search by Li Jun 20220218
                        QueryLeadFromAWS();
                    }
                    //Replace Vlookup Field
                    replaceSearchContactLookup();
                    //3. Set Readonly Attribute
                    document.querySelector("[data-id='OwnerId']").classList.add("disabledbutton");
                });
            </script>
            <div class="pbBottomButtons">
@@ -400,9 +406,9 @@
                        <tr>
                            <td class="pbTitle">
                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />&nbsp;</td>
                            <td class="pbButtonb" id="bottomButtonRow">
                                <input class="btn" type="Button" value="保存" onclick="saveLeadProcess()" />
                                <input class="btn" type="Button" value="保存并新建" onclick="saveLeadProcess()" />
                            <td class="pbButton" id="bottomButtonRow">
                                <input class="btn" type="Button" value="保存" onclick="saveLeadProcess('Save')" />
                                <input class="btn" type="Button" value="保存并新建" onclick="saveLeadProcess('SaveAndNew')" />
                                <apex:commandButton action="{!cancel}" value="取消" />
                            </td>
                        </tr>
force-app/main/default/pages/NewAndEditQIS.page
New file
@@ -0,0 +1,558 @@
<apex:page standardController="QIS_Report__c" extensions="NewAndEditQISController" id="page">
    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
    <script src="../../soap/ajax/53.0/connection.js" type="text/javascript"></script>
    <apex:stylesheet value="{!URLFOR($Resource.blockUIcss)}"/>
    <apex:includeScript value="{!URLFOR($Resource.jquery183minjs)}"/>
    <apex:includeScript value="{!URLFOR($Resource.PleaseWaitDialog)}"/>
    <script>
        var config = {};
        config = {
            SobjectName : "{!SobjectName}",
            ApiPrefix:"{!ApiPrefix}",
            SaveAndNew:false,
            AWSToSobjectMap:{!AWSToSobjectMapJson},
            AWSToSobjectNonEncryptedMap:{!AWSToSobjectNonEncryptedMapJson},
            AWSToSobjectNonEncryptedMapKeySet:{!AWSToSobjectNonEncryptedMapKeySet},
            AWSToSobjectEncryptedMap:{!AWSToSobjectEncryptedMapJson},
            SobjectToAWSModel:function (sobjJson) {
                let leadPayloadList = [];
                let leadPIData = {};
                for(let f in config.AWSToSobjectMap){
                    if(sobjJson.hasOwnProperty(config.AWSToSobjectMap[f])){
                        leadPIData[f] = sobjJson[config.AWSToSobjectMap[f]]
                    }
                    else{
                        console.log(config.AWSToSobjectMap[f] + 'is not in sobjJson');
                    }
                }
                leadPIData.medicalStaffFullName = leadPIData.lastName;// 完成field update workflow
                leadPIData.sfRecordId = '';
                console.log('Sobject PI Data:' + leadPIData);
                leadPayloadList.push(leadPIData);
                console.log(JSON.stringify(leadPayloadList));
                return JSON.stringify(leadPayloadList);
            },
            insertOrUpdateBack:function(payloadJson, r, isNewMode){
                for(let f in config.AWSToSobjectMap){
                    if(r.object[0].hasOwnProperty(f)){
                        payloadJson[config.AWSToSobjectMap[f]] = r.object[0][f];
                    }
                    else{
                        console.log(f + 'is not in r.object[0]');
                    }
                }
                for(let f in config.AWSToSobjectEncryptedMap){
                    if(r.object[0].hasOwnProperty(f)){
                        payloadJson[config.AWSToSobjectEncryptedMap[f]] = r.object[0][f];
                    }
                    else{
                        console.log(f + 'is not in r.object[0]');
                    }
                }
                //payloadJson.AWS_Data_Id__c = r.object[0].dataId;
                payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
                if (isNewMode) {
                    payloadJson.AWS_Data_Id__c = r.object[0].dataId;
                } else {
                    payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
                }
                return payloadJson;
            },
            queryBack:function (data) {
                console.log('data = ' + data);
                if(data.object){
                    for(let f of config.AWSToSobjectNonEncryptedMapKeySet){
                        let ele = document.getElementById(api_id_map[config.AWSToSobjectNonEncryptedMap[f]])
                        if(data.object.hasOwnProperty(f) && ele){
                            // 多选特殊处理
                            if(ele.type == 'select-multiple'){
                               //let me = GetEleByClass(config.ApiPrefix+'_'+field_api_name);
                               if(ele && data.object[f]){
                                   let arr = data.object[f].split(';');
                                   // 给隐藏的select赋值
                                   for(let op of ele.options){
                                       op.selected = arr.indexOf(op.value)>-1;
                                   }
                                   // 利用按钮给显示的select赋值
                                   let ra = document.getElementById(ele.id + '_right_arrow');
                                   if(ra){
                                       ra.click();
                                   }
                               }
                            }else{
                                ele.value = data.object[f];
                            }
                            if(ele.type.indexOf("select")>-1 && ele.value){
                                jQuery(ele).change()
                            }
                        }
                        else{
                            console.log(f + 'is not in data.object');
                        }
                    }
                }
                else{
                    console.log('data.object = ' + data.object);
                }
                // document.querySelector("[data-id='LastName']").value = data.object.lastName;
                // document.querySelector("[data-id='Phone']").value = data.object.phone;
                // document.querySelector("[data-id='Email']").value = data.object.email;
            },
            updateMethod:"NewAndEditQISController.saveQISReport",
            insertMethod:"NewAndEditQISController.saveQISReport"
        }
        AWSService.sfSessionId = '{!GETSESSIONID()}';
        var staticResources = JSON.parse('{!staticResource}');
        var requiredFieldAPIList = JSON.parse('{!requiredFieldAPIListStr}');
        var fieldAPIToLabelMap = JSON.parse('{!fieldAPIToLabelMapStr}');
        console.log('{!staticResource}');
        var VLookUpFields = {! VLookUpFieldsJson};
        function ProcessPI(sobjJson, payloadForNewPI) {
            blockme();
            if ({!isNewMode}) {
                NewPIToAWS(sobjJson, payloadForNewPI)
            }else {
                UpdatePIToAWS(sobjJson, payloadForNewPI)
            }
        }
        var GetEleByClass = function(class_name){
            let eles = document.getElementsByClassName(class_name);
            if(eles.length > 0) return eles[0];
            return null;
        }
        var GetEleApiName = function(ele){
            for(let c of ele.classList){
                if(c.indexOf(config.ApiPrefix+'_')>-1){
                    return c.replace(config.ApiPrefix+'_','');
                }
            }
            return '';
        }
        function IsFormTag(tag_name){
            return ['input','select','textarea'].indexOf(tag_name.toLowerCase())>-1;
        }
        function IsFormElement(e){
            return IsFormTag(e.tagName);
        }
        function getPIPayload(sobjJson) {
            return config.SobjectToAWSModel(sobjJson);
        }
        function validateFieldValueFormate() {
            let error_msg = '';
            //let textEmail = "[data-id='Email']";
            let textPhone = "[data-id='Caller_phone__c']";
            //Email
            // let email = document.querySelector(textEmail);
            // if(email && !/^[\w-]{3,12}@[\da-zA-Z]{2,16}\.[a-zA-Z]+$/.test(email.value)){
            //     error_msg += ';邮件格式错误';
            // }
            let phone = document.querySelector(textPhone);
            if(phone && !/^1[3|5|8|7][0-9]\d{4,8}$/.test(phone.value)){
                error_msg += ';电话号码错误';
            }
            for(let e of document.getElementsByTagName('select')){
                for(let op of e.options){
                    if(op.value == "*****" && op.selected){
                        error_msg += ';下拉框不能主动选择密文选项';
                    }
                }
            }
            if(error_msg.length>0 && error_msg[0]== ';'){
                error_msg = error_msg.substring(1);
            }
            return error_msg;
        }
        function getSobjectInformation() {
            //api_id_map
//let nodelist = document.getElementsByClassName(config.ApiPrefix);
            let result = {}
            for (let index in api_id_map) {
                let ele = document.getElementById(api_id_map[index]);
                let field_api_name = index;
                let tag_name = ele.tagName.toLowerCase();
                if(!IsFormTag(tag_name)){
                    console.log('tag_name='+tag_name+',field_api_name'+field_api_name+' is not a form element');
                    continue;
                }
                if (VLookUpFields.indexOf(field_api_name)>=0) {
                    console.log(ele.id.indexOf('lkwgt'));
                    if (ele.id.indexOf('lkwgt') == -1) {
                        let vlookUpNodeId = ele.id + '_lkid';
                        let vlook_ele = document.getElementById(vlookUpNodeId);
                        let v = '';
                        if(vlook_ele){
                            v = vlook_ele.value;
                        }else{
                            v = ele.value;
                        }
                        if(v && v != "000000000000000"){
                            result[field_api_name] = v;
                        }
                    }
                } else if (ele.type == 'checkbox') {
                    result[field_api_name] = ele.checked;
                } else if (ele.type == 'select-multiple') {
                    //field_api_name
                    let multiple = field_api_name;
                    let targets = GetEleByClass(config.ApiPrefix+'_'+field_api_name).parentNode.children[1].children[0].children[1].children[2].children[0].innerText;
                    targets = targets.replace(/\n/g, ";");
                    console.log('targets = ' + targets);
                    result[field_api_name] = targets;
                } else {
                    result[field_api_name] = ele.value;
                }
                // let e1 = document.getElementById(api_id_map[field_api_name]);
                // if(!result[field_api_name] && e1 && e1.value){
                //     result[field_api_name] = e1.value;
                // }
            }
            //赋值富文本区域
            //问题内容描述(图片)-FSE-OCSM-OSH
            if(document.querySelector("[title = 'RTF 編輯器, page:form:block:j_id50:4:j_id51:j_id52:15:j_id53:textAreaDelegate_problem_detail_photo__c']")){
                result.problem_detail_photo__c = document.querySelector("[title = 'RTF 編輯器, page:form:block:j_id50:4:j_id51:j_id52:15:j_id53:textAreaDelegate_problem_detail_photo__c']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
            }
            //问题内容描述(图片)-OSH回答完毕-现场结案-final
            if(document.querySelector("[title = 'RTF 編輯器, page:form:block:j_id50:5:j_id51:j_id52:15:j_id53:textAreaDelegate_problem_detail_photo__c']")){
                result.problem_detail_photo__c = document.querySelector("[title = 'RTF 編輯器, page:form:block:j_id50:5:j_id51:j_id52:15:j_id53:textAreaDelegate_problem_detail_photo__c']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
            }
            //照片1 - OCSM-现场结案-final
            if(document.querySelector("[title = 'RTF 編輯器, page:form:block:j_id50:14:j_id51:j_id52:0:j_id53:textAreaDelegate_problem_detail_photo__c']")){
                result.Photo_1__c = document.querySelector("[title = 'RTF 編輯器, page:form:block:j_id50:14:j_id51:j_id52:0:j_id53:textAreaDelegate_problem_detail_photo__c']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
            }
            //照片2-OCSM-现场结案-final
            if(document.querySelector("[title = 'RTF 編輯器, page:form:block:j_id50:14:j_id51:j_id52:1:j_id53:textAreaDelegate_problem_detail_photo__c']")){
                result.Photo_2__c = document.querySelector("[title = 'RTF 編輯器, page:form:block:j_id50:14:j_id51:j_id52:1:j_id53:textAreaDelegate_problem_detail_photo__c']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
            }
            //照片3 -OCSM-现场结案-final
            if(document.querySelector("[title = 'RTF 編輯器, page:form:block:j_id50:14:j_id51:j_id52:2:j_id53:textAreaDelegate_problem_detail_photo__c']")){
                result.Photo_3__c = document.querySelector("[title = 'RTF 編輯器, page:form:block:j_id50:14:j_id51:j_id52:2:j_id53:textAreaDelegate_problem_detail_photo__c']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
            }
            //照片4 -OCSM-现场结案-final
            if(document.querySelector("[title = 'RTF 編輯器, page:form:block:j_id50:14:j_id51:j_id52:3:j_id53:textAreaDelegate_problem_detail_photo__c']")){
                result.Photo_4__c = document.querySelector("[title = 'RTF 編輯器, page:form:block:j_id50:14:j_id51:j_id52:3:j_id53:textAreaDelegate_problem_detail_photo__c']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
            }
            //照片OSH1 - OCSM
             if(document.querySelector("[title = 'RTF 編輯器, page:form:block:j_id50:19:j_id51:j_id52:0:j_id53:textAreaDelegate_problem_detail_photo__c']")){
                result.Photo_OSH_1__c = document.querySelector("[title = 'RTF 編輯器, page:form:block:j_id50:19:j_id51:j_id52:0:j_id53:textAreaDelegate_problem_detail_photo__c']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
            }
            //照片OSH2-OCSM
            if(document.querySelector("[title = 'RTF 編輯器, page:form:block:j_id50:19:j_id51:j_id52:1:j_id53:textAreaDelegate_problem_detail_photo__c']")){
                result.Photo_OSH_2__c = document.querySelector("[title = 'RTF 編輯器, page:form:block:j_id50:19:j_id51:j_id52:1:j_id53:textAreaDelegate_problem_detail_photo__c']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
            }
            //照片OSH3 -OCSM
            if(document.querySelector("[title = 'RTF 編輯器, page:form:block:j_id50:19:j_id51:j_id52:2:j_id53:textAreaDelegate_problem_detail_photo__c']")){
                result.Photo_OSH_3__c = document.querySelector("[title = 'RTF 編輯器, page:form:block:j_id50:19:j_id51:j_id52:2:j_id53:textAreaDelegate_problem_detail_photo__c']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
            }
            //照片OSH4 -OCSM
            if(document.querySelector("[title = 'RTF 編輯器, page:form:block:j_id50:19:j_id51:j_id52:3:j_id53:textAreaDelegate_problem_detail_photo__c']")){
                result.Photo_OSH_4__c = document.querySelector("[title = 'RTF 編輯器, page:form:block:j_id50:19:j_id51:j_id52:3:j_id53:textAreaDelegate_problem_detail_photo__c']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
            }
            //照片OSH1 - OSH回答完毕
            if(document.querySelector("[title = 'RTF 編輯器, page:form:block:j_id50:18:j_id51:j_id52:0:j_id53:textAreaDelegate_problem_detail_photo__c']")){
                result.Photo_OSH_1__c = document.querySelector("[title = 'RTF 編輯器, page:form:block:j_id50:18:j_id51:j_id52:0:j_id53:textAreaDelegate_problem_detail_photo__c']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
            }
            //照片OSH2-OSH回答完毕
            if(document.querySelector("[title = 'RTF 編輯器, page:form:block:j_id50:18:j_id51:j_id52:1:j_id53:textAreaDelegate_problem_detail_photo__c']")){
                result.Photo_OSH_2__c = document.querySelector("[title = 'RTF 編輯器, page:form:block:j_id50:18:j_id51:j_id52:1:j_id53:textAreaDelegate_problem_detail_photo__c']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
            }
            //照片OSH3 -OSH回答完毕
            if(document.querySelector("[title = 'RTF 編輯器, page:form:block:j_id50:18:j_id51:j_id52:2:j_id53:textAreaDelegate_problem_detail_photo__c']")){
                result.Photo_OSH_3__c = document.querySelector("[title = 'RTF 編輯器, page:form:block:j_id50:18:j_id51:j_id52:2:j_id53:textAreaDelegate_problem_detail_photo__c']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
            }
            //照片OSH4 -OSH回答完毕
            if(document.querySelector("[title = 'RTF 編輯器, page:form:block:j_id50:18:j_id51:j_id52:3:j_id53:textAreaDelegate_problem_detail_photo__c']")){
                result.Photo_OSH_4__c = document.querySelector("[title = 'RTF 編輯器, page:form:block:j_id50:18:j_id51:j_id52:3:j_id53:textAreaDelegate_problem_detail_photo__c']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
            }
            //照片1 - OSH
            if(document.querySelector("[title = 'RTF 編輯器, page:form:block:j_id50:13:j_id51:j_id52:0:j_id53:textAreaDelegate_problem_detail_photo__c']")){
                result.Photo_1__c = document.querySelector("[title = 'RTF 編輯器, page:form:block:j_id50:13:j_id51:j_id52:0:j_id53:textAreaDelegate_problem_detail_photo__c']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
            }
            //照片2-OSH
            if(document.querySelector("[title = 'RTF 編輯器, page:form:block:j_id50:13:j_id51:j_id52:1:j_id53:textAreaDelegate_problem_detail_photo__c']")){
                result.Photo_2__c = document.querySelector("[title = 'RTF 編輯器, page:form:block:j_id50:13:j_id51:j_id52:1:j_id53:textAreaDelegate_problem_detail_photo__c']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
            }
            //照片3 -OSH
            if(document.querySelector("[title = 'RTF 編輯器, page:form:block:j_id50:13:j_id51:j_id52:2:j_id53:textAreaDelegate_problem_detail_photo__c']")){
                result.Photo_3__c = document.querySelector("[title = 'RTF 編輯器, page:form:block:j_id50:13:j_id51:j_id52:2:j_id53:textAreaDelegate_problem_detail_photo__c']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
            }
            //照片4 -OSH
            if(document.querySelector("[title = 'RTF 編輯器, page:form:block:j_id50:13:j_id51:j_id52:3:j_id53:textAreaDelegate_problem_detail_photo__c']")){
                result.Photo_4__c = document.querySelector("[title = 'RTF 編輯器, page:form:block:j_id50:13:j_id51:j_id52:3:j_id53:textAreaDelegate_problem_detail_photo__c']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
            }
            //照片OSH1 - OSH
            if(document.querySelector("[title = 'RTF 編輯器, page:form:block:j_id50:16:j_id51:j_id52:0:j_id53:textAreaDelegate_problem_detail_photo__c']")){
                result.Photo_OSH_1__c = document.querySelector("[title = 'RTF 編輯器, page:form:block:j_id50:16:j_id51:j_id52:0:j_id53:textAreaDelegate_problem_detail_photo__c']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
            }
            //照片OSH2-OSH
            if(document.querySelector("[title = 'RTF 編輯器, page:form:block:j_id50:16:j_id51:j_id52:1:j_id53:textAreaDelegate_problem_detail_photo__c']")){
                result.Photo_OSH_2__c = document.querySelector("[title = 'RTF 編輯器, page:form:block:j_id50:16:j_id51:j_id52:1:j_id53:textAreaDelegate_problem_detail_photo__c']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
            }
            //照片OSH3 -OSH
            if(document.querySelector("[title = 'RTF 編輯器, page:form:block:j_id50:16:j_id51:j_id52:2:j_id53:textAreaDelegate_problem_detail_photo__c']")){
                result.Photo_OSH_3__c = document.querySelector("[title = 'RTF 編輯器, page:form:block:j_id50:16:j_id51:j_id52:2:j_id53:textAreaDelegate_problem_detail_photo__c']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
            }
            //照片OSH4 -OSH
            if(document.querySelector("[title = 'RTF 編輯器, page:form:block:j_id50:16:j_id51:j_id52:3:j_id53:textAreaDelegate_problem_detail_photo__c']")){
                result.Photo_OSH_4__c = document.querySelector("[title = 'RTF 編輯器, page:form:block:j_id50:16:j_id51:j_id52:3:j_id53:textAreaDelegate_problem_detail_photo__c']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
            }
            //照片OSH1 -现场结案-final
            if(document.querySelector("[title = 'RTF 編輯器, page:form:block:j_id50:17:j_id51:j_id52:0:j_id53:textAreaDelegate_problem_detail_photo__c']")){
                result.Photo_OSH_1__c = document.querySelector("[title = 'RTF 編輯器, page:form:block:j_id50:17:j_id51:j_id52:0:j_id53:textAreaDelegate_problem_detail_photo__c']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
            }
            //照片OSH2-现场结案-final
            if(document.querySelector("[title = 'RTF 編輯器, page:form:block:j_id50:17:j_id51:j_id52:1:j_id53:textAreaDelegate_problem_detail_photo__c']")){
                result.Photo_OSH_2__c = document.querySelector("[title = 'RTF 編輯器, page:form:block:j_id50:17:j_id51:j_id52:1:j_id53:textAreaDelegate_problem_detail_photo__c']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
            }
            //照片OSH3 -现场结案-final
            if(document.querySelector("[title = 'RTF 編輯器, page:form:block:j_id50:17:j_id51:j_id52:2:j_id53:textAreaDelegate_problem_detail_photo__c']")){
                result.Photo_OSH_3__c = document.querySelector("[title = 'RTF 編輯器, page:form:block:j_id50:17:j_id51:j_id52:2:j_id53:textAreaDelegate_problem_detail_photo__c']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
            }
            //照片OSH4 -现场结案-final
            if(document.querySelector("[title = 'RTF 編輯器, page:form:block:j_id50:17:j_id51:j_id52:3:j_id53:textAreaDelegate_problem_detail_photo__c']")){
                result.Photo_OSH_4__c = document.querySelector("[title = 'RTF 編輯器, page:form:block:j_id50:17:j_id51:j_id52:3:j_id53:textAreaDelegate_problem_detail_photo__c']").contentWindow.document.getElementsByTagName('body')[0].innerHTML
            }
            return result;
        }
        function QuerySobjectFromAWS() {
            AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
        }
        function queryBack(data) {
            console.log('data = ' + data);
            config.queryBack(data);
            unblockUI();
        };
        function insertOrUpdateBack(payloadJson, result, isNewMode) {
            console.log(result);
            let r = result;
            console.log('Result from AWS' + r);
            console.log('payloadJson=' + payloadJson);
            return config.insertOrUpdateBack(payloadJson, r, isNewMode);
        }
        function redirectCallBack(sfId,errorMsg) {
            unblockUI();
            if(errorMsg){
                alertErrorMessage(errorMsg);
            }
            else{
                if(config.SaveAndNew){
                    window.open('{! SaveAndNewButtonUrl }','_self');
                }else{
                    window.open('/' + sfId, '_self');
                }
            }
        }
        function UpdatePIToAWS(sobjJson, payloadForNewPI) {
            let controllerSaveMethod = config.updateMethod;
            let obj = JSON.parse(payloadForNewPI);
            obj[0].dataId = '{!AWSDataId}';
            let payloadForNewPIJson = JSON.stringify(obj);
            AWSService.update(staticResources.updateUrl, sobjJson, payloadForNewPIJson, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, false, insertOrUpdateBack,redirectCallBack);
        }
        function NewPIToAWS(sobjJson, payloadForNewPI) {
            let controllerSaveMethod = config.insertMethod;
            AWSService.insert(staticResources.newUrl, sobjJson, payloadForNewPI, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, true, insertOrUpdateBack,redirectCallBack);
        }
        function checkRequiredFieldMsg(formData) {
            let blankRequiredFields = '';
            for(i = 0;i<requiredFieldAPIList.length;i++){
                if(formData[requiredFieldAPIList[i]]){
                    continue;
                }else{
                    if(blankRequiredFields == ''){
                        blankRequiredFields =blankRequiredFields + fieldAPIToLabelMap[requiredFieldAPIList[i]];
                    }else{
                        blankRequiredFields =blankRequiredFields+',' + fieldAPIToLabelMap[requiredFieldAPIList[i]];
                    }
                }
            }
            return blankRequiredFields;
        }
        function saveSobjectProcess(save_and_new) {
            if(save_and_new){
                config.SaveAndNew = true;
            }
            hiddenErrorMsgNode();
            //1. Get Sobject Information from Form
            let sobjJson = getSobjectInformation();
            //2. Validate the Sobject field value formate, for example the email formate or phone formate
            let validationResultMessage = validateFieldValueFormate();
            console.log(validationResultMessage);
            if (validationResultMessage) {
                //Popup error message.  - To Do After POC
                alertErrorMessage(validationResultMessage);
                return
            }
            // Check Required Field
            let checkRequiredFieldMsgResult = checkRequiredFieldMsg(sobjJson);
            if (checkRequiredFieldMsgResult) {
                alertErrorMessage('requiredErrorMsg' + checkRequiredFieldMsgResult);
                return
            }
            // //3. Prepare the payload for New PI API To AWS - To Do
            let payloadForNewPI = getPIPayload(sobjJson);
            // //4. Get Authentication Information for AWS
            // loadAWSAuthentication();
            // //5. lead to AWS
            ProcessPI(sobjJson, payloadForNewPI);
            // awsToken = TestToken;
            // NewPIToAWS(sobjJson,awsToken, payloadForNewPI)
        }
        function alertErrorMessage(errorMsg) {
            let errorMsgNode = document.getElementById("page:form:block:msgContent");
            errorMsgNode.innerText = errorMsg;
            errorMsgNode.className = 'pbError';
        }
        function hiddenErrorMsgNode() {
            let errorMsgNode = document.getElementById("page:form:block:msgContent");
            errorMsgNode.innerText = '';
            errorMsgNode.className = '';
        }
    </script>
    <div class="bPageTitle">
        <div class="ptBody">
            <div class="content">
                <img src="/img/s.gif" alt="{! SobjectLabel}" class="pageTitleIcon" title="{! SobjectLabel}" />
                <h1 class="pageType">{! SobjectLabel}<apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText>
                    <span class="titleSeparatingColon">:</span>
                </h1>
                <h2 class="pageDescription"> <apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText>{! SobjectLabel}</h2>
                <div class="blank">&nbsp;</div>
            </div>
            <div class="links">
                <a href="javascript:openPopupFocusEscapePounds(%27https://help.salesforce.com/apex/htdoor?loc=help&amp;target={!sobjectTypeValue}s_edit.htm&amp;section={!sobjectTypeValue}s&amp;language=zh_CN&amp;release=234.18.8&amp;instance=CS117&amp;showSplash=true%27, %27Help%27, 700, 600, %27width=700,height=600,resizable=yes,toolbar=yes,status=no,scrollbars=yes,menubar=yes,directories=no,location=no,dependant=no%27, false, false);"
                    title="此页面的帮助 (新窗口)">
                    <span class="helpLink">此页面的帮助</span>
                    <img src="/img/s.gif" alt="" class="helpIcon" />
                </a>
            </div>
        </div>
        <div class="ptBreadcrumb"></div>
    </div>
    <apex:form id="form">
        <apex:pageblock id="block">
            <div class="pbHeader">
                <table cellspacing="0" cellpadding="0" border="0">
                    <tbody>
                        <tr>
                            <td class="pbTitle">
                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />
                                <h2 class="mainTitle">{! SobjectLabel}<apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText></h2>
                            </td>
                            <td class="pbButton" id="topButtonRow">
                                <input class="btn" type="Button" value="{!$Label.Save}" onclick="saveSobjectProcess()" />
                                <input class="btn" type="Button" value="{!$Label.SaveAndNew}" onclick="saveSobjectProcess(1)" />
                                <apex:commandButton action="{!cancel}" value="{!$Label.Cancel}" />
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>
            <!-- Error Msg-->
            <div style="text-align: center;">
                <apex:outputPanel id="errorMsg">
                    <apex:pageMessages id="msgContent" escape="false" />
                </apex:outputPanel>
            </div>
            <!-- Iterate the layoutSections, which is a list of sections -->
            <apex:repeat value="{!layoutSections}" var="layoutSection">
                <apex:pageBlockSection title="{!layoutSection.name}" collapsible="{!layoutSection.allowCollapse}" columns="{!layoutSection.columns}">
                    <!--Each section has layoutFields, let's iterate them as well-->
                    <apex:repeat value="{!layoutSection.layoutFields}" var="layoutField">
                        <apex:inputField styleClass="{!ApiPrefix} {!ApiPrefix}_{!layoutField.fieldAPI}" html-data-id="{!layoutField.fieldAPI}" value="{!QIS_Report__c[layoutField.fieldAPI]}" rendered="{!not(layoutField.isPlaceHOlder)}"
                                         required="{!layoutField.isRequired}" />
                        <apex:pageblocksectionitem rendered="{!layoutField.isPlaceHolder}">
                        </apex:pageblocksectionitem>
                    </apex:repeat>
                </apex:pageBlockSection>
            </apex:repeat>
            <script>
            var init_nodes = document.getElementsByClassName("PIBackApi");
            var api_id_map={};
            for(let e of init_nodes){
                if(IsFormElement(e)){
                     api_id_map[GetEleApiName(e)] = e.id;
                }
            }
            console.log(api_id_map);
            sfdcPage.appendToOnloadQueue(function () {
                //1. Set Last Name label
                //document.querySelector("[data-id='LastName']").parentNode.parentNode.parentNode.children[2].children[0].innerText = '姓名';
                //2. Query AWS Data by dataId
                console.log('Mode for Sobject Page:' + {!isNewMode});
                if (!{!isNewMode}) {
                    blockme();
                    QuerySobjectFromAWS();
                }
            });
            </script>
            <div class="pbBottomButtons">
                <table cellspacing="0" cellpadding="0" border="0">
                    <tbody>
                        <tr>
                            <td class="pbTitle">
                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />&nbsp;</td>
                            <td class="pbButtonb" id="bottomButtonRow">
                                <input class="btn" type="Button" value="{!$Label.Save}" onclick="saveSobjectProcess()" />
                                <input class="btn" type="Button" value="{!$Label.SaveAndNew}" onclick="saveSobjectProcess()" />
                                <apex:commandButton action="{!cancel}" value="{!$Label.Cancel}" />
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>
        </apex:pageblock>
    </apex:form>
</apex:page>
Diff truncated after the above file
force-app/main/default/pages/NewAndEditQIS.page-meta.xml force-app/main/default/pages/NewAndEditRepairSubOrder.page force-app/main/default/pages/NewAndEditRepairSubOrder.page-meta.xml force-app/main/default/pages/NewAndEditReport.page force-app/main/default/pages/NewAndEditReport.page-meta.xml force-app/main/default/pages/NewAndEditTenderinformation.page force-app/main/default/pages/NewAndEditTenderinformation.page-meta.xml force-app/main/default/pages/NewConsumApply.page force-app/main/default/pages/NewConsumApply.page-meta.xml force-app/main/default/pages/NewConsumApplyEquipmentSetDetail.page force-app/main/default/pages/NewConsumApplyEquipmentSetDetail.page-meta.xml force-app/main/default/pages/NewListOfConsumables.page force-app/main/default/pages/NewListOfConsumables.page-meta.xml force-app/main/default/pages/NewOnCall.page force-app/main/default/pages/NewOnCall.page-meta.xml force-app/main/default/pages/NewRentalApply.page force-app/main/default/pages/NewRentalApply.page-meta.xml force-app/main/default/pages/NewRepair.page force-app/main/default/pages/NewRepair.page-meta.xml force-app/main/default/pages/NewRepairPage.page force-app/main/default/pages/NewRepairPage.page-meta.xml force-app/main/default/pages/OFSInsReportLayout.page force-app/main/default/pages/QISPDF.page force-app/main/default/pages/RentalApplyUploadPdf.page force-app/main/default/pages/RentalApplyUploadPdf.page-meta.xml force-app/main/default/pages/SLAReportDetails.page force-app/main/default/pages/SearchContactPage.page force-app/main/default/pages/SearchContactPage.page-meta.xml force-app/main/default/pages/SearchLeadPage.page force-app/main/default/pages/SearchLeadPage.page-meta.xml force-app/main/default/pages/SearchVisitor.page force-app/main/default/pages/SimpleEventRegister.page force-app/main/default/pages/StartTrading.page force-app/main/default/pages/StraightBackAddress.page force-app/main/default/pages/TenderInformationUploadPdf.page force-app/main/default/pages/TenderInformationUploadPdf.page-meta.xml force-app/main/default/pages/TestClass.page force-app/main/default/pages/TestClass.page-meta.xml force-app/main/default/pages/TestVfPage.page force-app/main/default/pages/TestVfPage.page-meta.xml force-app/main/default/pages/UploadPdf.page force-app/main/default/pages/UploadPdf.page-meta.xml force-app/main/default/pages/ViewASEActivityDecryptInfo.page force-app/main/default/pages/ViewASEActivityDecryptInfo.page-meta.xml force-app/main/default/pages/ViewAddressDecryptInfo.page force-app/main/default/pages/ViewAddressDecryptInfo.page-meta.xml force-app/main/default/pages/ViewAgencyContactDecryptInfo.page force-app/main/default/pages/ViewAgencyContactDecryptInfo.page-meta.xml force-app/main/default/pages/ViewCaseDecryptInfo.page force-app/main/default/pages/ViewCaseDecryptInfo.page-meta.xml force-app/main/default/pages/ViewConsumApplyEquipmentSetDetailDecrypt.page force-app/main/default/pages/ViewConsumApplyEquipmentSetDetailDecrypt.page-meta.xml force-app/main/default/pages/ViewContactDecryptInfo.page force-app/main/default/pages/ViewContactDecryptInfo.page-meta.xml force-app/main/default/pages/ViewDecryptConsumApply.page force-app/main/default/pages/ViewDecryptConsumApply.page-meta.xml force-app/main/default/pages/ViewEventDecryptInfo.page force-app/main/default/pages/ViewEventDecryptInfo.page-meta.xml force-app/main/default/pages/ViewInquiryFormDecryptInfo.page force-app/main/default/pages/ViewInquiryFormDecryptInfo.page-meta.xml force-app/main/default/pages/ViewInspectionReportDecryptInfo.page force-app/main/default/pages/ViewInspectionReportDecryptInfo.page-meta.xml force-app/main/default/pages/ViewLeadDecryptInfo.page force-app/main/default/pages/ViewLeadDecryptInfo.page-meta.xml force-app/main/default/pages/ViewListOfConsumablesDecrypt.page force-app/main/default/pages/ViewListOfConsumablesDecrypt.page-meta.xml force-app/main/default/pages/ViewOnCallDecrypt.page force-app/main/default/pages/ViewOnCallDecrypt.page-meta.xml force-app/main/default/pages/ViewParticipantsDecryptInfo.page force-app/main/default/pages/ViewParticipantsDecryptInfo.page-meta.xml force-app/main/default/pages/ViewQISReportDecryptInfo.page force-app/main/default/pages/ViewQISReportDecryptInfo.page-meta.xml force-app/main/default/pages/ViewRentalApplyDecrypt.page force-app/main/default/pages/ViewRentalApplyDecrypt.page-meta.xml force-app/main/default/pages/ViewRepairEncrypt.page force-app/main/default/pages/ViewRepairEncrypt.page-meta.xml force-app/main/default/pages/ViewRepairSubOrderDecryptInfo.page force-app/main/default/pages/ViewRepairSubOrderDecryptInfo.page-meta.xml force-app/main/default/pages/ViewReportDecryptInfo.page force-app/main/default/pages/ViewReportDecryptInfo.page-meta.xml force-app/main/default/pages/ViewTenderinformationDecryptInfo.page force-app/main/default/pages/ViewTenderinformationDecryptInfo.page-meta.xml force-app/main/default/pages/XinDailyReport.page force-app/main/default/triggers/ContactHpDeptUpd.trigger force-app/main/default/triggers/FileAddressTrigger.trigger force-app/main/default/triggers/FileAddressTrigger.trigger-meta.xml force-app/main/default/triggers/Repair.trigger