def recommendUniversityAndCompany(town_id=None,
                                  uni_id=None,
                                  limit=20,
                                  filter_company=""):
    """
    针对给定的地区和高校,推荐适合与高校合作的企业
    :param town_id: int 区镇id, 若 town_id==0 表示全部区镇
    :param uni_id: String, eg: "123,456,345"
    :param limit:
    :param filter_company: String, 需要排除在外的企业id, 字符串类型,以英文逗号分割, eg: "123,4432,5,2354"
    :return:
    """

    if town_id is None or town_id < 0:
        return public_service.returnResult(success=False, message="区镇选择不正确")
    if not uni_id or 0 == len(uni_id):
        return public_service.returnResult(success=False, message="高校不能为空")

    try:
        filter_list = []
        if filter_company and len(filter_company) > 0:
            filter_list = [int(com_id) for com_id in filter_company.split(",")]

        university_id = [int(u_id) for u_id in uni_id.split(",")]
    except BaseException as e:
        logging.error(e)
        return public_service.returnResult(success=False, message="传入参数格式不正确")
def recommendTeacherForCompany(company_id, university_id, team=True, limit=20):
    """
     向企业推荐适合于 某一高校合作的企业及对应团队
    :param company_id: str类型,以 “,” 作为 分隔符, eg: "123,234,456"
    :param university_id: String, eg: "123,456,345"
    :param team: 是否团队
    :param limit: 一次获取的数据量
    :return:
    """
    if not company_id or len(company_id) == 0:
        return public_service.returnResult(success=False, message="企业不能为空")
    if not university_id or len(university_id) == 0:
        return public_service.returnResult(success=False, message="高校不能为空")
    try:
        company_id = [int(com_id) for com_id in company_id.split(",")]
        university_id = [int(uni_id) for uni_id in university_id.split(",")]
    except BaseException as e:
        logging.error(e)
        return public_service.returnResult(success=False, message="传入参数格式不正确")

    data = recommend_dao.recommendTeacherForCompany(
        company_id=company_id,
        university_id=university_id,
        limit=limit,
        team=team)

    return formatResultOfRecommendTeacherForCompany(data=data, team=team)
def technicalFieldComparison(eid=None, tid=None, team=1):
    """
    获取技术领域对比数据
    :return:
    {
        success: True or False,
        data:{
            "xAxis": ["ipc1", "ipc2", ..., "ipcn"],
            "eData": [n,n-1, ..., 1],
            "tData": [1,2,..., n]
        },
        message: xxx
    }
    """
    if eid is None or tid is None:
        return public_service.returnResult(success=False,
                                           message="参数有误,e_id=%s, t_id=%s" %
                                           (eid, tid))
    # data = detail_dao.getTechnicalFieldComparison(eid=eid, tid=tid, team=True if team == 1 else False)
    # data = transformTechnicalFieldComparisonData(data=data)

    # ==> [{ipc:xxx, patent:xxx}, ...]结果中包含重复数据,需要去重
    teacher_patent = detail_dao.getTeamTechnicalFieldDistribute(team_id=tid,
                                                                teacher=True)
    engineer_patent = detail_dao.getTeamTechnicalFieldDistribute(team_id=eid,
                                                                 teacher=False)

    data = formatTechnicalFieldComparisonData(
        teacher=countIPCDistribute(IPC_patent=teacher_patent, merge=True),
        engineer=countIPCDistribute(IPC_patent=engineer_patent, merge=True))

    # if data is None:
    #     return public_service.returnResult(success=False, message="从图数据库获取数据格式不正确")
    return public_service.returnResult(success=True, data=data)
