FieldSet第二篇 - 动态查询优化

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/itsme_web/article/details/82592937

前言】:
在早前,我们已经分享过"在salesforce中使用FieldSet实例",该实例覆盖了fieldSet在detail页面及List列表页的实际应用,那么本篇我们将介绍如何基于fieldSet的字段做动态查询。

场景描述】:
同一个role下的A/B两个user创建的Lead可以互相共享记录,那被共享人仅仅只能看到部分字段,由于其他原因我们最终使用fieldSet来进行可配置化开发。由于Lead detail页面是通过访问list页面中的超链接显示的,因此我们使用了visualforce tab来代替标准的Lead Tab。

代码示例】:
1. Lead List Page:

<apex:page id="thePage" standardController="Lead" recordSetVar="leads" tabStyle="Lead">
    <apex:includeScript value="{!$Resource.cryptoJs}"/>
    <style>
        div[id*=linkPanel] {
            text-align: center;
            padding-top: 7px;
        }
    </style>
    <apex:form id="theForm">
        <!-- Section Header -->
        <apex:sectionHeader title="Leads" subtitle="Home"/>
        <!-- Filter Section -->
        <apex:panelGrid columns="2">
            <apex:outputLabel value="View:" style="font-weight: bold;"/>
            <apex:selectList value="{!filterId}" size="1">
                <apex:actionSupport event="onchange" rerender="theForm"/>
                <apex:selectOptions value="{!listviewoptions}"/>
            </apex:selectList>
        </apex:panelGrid>
        <!-- Data List Section -->
        <apex:pageBlock id="theBlock" title="Leads">
            <!-- New Button -->
            <apex:pageBlockButtons location="top">
                <apex:commandButton value="New" onclick="navigateToUrl('/setup/ui/recordtypeselect.jsp?ent=Lead&retURL=%2F00Q%2Fo&save_new_url=%2F00Q%2Fe%3FretURL%3D%252F00Q%252Fo',null,'new');return false;"/>
            </apex:pageBlockButtons>
            <!-- Data Table -->
            <apex:outputPanel rendered="{! NOT(ISBLANK(leads))}">
                <apex:pageBlockTable id="theTable" value="{!leads}" var="ld">
                    <apex:column headerValue="Name">
                        <apex:outputLink value="javascript:navigateToDetail('{! $label.privateKey}', '{! $label.initializationVector}', '{!ld.Id}')">{!ld.Name}</apex:outputLink>
                        <!--<apex:outputLink value="/apex/LeadPage?id={!ld.Id}">{!ld.Name}</apex:outputLink>-->
                    </apex:column>
                    <apex:column headerValue="Company" value="{!ld.Company}" />
                    <apex:column headerValue="Email" value="{!ld.Email}" />
                    <apex:column headerValue="Lead Status" value="{!ld.Status}" />
                    <apex:column headerValue="Lead Source" value="{!ld.LeadSource}" />
                    <apex:column headerValue="Country" value="{!ld.Country}" />
                    <apex:column headerValue="State/Province" value="{!ld.State}" />
                </apex:pageBlockTable>
                <!-- Page Info -->
                <apex:outputPanel id="linkPanel" layout="block">
                    <!-- Previous Page -->  
                    <!-- active -->  
                    <apex:commandLink action="{! Previous}" value="« Previous" reRender="theForm" rendered="{! HasPrevious}" /> 
                    <apex:outputText style="color:#ccc;" value="« Previous" rendered="{! NOT(HasPrevious)}" />  
                    <!-- Next Page --> 
                    &nbsp;&nbsp; 
                    <!-- active -->  
                    <apex:commandLink action="{! Next}" value="Next »" reRender="theForm" rendered="{! HasNext}" />  
                    <apex:outputText style="color: #ccc;" value="Next »" rendered="{! NOT(HasNext)}" /> 
                    <!-- Page X of Y -->  
                    <apex:outputText style="float: right;" value="{! PageNumber}/{! CEILING(ResultSize / PageSize)}" />
                </apex:outputPanel>
            </apex:outputPanel>
            <apex:outputPanel rendered="{! ISBLANK(leads)}">
                No records to display.
            </apex:outputPanel>
        </apex:pageBlock>
    </apex:form> 
    <script type="text/javascript">
    	function navigateToDetail(key, iv, data) {
            var url = '/apex/LeadPage?param=';
        	var key = CryptoJS.enc.Utf8.parse(key);
            var iv = CryptoJS.enc.Utf8.parse(iv);
            var srcs = CryptoJS.enc.Utf8.parse(data);
            var encrypted = CryptoJS.AES.encrypt(srcs, key, {
                iv: iv,
                mode:CryptoJS.mode.CBC,
                padding:CryptoJS.pad.Pkcs7
            });
            url += encodeURIComponent(encrypted.toString());
            window.location.href = url;
        }
    </script>
