如何在Salesforce上搭建一个全球疫情排行榜?

基于Salesforce LWC的全球疫情排行榜

今天我们来尝试在Salesforce上搭建一个‘全球疫情全球疫情趋势列表(排行榜)’,方便一些企业特别是外企能够在Salesforce内实时查看全球疫情趋势。

效果

废话不多说,先来看看效果。主页君将其发布在Salesforce Community 上,大家可以看看

https://trailhead-cn-developer-edition.na112.force.com/s/covid-19-list-01

也可以直接放在Salesforce主页(Home Page)上,有了这个,一些跨国企业可以在Salesforce主页上展示给员工该列表,这样员工每一次登入Salesforce就可以直接查看不同国家的新增确诊案例。

然后我们具体来看看怎么做。

首先,我们的思路是,在Salesforce后台通过实时API拿到全球疫情数据,然后,通过LWC前端展现出来,并且利用官方的一些模块化组建如lightning-datatable,将数据展现给用户。

其次我们需要解决数据源的问题,如何拿到全球确诊准确实时的数据是非常关键。我们可以调用Postman的一个API,直接Get就可以了,API End Point为https://api.covid19api.com/summary

之后我们需要分析接口,拿到的数据是分到‘国家’,并且显示了‘新增确诊’,‘累积确诊’等数据,如美国的情况,我们可以将其直接转换到lightning-datatable的格式。

1
2
3
4
5
6
7
8
9
10
11
12
{
"Country": "United States of America",
"CountryCode": "US",
"Slug": "united-states",
"NewConfirmed": 32129,
"TotalConfirmed": 275582,
"NewDeaths": 1161,
"TotalDeaths": 7087,
"NewRecovered": 0,
"TotalRecovered": 0,
"Date": "2020-04-05T06:37:00Z"
}

关于API的其他参考资料,大家可以参考Postman的文档:
https://documenter.getpostman.com/view/10808728/SzS8rjbc?version=latest

然后我们可以在Apex Class,通过HttpRequest 调用其API。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public without sharing class Covid19TrackerController {

@AuraEnabled(continuation=true cacheable = true)
public static Map<String, Object> getCov19Data(){
Map<String, Object> results = new Map<String, Object> ();
Http http = new Http();
HttpRequest request = new HttpRequest();
request.setEndpoint('https://api.covid19api.com/summary');
request.setMethod('GET');
HttpResponse response = http.send(request);
// If the request is successful, parse the JSON response.
if (response.getStatusCode() == 200) {
// Deserialize the JSON string into collections of primitive data types.
results = (Map<String, Object>) JSON.deserializeUntyped(response.getBody());
}

return results;
}

}

关于Call out的文章,大家可以参考:https://trailhead.salesforce.com/en/content/learn/modules/apex_integration_services/apex_integration_rest_callouts

需要注意的是,这里需要把这个API放入Remote Site Setting 里面

然后新建一个LWC 的component,名字为 :covid19TrackerCompt

在covid19TrackerCompt.html利用lightning-datatable把数据展示出来

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<template>
<template if:true={showSpinner}>
<lightning-layout class="slds-m-top_medium slds-m-bottom_small">
<lightning-spinner alternative-text="Loading"></lightning-spinner>
</lightning-layout>
</template>
<lightning-card title="新型冠状病毒全球排行榜" icon-name="standard:announcement">
<lightning-datatable
key-field="id"
data={data} show-row-number-column
columns={columns}
sorted-by={sortBy}
sorted-direction={sortDirection}
onsort={handleSortdata}
hide-checkbox-column=true>
</lightning-datatable>
</lightning-card>
<img src={FooterLogoUrl} style="display: block; margin: 0 auto;" >
</template>

关于lightning-datatable的官方帮助文档,大家可以参考
https://developer.salesforce.com/docs/component-library/bundle/lightning-datatable/example

接下来,在 covid19TrackerCompt.js上,拿Covid19TrackerController里面的全球个案数据。注意,由于这里我们使用官方的lightning-datatable,所以是没有排序功能的,所以要自己写,可以参见 sortData(fieldname, direction),每一次点击‘新增确诊’,然后调用handleSortdata(event),从而实现datatable的排序功能。

同时,我们给每一个国家加上一个状态,如果这个国家没有死亡病例,那么就是绿色,有死亡病例就是红色,可以通过TotalDeaths 来判断。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
import { LightningElement, track, api, wire } from 'lwc';
import getCovidData from '@salesforce/apexContinuation/Covid19TrackerController.getCov19Data';
import WechatPublicLogo_1 from '@salesforce/resourceUrl/WechatPublicLogo_1';