def technicalFieldComparisonForRadar(eid=None, tid=None):
    """
        获取技术领域对比数据
        :return:
        {
            success: True or False,
            data:{
                "indicator": [
                    {"name": '销售(sales)', "max": 6500},
                    {"name": '管理(Administration)', "max": 16000},
                ],
               "t_value": [4300, 10000, 28000, 35000, 50000, 19000],
               "e_value": [5000, 14000, 28000, 31000, 42000, 21000],
            },
            message: xxx
        }
        """
    if eid is None or tid is None:
        return public_service.returnResult(success=False,
                                           message="参数有误,e_id=%s, t_id=%s" %
                                           (eid, tid))

    # ==> [{ipc:xxx, patent:xxx}, ...]结果中包含重复数据,需要去重
    teacher_patent = detail_dao.getTeamTechnicalFieldDistribute(team_id=tid,
                                                                teacher=True)
    engineer_patent = detail_dao.getTeamTechnicalFieldDistribute(team_id=eid,
                                                                 teacher=False)

    data = formatFieldComparisonDataForRadar(
        teacher=formatIPC_PatentRelation(teacher_patent),
        engineer=formatIPC_PatentRelation(engineer_patent))
    # if data is None:
    #     return public_service.returnResult(success=False, message="从图数据库获取数据格式不正确")
    return public_service.returnResult(success=True, data=data)
def recommendResult(uni_id="",
                    teacher_id=None,
                    town_id=None,
                    com_id="",
                    limit=20):
    """
    根据传入参数的不同组合,调用不同的处理部分, 返回统一格式的推荐结果
    :param uni_id: 高校id, str eg: "123,2343"
    :param teacher_id: 专家id, str, eg: "3224,3435"
    :param town_id: 区镇id, str, eg: "324,435"
    :param com_id: 企业id, str类型,多个企业id之间以 , 分割, eg:”123,234,345“
    :param limit:
    :return: {
        success: True or False
        data: {
            # 此处使用二维数组存储 nodes, len(nodes) 表示共有多少列节点, len(nodes[i]) 表示 第 i 列有多少节点
            nodes:[[{node prop}], [...], ...]
            links: [{source: xx, target:xxx, others: xxx}, ...]
            category: [{name: xxx}]
        }
    }
    """
    if not isinstance(uni_id, str) or 0 == len(uni_id):
        return public_service.returnResult(success=False, message="高校值不正确")
    if not isinstance(town_id, str) or 0 == len(town_id):
        return public_service.returnResult(success=False, message="区镇值不正确")

    towns = [int(t_id) for t_id in town_id.split(",")]
    unis = [int(u_id) for u_id in uni_id.split(",")]

    if isinstance(com_id, str) and 0 < len(com_id) and isinstance(
            teacher_id, str) and 0 < len(teacher_id):
        # 指定企业 & 专家
        # ==> 推荐 专家个人和 工程师团队
        comps = [int(c_id) for c_id in com_id.split(",")]
        teachers = [int(t_id) for t_id in teacher_id.split(",")]
        return recommendEngineerAndTeacher(com_id=comps,
                                           uni_id=unis,
                                           teacher_id=teachers,
                                           limit=limit)

    elif isinstance(com_id, str) and 0 < len(com_id):
        # 指定高校 & 企业
        # ==> 推荐企业工程师和高校专家
        comps = [int(c_id) for c_id in com_id.split(",")]
        return recommend2Area_service.recommendEngineerAndTeacherTeam(
            com_id=comps, uni_id=unis, reverse=False, limit=limit)

    elif isinstance(teacher_id, str) and 0 < len(teacher_id):
        # 指定 专家 & 地区
        # ===> 推荐 适合与专家合作的企业
        # TODO
        return public_service.returnResult(success=False, message="未获取到数据")
    else:
        # 指定高校 & 地区
        # ==> 推荐适合与当地企业合作的高校
        return recommend2Area_service.recommendInstitutionAndCompany(
            town_id=towns, uni_id=unis, reverse=False, limit=limit)