</apex:page>

2. 下面我们来看Lead detail页面的逻辑和自定义页面:

/*
 * Fields controlled by fls
 */
public class LeadController {
    public final Lead lead {get;set;}
    public Boolean isSameRole {get;set;}
    public Boolean isSameUser {get;set;}
    public static String loginUserRole = UserInfo.getUserRoleId();
    public static String loginUser = UserInfo.getUserId();
    
    public LeadController() {
        String param = ApexPages.currentPage().getParameters().get('param');
        System.debug('param: ' + param);
        String recId = CryptoUtil.decryptData(param, 'decrypt');
        System.debug('decryptedResult: ' + recId);

        String query = 'SELECT ';
        for(Schema.FieldSetMember f : SObjectType.Lead.FieldSets.Lead_Field_Set.getFields()) {
            query += f.getFieldPath() + ', ';
        }
        query = query.toLowerCase().contains('ownerid') ? query.left(query.length() - 2) : query + 'OwnerId';
        query += ' FROM Lead WHERE Id = \''+ recId +'\'';
        System.debug('query: ' + query);
        this.lead = Database.query(query);
        System.debug('lead: ' + lead);
        
        String recordRole = [SELECT UserRoleId FROM User WHERE Id = :lead.OwnerId LIMIT 1].UserRoleId;

        // if the login user and the record user is in the same role level, the login user cannot edit record.
        isSameRole = loginUserRole.equals(recordRole);
        isSameUser = loginUser.equals(lead.OwnerId);
        System.debug('isSameRole: ' + isSameRole);
        System.debug('isSameUser: ' + isSameUser);
    }
}
<apex:page controller="LeadController" tabStyle="Lead">
    <apex:detail subject="{!Lead.Id}" relatedList="true" title="true" inlineEdit="true" showChatter="true" rendered="{! OR(Not(isSameRole), isSameUser)}"/>
    <apex:outputPanel id="viewWrap" rendered="{! AND(isSameRole, !isSameUser)}">
    	<apex:sectionHeader title="Lead" subtitle="{! lead.Name}"/>
        <apex:pageBlock title="View Shared Lead" mode="detail">
        	<apex:pageBlockSection columns="2">
                <apex:repeat value="{!$ObjectType.Lead.FieldSets.Lead_Field_Set}" var="f">
                    <apex:outputField value="{!Lead[f]}"/>
                </apex:repeat>
            </apex:pageBlockSection>
        </apex:pageBlock>
    </apex:outputPanel>
</apex:page>

总结与归纳】:
1. 在detail页面controller里面,ownerId是必须的,我们不确定用户是否会添加OwnerId,所以此处做了校验;重复会报错
查询FieldSet中的字段模板:

public static List<String> getFieldsByFieldSet() {
	List<String> fields = new List<String>();
	for(Schema.FieldSetMember f : SObjectType.Lead.FieldSets.Lead_Field_Set.getFields()) {
		fields.add(f.getFieldPath());
	}
	return fields;
}

参考资料】:FieldSet Class

猜你喜欢

转载自blog.csdn.net/itsme_web/article/details/82592937