# 2021.12.31 - 小计

明天就是元旦了,新的一年即将来临。

最近都在搞产品性能优化,还了好多技术债务。

产品的表单有一个组织项目筛选项,用的是建模的自定义多级下拉框,它会把集团、区域、公司、项目按照层级结构展示出来,本来一切都很完美,但是当数据量到达一定级别后,下拉框卡死,页面挂掉了。于是就来活了,我要负责将组织下拉框这块性能问题搞定。咱们建模内置的一个标准控件,其实也就是筛选项,做过大量优化,支持数据懒加载。但是自定义的多级下拉框啥都不支持。

把突破点放到标准的筛选项控件上,让建模对外提供这个组件,然后由决策平台进行一层简单的封装,产品这边提供数据源。模拟标准控件的功能解决这个该死的性能问题。

看看建模平台业务组件,他有一些属性及事件可以调用。

<title>基础用法</title>
<describe>项目控件的基础用法</describe>
<template>
    <hc-project-select source="标准项目过滤" filter-type="LeafProject,LeafCompany" display-type="Company,Project" @change="change"></hc-project-select>
</template>
<script>
export default {
  data: function() {
    return {

    }
  },
  methods:{
      change(e){
          console.log(e)
      }
  }
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

进行简单的封装:

<div class="project-select-main" v-if='isPropsValidator'>
    <hc-project-select class="private-project-select"
    :display-type="displayType"
    :filter-type="filterType"
    @change="change"
    :source="source"
    ref="projectSelect"></hc-project-select>
</div>
1
2
3
4
5
6
7
8

module.exports = {
    props:{
        source: String,
        filterTypeList: Array,
        displayTypeList: Array,
        elementCode: String
    },
    data: function() {
        return {
            isPropsValidator: true,
            value: ''
        }
    },
    computed: {
        filterType: function() {
            var me = this
            return me.filterTypeList.join(',')
        },
        displayType: function() {
            var me = this
            return me.displayTypeList.join(',')
        }
    },
    created: function() {
        this._propsValidator()
    },
    mounted: function() {
        
    },
    methods: {
        change: function(item) {
            if(!this.value) {
                this.value = item
                this.$emit('mounted', item)
            } else {
                this.value = item
                this.$emit('changed', item)
            }
        },
        setValue: function (value) {
            this.$refs.projectSelect.setValue(value)
        },
        getValue: function () {
            return this.value
        },
        getText: function () {
            return this.$refs.projectSelect.getText()
        },
        getElementCode: function() {
            if(this.elementCode && this.value && this.value.item && this.value.item.extData && this.value.item.extData[this.elementCode]) {
                return this.value.item.extData[this.elementCode]
            } else {
                return ''
            }
        },
        _propsValidator: function() {
            if(!this.filterType || !this.displayType) {
                this.isPropsValidator = false
                $notify.warning("组件配置错误,请重新配置。")
            } else {
                this.isPropsValidator = true
            }
        }
    }
}
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

自定义数据源是个难点,刚开始几十万数据源构建每次耗时都有30~40秒左右,经过优化代码,现在首次打开在一秒左右完成,然后缓存数据,后续打开毫秒级别完成,完美解决了组织项目筛选项卡顿的问题。

private List<OptionItem> GetProjectsTree(List<OrganizationDTO> organizations)
{
    var items = new List<OptionItem>();
    var projects = _dataFilterAppService.Instance.GetProjectList();
    var dics = projects.GroupBy(x => x.BuGuid).ToDictionary(x => x.Key, x => x.ToList());
    foreach (var org in organizations)
    {
        var parentItem = new OptionItem
        {
            Text = org.BuName,
            Parent = org.ParentGuid.HasValue ? org.ParentGuid.Value.ToString() : string.Empty,
            Value = org.Buguid.ToString(),
            IsLeaf = false,
            ExtData = new Dictionary<string, object>
            {
                { "BUType", org.BuType },
                { "BUGUID", org.Buguid.ToString() },
                { "BUName", org.BuName },
                { "IsHasStage", org.IsEndCompany ? 0 : 1 },
                { "HierarchyCode", org.HierarchyCode },
                { "OrderHierarchyCode", org.OrderHierarchyCode }
            }
        };
        if (org.IsEndCompany)
        {
            parentItem.ExtData["IsEndCompany"] = true;
        }
        items.Add(parentItem);
        if (org.IsEndCompany)
        {
            var hasValue = dics.TryGetValue(org.Buguid, out List<ProjectMngDto> _projects);
            if (hasValue)
            {
                items.AddRange(_projects.Select(x => new OptionItem
                {
                    Text = x.ProjectName,
                    Value = x.ProjectGUID.ToString(),
                    Parent = org.Buguid.ToString(),
                    IsLeaf = true,
                    ExtData = new Dictionary<string, object>
                    {
                        { "BUType", 3 },
                        { "BUGUID", org.Buguid.ToString() },
                        { "BUName", org.BuName },
                        { "IsHasStage", org.IsEndCompany ? 0 : 1 },
                        { "HierarchyCode", x.HierarchyCode },
                        { "OrderHierarchyCode", org.OrderHierarchyCode }
                    }
                }));
            }
            else
            {
                items.Remove(parentItem);
            }
        }
    }
    var removeList = new List<string>();
    var list = items.Where(x => !x.IsLeaf).ToList();
    foreach (var item in list)
    {
        if (!items.Any(x => x.Parent == item.Value))
        {
            removeList.Add(item.Value);
        }
    }
    items = items.Where(x => !removeList.Contains(x.Value)).ToList();
    return items;
}
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

这是解决的第一个问题,还主责了项目地图的加载优化方案,产品调用了百度地图,需要在百度地图上面进行地块位置标点操作,但是当海量标点达到上万级别,地图就会卡死...

之前的方案是根据筛选条件查出所有地块位置及其地块的相关信息,当筛选条件全部命中时,会查出所有数据,进行自定义标点操作。这当然会卡,不卡才怪。

现在的方案,根据筛选条件查出所有数据按省份的汇总数据,首次加载页面只展示省份和省份下对应地块数量,这样首次加载就非常的快,不会有任何性能问题。当点击省份的时候再去调用接口查询省份下对应的地块位置,拿到地块位置和相关数据后再进行最后的标点操作。

还有一些零零散散的各种优化,拿地测算产品第一次进入主项发版,后面会进安装盘。2021产品卖得貌似并不怎么好,没有几个客户,整个房地产行业都处于低迷状态。2022来了,他能活过来吗?赶紧年底的OKR妥妥的凉了,入职不到一年,年终也不知道能拿多少。

不管怎么说,既来之则安之,把手头上的每件事都做好就行了,2022,希望一切都好。加油!