Ejemplo n.º 6
0
def addContactInformation(agent_id=0,
                          agent_type="area",
                          target_id=0,
                          target_type="engineer",
                          visited=0,
                          cooperate=0,
                          activity=0):
    """
    创建/更新 中介与 专家/工程师之间的关系
    :param agent_id: str 中介 id
    :param agent_type: str 中介类型 :area ==> Agent_Area or uni ==>  Agent_University
    :param target_id: int 目标节点 id
    :param target_type: str 目标节点类型类型: teacher ==> Teacher or engineer ==> Engineer
    :param visited: int 拜访次数
    :param cooperate: int 合作次数
    :param activity: int 参与活动次数
    :return : dict {success: True or False, message: xxx}
    """
    agent_label = public_service.transformUser(user=agent_type)
    target_label = public_service.transformUser(user=target_type)
    if (not isinstance(target_id,
                       int)) or target_id < 1 or target_label is None:
        return public_service.returnResult(success=False, message="目标节点参数不正确")

    start_node = neo4j.search_node(search_dict={
        "label": agent_label,
        "search": {
            "id": agent_id
        }
    })
    if start_node is None:
        return public_service.returnResult(success=False, message="用户信息有误")

    target_node = neo4j.search_node({
        "label": target_label,
        "search": {
            "id": target_id
        }
    })
    if target_node is None:
        return public_service.returnResult(success=False, message="目标节点信息有误")

    res = api_dao.addContactInformation(start_node=start_node,
                                        target_node=target_node,
                                        visited=visited,
                                        cooperate=cooperate,
                                        activity=activity)
    if res is False:
        return public_service.returnResult(success=False,
                                           message="创建/更新关系操作失败")
    return public_service.returnResult(success=True, message="操作成功")
def linkTargetBySocial(agent_id,
                       agent_label,
                       target_id,
                       target_label,
                       max_step=3,
                       limit=5):
    """
    高校中介联络专家 or 地区中介联络工程师时, 通过社交关系获取联络路径
    :param agent_id: str
    :param agent_label: str
    :param target_id:
    :param target_label:
    :param max_step:
    :param limit:
    :return: None or {success: True or False, data: None or {...}, message: xxx}
    """
    path = path_dao.getLinkPath(agent_id=agent_id,
                                agent_label=agent_label,
                                target_id=target_id,
                                target_label=target_label,
                                step=max_step,
                                limit=limit)
    if 0 == len(path):
        return None
    else:
        return public_service.returnResult(
            success=True, data=formatPath2Echarts(path_list=path))
def wordCloud(teamId, teacher=True):
    """
    根据团队id & 团队类型获取团队涉及行业的词云
    :param teamId: 团队id ,
    :param teacher: 是否是专家团队,布尔型。
    :return: {
        success: True or False, message: xx,
        data: [
            {
                name: xxx,
                value: 123
            }, ...
        ]
    }
    """
    # ==> [{ipc:xxx, patent:xxx, date: 1429142400}, ...]结果中包含重复数据,需要去重
    ipc_patent_time = detail_dao.getTeamTechnicalFieldDistribute(
        team_id=teamId, teacher=teacher)

    ipc_patent = formatIPC_PatentRelation(
        ipc_patent_time)  # {ipc: {p1,p2,...}, ...}\
    # ==> [{code: xxxx, title: xxx, ipc: xx}, ...]
    industry_ipc = detail_dao.getIndustryIPC(ipc_patent.keys())
    industry_title, ipc_industry = formatIPC_Industry(industry_ipc)

    # 统计每个行业下专利的数量 ==> {industry_code: {p1, p2, ...}, ...}
    industry_patent = countIndustryPatent(ipc_industry, ipc_patent)
    # ==> [["农药制造", 110], ....]
    res = [{
        "name": industry_title[code],
        "value": len(patents)
    } for code, patents in industry_patent.items()]
    return public_service.returnResult(success=True, data=res)
def getLinkPath(agent_id=0,
                agent_type="area",
                target_id=0,
                target_type="engineer",
                max_step=3,
                limit=5):
    """
    获取两个节点之间的联络路径, 并格式化为 Echarts 关系图 可解析的数据格式
    :param agent_id: int 中介 id
    :param agent_type: str 中介类型 :area ==> Agent_Area or uni ==>  Agent_University
    :param target_id: int 目标节点 id
    :param target_type: str 目标节点类型类型: teacher ==> Teacher or engineer ==> Engineer
    :param max_step: int 路径最大长度
    :param limit: int 路径数量
    :return : {success: True or False, data: None or {...}, message: xxx}
    """
    agent_label = public_service.transformUser(user=agent_type)
    if agent_label is None or not isinstance(agent_id,
                                             str) or len(agent_id) == 0:
        return public_service.returnResult(success=False, message="中介参数不正确")

    target_label = public_service.transformUser(user=target_type)
    if target_label is None or not isinstance(target_id,
                                              str) or len(target_id) == 0:
        return public_service.returnResult(success=False, message="目标节点参数不正确")

    if agent_label == LABEL["areaAGENT"] and target_label == LABEL["TEACHER"]:
        # 地区中介 联络 专家
        return linkTeacherByPartner(agent_id=agent_id, teacher_id=target_id)
    if agent_label == LABEL["uniAGENT"] and target_label == LABEL["ENGINEER"]:
        # 高校中介联络工程师
        return linkEngineerByPartner(agent_id=agent_id, engineer_id=target_id)

    social_path = linkTargetBySocial(agent_id=agent_id,
                                     agent_label=agent_label,
                                     target_id=target_id,
                                     target_label=target_label,
                                     max_step=max_step,
                                     limit=limit)
    if social_path is None:
        # 无法通过社交关系(如同事、朋友)等关系联系到目标 ==> 通过组织机构联系到目标
        return linkTargetByOrg(agent_id=agent_id,
                               agent_label=agent_label,
                               target_id=target_id,
                               target_label=target_label)
    return social_path