// Summary Table columns
const columns = [
{
label: '国家',
fieldName: 'Country',
type: 'text',
sortable: "true",
cellAttributes: { class: { fieldName: 'covidStatus' } }
}, {
label: '新增确诊',
fieldName: 'NewConfirmed',
type: 'number',
sortable: "true",
cellAttributes: { class: { fieldName: 'covidStatus' } }
}, {
label: '累积确诊',
fieldName: 'TotalConfirmed',
type: 'number',
sortable: "true",
cellAttributes: { class: { fieldName: 'covidStatus' } }
}, {
label: '新增死亡',
fieldName: 'NewDeaths',
type: 'number',
sortable: "true",
cellAttributes: { class: { fieldName: 'covidStatus' } }
}, {
label: '累积死亡',
fieldName: 'TotalDeaths',
type: 'number',
sortable: "true",
cellAttributes: { class: { fieldName: 'covidStatus' } }
}, {
label: '新增治愈',
fieldName: 'NewRecovered',
type: 'number',
sortable: "true",
cellAttributes: { class: { fieldName: 'covidStatus' } }
}, {
label: '累积治愈',
fieldName: 'TotalRecovered',
type: 'number',
sortable: "true",
cellAttributes: { class: { fieldName: 'covidStatus' } }
}
];

export default class Covid19TrackerCompt extends LightningElement {
// Expose the static resource URL for use in the template
FooterLogoUrl = WechatPublicLogo_1;

@track data = [];
@track showSpinner = true;
@track Initialized = false;
@track columns = columns;
@track sortDirection;
@track sortBy;

//connectedCallback() { }
renderedCallback() {
console.log('enter renderedCallback');

getCovidData().then(data => {
if (this.Initialized) {
return;
}
this.Initialized = true;

console.log('***getCovidData1.0 **');
console.log(data.Global);
this.data = [];
for (let i = 0; i < data.Countries.length; i++) {
let covidStatusVal = 'slds-text-color_success';
if (data.Countries[i].TotalDeaths > 0) {
covidStatusVal = 'slds-text-color_error'; //error color code to display if total deaths > 0
}

var row = {
id: data.Countries[i].Country,
Country: data.Countries[i].Country,
NewConfirmed: data.Countries[i].NewConfirmed,
TotalConfirmed: data.Countries[i].TotalConfirmed,
NewDeaths: data.Countries[i].NewDeaths,
TotalDeaths: data.Countries[i].TotalDeaths,
NewRecovered: data.Countries[i].NewRecovered,
TotalRecovered: data.Countries[i].TotalRecovered,
covidStatus: covidStatusVal
}
//console.log(row);
this.data.push(row);
}
console.log('Done');
this.showSpinner = false;
this.sortData('NewConfirmed', 'desc');

}).catch(error => {
console.log(' ** error ** ');
console.log(error);
});
}


//sorting methods
handleSortdata(event) {
this.showSpinner = true;
// field name
this.sortBy = event.detail.fieldName;
// sort direction
this.sortDirection = event.detail.sortDirection;
console.log('fieldName : '+event.detail.fieldName + ' sortDirection : ' + event.detail.sortDirection);
// calling sortdata function to sort the data based on direction and selected field
this.sortData(event.detail.fieldName, event.detail.sortDirection);
}

sortData(fieldname, direction) {
// serialize the data before calling sort function
let parseData = JSON.parse(JSON.stringify(this.data));
// Return the value stored in the field
let keyValue = (a) => {
return a[fieldname];
};
// cheking reverse direction
let isReverse = direction === 'asc' ? 1 : -1;
// sorting data
parseData.sort((x, y) => {
x = keyValue(x) ? keyValue(x) : ''; // handling null values
y = keyValue(y) ? keyValue(y) : '';

// sorting values based on direction
return isReverse * ((x > y) - (y > x));
});
// set the sorted data to data table data
this.data = parseData;
this.showSpinner = false;
}
}

最后,covid19TrackerCompt.js-meta.xml写为:

1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="urn:metadata.tooling.soap.sforce.com" fqn="covid19TrackerCompt">
<apiVersion>48.0</apiVersion>
<isExposed>true</isExposed>
<targets>
<target>lightning__AppPage</target>
<target>lightning__RecordPage</target>
<target>lightning__HomePage</target>
<target>lightningCommunity__Page</target>
<target>lightningCommunity__Default</target>
</targets>
</LightningComponentBundle>

怎么样,要不你也试试?