def linkTeacherByPartner(agent_id, teacher_id):
    """
    地区中介 通过 高校搭档联络到用户
    :param agent_id:
    :param teacher_id:
    :return: {success=True or False, data={nodes, links}, message="xxx"}
    """
    # ==> [{start, target, partner}] or []
    path = path_dao.linkTeacherByPartner(agent_id=agent_id,
                                         teacher_id=teacher_id)
    if 0 == len(path):
        return public_service.returnResult(success=False,
                                           message="你在当前高校没有联络权限")
    return public_service.returnResult(success=True,
                                       data=generatePathWithPublicNode(
                                           start_node=path[0]["start"],
                                           target_node=path[0]["target"],
                                           agent_node=path[0]["partner"]))
def linkEngineerByPartner(agent_id, engineer_id):
    """
    高校中介月用户 通过 地区搭档联络到用户
    :param agent_id: 技转中心用户id
    :param engineer_id: 目标工程师 id
    :return: {success=True or False, data={nodes, links}, message="xxx"}
    """
    # ==> [{start, target, partner}] or []
    path = path_dao.linkEngineerByPartner(agent_id=agent_id,
                                          engineer_id=engineer_id)
    if 0 == len(path):
        return public_service.returnResult(success=False,
                                           message="你在当前地区没有联络权限")
    return public_service.returnResult(success=True,
                                       data=generatePathWithPublicNode(
                                           start_node=path[0]["start"],
                                           target_node=path[0]["target"],
                                           agent_node=path[0]["partner"]))
def recommendTeacherForArea(area_id=None,
                            uni_id=None,
                            team=True,
                            skip=0,
                            limit=20,
                            sort="",
                            order="desc"):
    """
    向地区推荐适合于 某一高校合作的企业及对应团队
    :param area_id:
    :param uni_id: String, eg: "123,456,345"
    :param team: 是够团队
    :param skip: 偏移量
    :param limit: 一次获取的数据量
    :param sort: 用于排序的字段, 目前只根据 企业名 及 高校名 排序
    :param order: 排序方式 asc or desc
    :return:
    """
    if not area_id:
        return public_service.returnResult(success=False, message="找不到地区")
    if not uni_id or len(uni_id) == 0:
        return public_service.returnResult(success=False, message="找不到高校")
    try:
        uni_id_list = [int(uid) for uid in uni_id.split(",")]
    except BaseException as e:
        logging.error(e)
        return public_service.returnResult(success=False, message="参数格式不正确")

    sort = public_service.transformSort(sort, order)
    data = recommend_dao.recommendTeacherForArea(area_id=area_id,
                                                 university_id=uni_id_list,
                                                 team=team,
                                                 sort=sort,
                                                 skip=skip,
                                                 limit=limit)
    total = recommend_dao.totalRecommendTeacherForArea(
        area_id=area_id, university_id=uni_id_list, team=team)
    total = 0 if len(total) == 0 else total[0]["total"]
    return public_service.returnResult(success=True,
                                       data=data,
                                       total=total,
                                       offset=skip,
                                       limit=limit,
                                       team=team)
Ejemplo n.º 13
0
def recommendUniversityForCompany(com_id, limit=20):
    """
    根据企业id, 为特定企业推荐 高校
    :param com_id: list [2,3,4...]
    :param limit:
    :return:
    """
    records = recommend2Area_dao.recommendUniversityForCompany(
        company_id=com_id, limit=limit)
    return public_service.returnResult(
        success=True, data=formatRecommendUniversityAndCompany(records))
Ejemplo n.º 14
0
def recommendEngineerAndTeacherTeam2(com_id, reverse=True, limit=20):
    """
    制定 高校 & 企业 推荐 专家团队 & 工程师团队
    :param com_id: list, [] or [123,435...]
    :param reverse: True or False, 地区排列 与 高校排列 的顺序
    :param limit: 一次获取的数据量
    :return:
    """
    records = recommend2Area_dao.recommendEngineerAndTeacherTeam2(
        com_id=com_id, limit=limit)
    return public_service.returnResult(success=True,
                                       data=formatRecommendEngineerAndTeacher(
                                           records=records, reverse=reverse))
def linkTargetByOrg(agent_id, agent_label, target_id, target_label):
    """
    通过 目标所属 学院 or 企业联络到目标的路径
    :param agent_id:
    :param agent_label:
    :param target_id:
    :param target_label:
    :return:
    """
    # ==> [{start, target, org}] or []
    path = path_dao.linkTargetByOrg(agent_id=agent_id,
                                    agent_label=agent_label,
                                    target_id=target_id,
                                    target_label=target_label)
    if 0 == len(path):
        return public_service.returnResult(success=False,
                                           message="参数错误, 无法找到节点")
    return public_service.returnResult(success=True,
                                       data=generatePathWithPublicNode(
                                           start_node=path[0]["start"],
                                           target_node=path[0]["target"],
                                           agent_node=path[0]["org"]))
Ejemplo n.º 16
0
def recommendUniversityAndCompany(town_id=None, reverse=True, limit=20):
    """
    为特定区域内的企业 推荐 适合合作的高校
    :param town_id: 整型
    :param reverse: True or False, 地区排列 与 高校排列 的顺序
    :param limit:
    :return:
    """
    records = recommend2Area_dao.recommendUniversityAndCompany(town_id=town_id,
                                                               limit=limit)
    return public_service.returnResult(
        success=True,
        data=formatRecommendUniversityAndCompany(records=records,
                                                 reverse=reverse))
Ejemplo n.º 17
0
def recommendInstitutionAndCompany(town_id, uni_id, reverse=True, limit=20):
    """
    根据选定区域的id、 以及选定高校的id, 推荐地区企业 和 高校学院
    :param town_id:list [2,3,4...]
    :param uni_id:
    :param reverse: True or False, 地区排列 与 高校排列 的顺序
    :param limit:
    :return:
    """
    records = recommend2Area_dao.recommendInstitutionAndCompany(
        town_id=town_id, uni_id=uni_id, limit=limit)
    return public_service.returnResult(
        success=True,
        data=formatRecommendInstitutionAndCompany(records, reverse=reverse))
def recommendEngineerAndTeacher(com_id, uni_id, teacher_id, limit=20):
    """
    指定企业 & 专家,推荐 专家和 工程师团队
    :param com_id: list [12,34,3]
    :param uni_id: list [23,543]
    :param teacher_id: [234,453, 435]
    :param limit:
    :return:
    """
    records = recommend2University_dao.recommendEngineerAndTeacher(
        com_id=com_id, uni_id=uni_id, teacher_id=teacher_id, limit=limit)
    return public_service.returnResult(
        success=True,
        data=recommend2Area_service.formatRecommendEngineerAndTeacher(
            records=records, reverse=False))
def getPersonalNetwork(agent_id, agent_type=0):
    """
    获取中介的个人中心网络
    :param agent_id:
    :param agent_type: 中介类型: area ==> Agent_Area or uni ==>  Agent_University
    :return: [{s_id, s_name, t_id, t_name, org_id, org_name}]
    """
    agent_type = public_service.transformUser(user=agent_type)
    # if (not isinstance(agent_id, int)) or agent_id <= 0 or agent_type is None:
    #     return public_service.returnResult(success=False, message="参数不正确")

    agent = personal_dao.getAgentNode(agent_id=agent_id, agent_type=agent_type)
    if not agent or 0 == len(agent):
        return public_service.returnResult(success=False, message="id有误, 查无此人")

    work_network = personal_dao.getAgentPartnerRelation(agent_id=agent_id,
                                                        agent_type=agent_type)
    visit_network = personal_dao.getPersonalNetworkVisitedRelation(
        agent_id=agent_id, agent_type=agent_type)

    data = formatPersonalNetworkData(agent=agent[0],
                                     work_relation=work_network,
                                     visit_relation=visit_network)
    return public_service.returnResult(success=True, data=data)
Ejemplo n.º 20
0
def recommendResult(town_id=None, com_id="", uni_id="", limit=20):
    """
    根据传入参数的不同组合,调用不同的处理部分, 返回统一格式的推荐结果
    :param town_id: 区镇id, str类型,
    :param com_id: 企业id, str类型,多个企业id之间以 , 分割, eg:”123,234,345“
    :param uni_id: 高校id, str类型,多个id之间以 , 分割, eg:”321,453,465“
    :param limit:
    :return: {
        success: True or False
        data: {
            # 此处使用二维数组存储 nodes, len(nodes) 表示共有多少列节点, len(nodes[i]) 表示 第 i 列有多少节点
            nodes:[[{node prop}], [...], ...]
            links: [{source: xx, target:xxx, others: xxx}, ...]
            category: [{name: xxx}]
        }
    }
    """
    if not isinstance(town_id, str) or 0 == len(town_id):
        return public_service.returnResult(success=False, message="区镇值不正确")

    towns = [int(t_id) for t_id in town_id.split(",")]

    if not isinstance(com_id, str) or 0 == len(com_id):  # 未传入 企业参数 或 参数格式不正确
        if not isinstance(uni_id,
                          str) or 0 == len(uni_id):  # 未传入高校参数 或 参数格式不正确
            # ==> 只输入区镇信息, 为特定区域内的企业 推荐 适合合作的高校
            return recommendUniversityAndCompany(town_id=towns, limit=limit)
        else:  # 传入高校参数
            # ==> 指定地区和高校,推荐适合与当地企业合作的高校
            uni_id_list = [int(u_id) for u_id in uni_id.split(",")]
            return recommendInstitutionAndCompany(town_id=towns,
                                                  uni_id=uni_id_list,
                                                  limit=limit)
    else:  # 输入企业
        comps = [int(c_id) for c_id in com_id.split(",")]
        if not isinstance(uni_id,
                          str) or 0 == len(uni_id):  # 未传入高校参数 或 参数格式不正确
            # ==> 推荐与特定企业相匹配的高校专家团队
            # return recommendUniversityForCompany(com_id=comps, limit=limit)
            # return recommendInstitutionForCompany(com_id=comps, limit=limit)
            return recommendEngineerAndTeacherTeam2(com_id=comps, limit=limit)
        else:
            # ==> 推荐企业工程师和高校专家
            uni_id_list = [int(u_id) for u_id in uni_id.split(",")]
            return recommendEngineerAndTeacherTeam(com_id=comps,
                                                   uni_id=uni_id_list,
                                                   limit=limit)
def chartsRiver(teamId=None, teacher=True):
    """
    获取某个团队的河流图数据
    :param teamId: 团队id ,
    :param teacher: 是否是专家团队,布尔型。
    :return: {
        success: True or False, message: xx,
        data: {
            legend: [ipc1, ipc2, ...]
            data: [["2020/1/1", "xx行业" or "IPC", 123], 。。。]
        }
    }
    """
    # ==> [{ipc:xxx, patent:xxx, date: 1429142400}, ...]结果中包含重复数据,需要去重
    ipc_patent_time = detail_dao.getTeamTechnicalFieldDistribute(
        team_id=teamId, teacher=teacher)

    ipc_patent = formatIPC_PatentRelation(
        ipc_patent_time)  # {ipc: {p1,p2,...}, ...}\
    # ==> {year: {patent,...}} & {patent: year, ...}
    year_patent, patent_year = formatYear_PatentRelation(ipc_patent_time)

    # ==> [{code: xxxx, title: xxx, ipc: xx}, ...]
    industry_ipc = detail_dao.getIndustryIPC(ipc_patent.keys())
    industry_title, ipc_industry = formatIPC_Industry(industry_ipc)

    # 统计每个行业下专利的数量 ==> {industry_code: {p1, p2, ...}, ...}
    industry_patent = countIndustryPatent(ipc_industry, ipc_patent)

    # 取涉及专利最多的 6 个行业 ==> {code1, code2, ...}
    tmp = sorted(industry_patent.items(),
                 key=lambda kv: len(kv[1]),
                 reverse=True)[:5]
    industry = {item[0] for item in tmp}

    legend = [industry_title[code] for code in industry]

    # ==> {2020: {industry1: 123, industry2: 345,...}, ...}
    time_industry = dict()
    max_year, min_year = max(year_patent.keys()), min(year_patent.keys())
    for year in range(min_year, max_year + 1):
        if year not in time_industry:
            time_industry[year] = dict()
        industry_year = time_industry[year]

        for code in industry:
            patents = industry_patent[code]
            for patent in patents:
                if year == patent_year[patent]:
                    if code not in industry_year:
                        industry_year[code] = 1
                    else:
                        industry_year[code] += 1

    res = list()
    for year, industry_dict in time_industry.items():
        for code in industry:
            num = 0 if code not in industry_dict else industry_dict[code]
            title = industry_title[code]
            res.append([str(year + 1), num, title])

    return public_service.returnResult(success=True,
                                       data={
                                           "legend": legend,
                                           "data": res
                                       })
def formatResultOfRecommendTeacherForCompany(data, team):
    """
    将从图数据库中获取的数据格式化为前端可处理的数据格式
    """
    if 0 == len(data):
        return public_service.returnResult(success=False, message="未查询到数据")

    nodes_com, nodes_engineer, nodes_teacher, nodes_uni = list(), list(), list(
    ), list()
    links = []
    set_node = set()
    category_list, category_map = list(), dict()
    for record in data:
        com_id = "c_%s" % record["c_id"]
        e_id = "e_%s" % record["e_id"]
        t_id = "t_%s" % record["t_id"]
        u_id = "u_%s" % record["u_id"]

        # 添加企业节点
        index_category = addCategory(category_list=category_list,
                                     category_map=category_map,
                                     node_id=record["c_id"],
                                     name=record["c_name"])
        addNode(node_set=set_node,
                node_container=nodes_com,
                node_id=com_id,
                category=index_category,
                label=record["c_name"])
        # 添加工程师节点
        addNode(node_set=set_node,
                node_container=nodes_engineer,
                node_id=e_id,
                category=index_category,
                label=record["e_name"])
        # 添加工程师与企业的关系
        addLinks(links=links,
                 source=com_id,
                 target=e_id,
                 category=index_category)

        # 添加高校节点
        index_category = addCategory(category_list=category_list,
                                     category_map=category_map,
                                     node_id=record["u_id"],
                                     name=record["u_name"])
        addNode(node_set=set_node,
                node_container=nodes_uni,
                node_id=u_id,
                category=index_category,
                label=record["u_name"])
        # 添加专家节点
        addNode(node_set=set_node,
                node_container=nodes_teacher,
                node_id=t_id,
                category=index_category,
                label=record["t_name"])

        # 添加专家和高校的关系
        addLinks(links=links,
                 source=u_id,
                 target=t_id,
                 category=index_category)

        # 添加工程师与专家的技术领域相似关系
        isTeam = "团队" if team else ""
        similar = '%.2f' % ((1 - record["weight"]) * 100) + "%"
        weight = "{engineer}{team} - {teacher}{team} " \
                 "<br> 技术相似度:{similar} ".format(engineer=record["e_name"], team=isTeam, teacher=record["t_name"],
                                                similar=similar, category=index_category)
        addLinks(links=links, source=e_id, target=t_id, weight=weight)

    result = {
        "com": nodes_com,
        "engineer": nodes_engineer,
        "teacher": nodes_teacher,
        "uni": nodes_uni
    }
    return public_service.returnResult(success=True,
                                       data={
                                           "nodes": result,
                                           "links": links,
                                           "category": category_list
                                       })