f
This commit is contained in:
@@ -17,9 +17,9 @@ import (
|
||||
"tyapi-server/internal/domains/api/services/processors"
|
||||
)
|
||||
|
||||
// ProcessQYGLJ1U9Request 企业全景报告处理器:并发调用企业全量(QYGLUY3S)、股权全景(QYGLJ0Q1)、司法涉诉(QYGL5S1I),
|
||||
// 以及企业年报(QYGLDJ12)、税收违法(QYGL8848)、欠税公告(QYGL7D9A);
|
||||
// 前三者走 buildReport / map*;后三者在 buildReport 中转为 annualReports、taxViolations、ownTaxNotices 供页面展示。
|
||||
// ProcessQYGLJ1U9Request 企业全景报告处理器:并发调用企业全量(QYGLUY3S)、股权全景(QYGLJ0Q1)、司法涉诉(QYGL5S1I)、
|
||||
// 企业年报(QYGLDJ12)、税收违法(QYGL8848)、欠税公告(QYGL7D9A)。
|
||||
// 单路失败、查无、解析失败时该路按空数据处理并继续合并;仅当合并后的报告仍无任何可展示的企业要素时返回查询为空。
|
||||
func ProcessQYGLJ1U9Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
|
||||
// 复用 QYGLUY3S 的入参结构:企业名称/注册号/统一社会信用代码
|
||||
var p dto.QYGLJ1U9Req
|
||||
@@ -30,7 +30,7 @@ func ProcessQYGLJ1U9Request(ctx context.Context, params []byte, deps *processors
|
||||
return nil, errors.Join(processors.ErrInvalidParam, err)
|
||||
}
|
||||
|
||||
// 并发调用三个已有处理器
|
||||
// 并发调用六个子处理器;单路失败或无数据时降级为空结果,仅当合并后仍无任何企业要素时返回查询为空
|
||||
type apiResult struct {
|
||||
key string
|
||||
data map[string]interface{}
|
||||
@@ -108,12 +108,15 @@ func ProcessQYGLJ1U9Request(ctx context.Context, params []byte, deps *processors
|
||||
wg.Wait()
|
||||
close(resultsCh)
|
||||
|
||||
var jiguang, judicial, equity map[string]interface{}
|
||||
var annualReport, taxViolation, taxArrears map[string]interface{}
|
||||
jiguang := map[string]interface{}{}
|
||||
judicial := map[string]interface{}{}
|
||||
equity := map[string]interface{}{}
|
||||
annualReport := map[string]interface{}{}
|
||||
taxViolation := map[string]interface{}{}
|
||||
taxArrears := map[string]interface{}{}
|
||||
for r := range resultsCh {
|
||||
if r.err != nil {
|
||||
// 任一关键数据源异常,则返回系统错误(也可以根据需求做降级)
|
||||
return nil, errors.Join(processors.ErrSystem, fmt.Errorf("%s 调用失败: %w", r.key, r.err))
|
||||
if r.err != nil || r.data == nil {
|
||||
continue
|
||||
}
|
||||
switch r.key {
|
||||
case "jiguangFull":
|
||||
@@ -130,27 +133,12 @@ func ProcessQYGLJ1U9Request(ctx context.Context, params []byte, deps *processors
|
||||
taxArrears = r.data
|
||||
}
|
||||
}
|
||||
if jiguang == nil {
|
||||
jiguang = map[string]interface{}{}
|
||||
}
|
||||
if judicial == nil {
|
||||
judicial = map[string]interface{}{}
|
||||
}
|
||||
if equity == nil {
|
||||
equity = map[string]interface{}{}
|
||||
}
|
||||
if annualReport == nil {
|
||||
annualReport = map[string]interface{}{}
|
||||
}
|
||||
if taxViolation == nil {
|
||||
taxViolation = map[string]interface{}{}
|
||||
}
|
||||
if taxArrears == nil {
|
||||
taxArrears = map[string]interface{}{}
|
||||
}
|
||||
|
||||
// 复用构建逻辑生成企业报告结构(含年报 / 税收违法 / 欠税公告的转化结果)
|
||||
report := buildReport(jiguang, judicial, equity, annualReport, taxViolation, taxArrears)
|
||||
if !qyglJ1U9ReportHasSubstantiveData(report) {
|
||||
return nil, errors.Join(processors.ErrNotFound, errors.New("未查询到可用于生成报告的企业数据"))
|
||||
}
|
||||
|
||||
// 为报告生成唯一编号并缓存,供后续通过编号查看
|
||||
reportID := saveQYGLReport(report)
|
||||
|
||||
@@ -58,9 +58,654 @@ func buildReport(jiguang, judicial, equity, annualRaw, taxViolationRaw, taxArrea
|
||||
report["annualReports"] = annualReports
|
||||
report["taxViolations"] = mapTaxViolations(taxViolationRaw)
|
||||
report["ownTaxNotices"] = mapOwnTaxNotices(taxArrearsRaw)
|
||||
applyQYGLJ1U9ReportFieldDefaults(report)
|
||||
return report
|
||||
}
|
||||
|
||||
// applyQYGLJ1U9ReportFieldDefaults 在子数据源缺失时仍保证报告字段齐全:字符串 ""、数值 0、数组 []、对象按约定填空结构(不向客户暴露「缺键」)。
|
||||
func applyQYGLJ1U9ReportFieldDefaults(report map[string]interface{}) {
|
||||
if report == nil {
|
||||
return
|
||||
}
|
||||
// 顶层字符串
|
||||
report["entName"] = str(report["entName"])
|
||||
report["creditCode"] = str(report["creditCode"])
|
||||
report["reportTime"] = str(report["reportTime"])
|
||||
|
||||
report["basic"] = mergeBasicDefaults(report["basic"])
|
||||
b, _ := report["basic"].(map[string]interface{})
|
||||
if str(report["entName"]) == "" {
|
||||
report["entName"] = str(b["entName"])
|
||||
}
|
||||
if str(report["creditCode"]) == "" {
|
||||
report["creditCode"] = str(b["creditCode"])
|
||||
}
|
||||
|
||||
report["branches"] = ensureSlice(report["branches"])
|
||||
report["guarantees"] = ensureSlice(report["guarantees"])
|
||||
report["inspections"] = ensureSlice(report["inspections"])
|
||||
report["timeline"] = ensureSlice(report["timeline"])
|
||||
report["beneficiaries"] = ensureSlice(report["beneficiaries"])
|
||||
report["annualReports"] = ensureSlice(report["annualReports"])
|
||||
if _, ok := report["basicList"]; !ok {
|
||||
report["basicList"] = []interface{}{}
|
||||
} else {
|
||||
report["basicList"] = ensureSlice(report["basicList"])
|
||||
}
|
||||
|
||||
report["shareholding"] = mergeShareholdingDefaults(report["shareholding"])
|
||||
report["controller"] = mergeControllerDefaults(report["controller"])
|
||||
report["investments"] = mergeInvestmentsDefaults(report["investments"])
|
||||
report["management"] = mergeManagementDefaults(report["management"])
|
||||
report["assets"] = mergeAssetsDefaults(report["assets"])
|
||||
report["licenses"] = mergeLicensesDefaults(report["licenses"])
|
||||
report["activities"] = mergeActivitiesDefaults(report["activities"])
|
||||
report["risks"] = mergeRisksDefaults(report["risks"])
|
||||
report["listed"] = mergeListedDefaults(report["listed"])
|
||||
|
||||
report["taxViolations"] = mergeTaxViolationsDefaults(report["taxViolations"])
|
||||
report["ownTaxNotices"] = mergeOwnTaxNoticesDefaults(report["ownTaxNotices"])
|
||||
|
||||
if ro, ok := report["riskOverview"].(map[string]interface{}); ok {
|
||||
report["riskOverview"] = mergeRiskOverviewDefaults(ro)
|
||||
} else {
|
||||
report["riskOverview"] = mergeRiskOverviewDefaults(nil)
|
||||
}
|
||||
}
|
||||
|
||||
func mergeBasicDefaults(v interface{}) map[string]interface{} {
|
||||
out, _ := v.(map[string]interface{})
|
||||
if out == nil {
|
||||
out = map[string]interface{}{}
|
||||
}
|
||||
skel := map[string]interface{}{
|
||||
"entName": "",
|
||||
"creditCode": "",
|
||||
"regNo": "",
|
||||
"orgCode": "",
|
||||
"entType": "",
|
||||
"entTypeCode": "",
|
||||
"entityTypeCode": "",
|
||||
"establishDate": "",
|
||||
"registeredCapital": float64(0),
|
||||
"regCapCurrency": "",
|
||||
"regCapCurrencyCode": "",
|
||||
"regOrg": "",
|
||||
"regOrgCode": "",
|
||||
"regProvince": "",
|
||||
"provinceCode": "",
|
||||
"regCity": "",
|
||||
"regCityCode": "",
|
||||
"regDistrict": "",
|
||||
"districtCode": "",
|
||||
"address": "",
|
||||
"postalCode": "",
|
||||
"legalRepresentative": "",
|
||||
"compositionForm": "",
|
||||
"approvedBusinessItem": "",
|
||||
"status": "",
|
||||
"statusCode": "",
|
||||
"operationPeriodFrom": "",
|
||||
"operationPeriodTo": "",
|
||||
"approveDate": "",
|
||||
"cancelDate": "",
|
||||
"revokeDate": "",
|
||||
"cancelReason": "",
|
||||
"revokeReason": "",
|
||||
"businessScope": "",
|
||||
"lastAnnuReportYear": "",
|
||||
"oldNames": []interface{}{},
|
||||
}
|
||||
for k, def := range skel {
|
||||
if _, ok := out[k]; !ok {
|
||||
out[k] = def
|
||||
}
|
||||
}
|
||||
if out["oldNames"] == nil {
|
||||
out["oldNames"] = []interface{}{}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func ensureSlice(v interface{}) []interface{} {
|
||||
if v == nil {
|
||||
return []interface{}{}
|
||||
}
|
||||
arr, ok := v.([]interface{})
|
||||
if !ok {
|
||||
return []interface{}{}
|
||||
}
|
||||
return arr
|
||||
}
|
||||
|
||||
func mergeShareholdingDefaults(v interface{}) map[string]interface{} {
|
||||
out, _ := v.(map[string]interface{})
|
||||
if out == nil {
|
||||
out = map[string]interface{}{}
|
||||
}
|
||||
skel := map[string]interface{}{
|
||||
"shareholders": []interface{}{},
|
||||
"equityChanges": []interface{}{},
|
||||
"equityPledges": []interface{}{},
|
||||
"paidInDetails": []interface{}{},
|
||||
"subscribedCapitalDetails": []interface{}{},
|
||||
"hasEquityPledges": false,
|
||||
"shareholderCount": 0,
|
||||
"registeredCapital": float64(0),
|
||||
"currency": "",
|
||||
"topHolderName": "",
|
||||
"topHolderPercent": float64(0),
|
||||
"top5TotalPercent": float64(0),
|
||||
}
|
||||
for k, def := range skel {
|
||||
if _, ok := out[k]; !ok {
|
||||
out[k] = def
|
||||
}
|
||||
}
|
||||
for _, k := range []string{"shareholders", "equityChanges", "equityPledges", "paidInDetails", "subscribedCapitalDetails"} {
|
||||
out[k] = ensureSlice(out[k])
|
||||
}
|
||||
if out["registeredCapital"] == nil {
|
||||
out["registeredCapital"] = float64(0)
|
||||
}
|
||||
if _, ok := out["hasEquityPledges"].(bool); !ok {
|
||||
out["hasEquityPledges"] = false
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func mergeControllerDefaults(v interface{}) map[string]interface{} {
|
||||
if m, ok := v.(map[string]interface{}); ok && m != nil {
|
||||
if m["path"] == nil {
|
||||
m["path"] = map[string]interface{}{
|
||||
"nodes": []interface{}{},
|
||||
"links": []interface{}{},
|
||||
}
|
||||
}
|
||||
if p, ok := m["path"].(map[string]interface{}); ok {
|
||||
if _, ok := p["nodes"]; !ok {
|
||||
p["nodes"] = []interface{}{}
|
||||
}
|
||||
if _, ok := p["links"]; !ok {
|
||||
p["links"] = []interface{}{}
|
||||
}
|
||||
}
|
||||
ensureStrKeys(m, []string{"id", "name", "type", "reason", "source"})
|
||||
if m["percent"] == nil {
|
||||
m["percent"] = float64(0)
|
||||
} else if _, ok := m["percent"].(float64); !ok {
|
||||
m["percent"] = num(m["percent"])
|
||||
}
|
||||
return m
|
||||
}
|
||||
return map[string]interface{}{
|
||||
"id": "",
|
||||
"name": "",
|
||||
"type": "",
|
||||
"percent": float64(0),
|
||||
"path": map[string]interface{}{
|
||||
"nodes": []interface{}{},
|
||||
"links": []interface{}{},
|
||||
},
|
||||
"reason": "",
|
||||
"source": "",
|
||||
}
|
||||
}
|
||||
|
||||
func mergeInvestmentsDefaults(v interface{}) map[string]interface{} {
|
||||
out, _ := v.(map[string]interface{})
|
||||
if out == nil {
|
||||
out = map[string]interface{}{}
|
||||
}
|
||||
if _, ok := out["totalCount"]; !ok {
|
||||
out["totalCount"] = 0
|
||||
}
|
||||
if _, ok := out["totalAmount"]; !ok {
|
||||
out["totalAmount"] = float64(0)
|
||||
}
|
||||
if out["totalAmount"] == nil {
|
||||
out["totalAmount"] = float64(0)
|
||||
}
|
||||
out["list"] = ensureSlice(out["list"])
|
||||
out["legalRepresentativeInvestments"] = ensureSlice(out["legalRepresentativeInvestments"])
|
||||
return out
|
||||
}
|
||||
|
||||
func mergeManagementDefaults(v interface{}) map[string]interface{} {
|
||||
out, _ := v.(map[string]interface{})
|
||||
if out == nil {
|
||||
out = map[string]interface{}{}
|
||||
}
|
||||
if _, ok := out["executives"]; !ok {
|
||||
out["executives"] = []interface{}{}
|
||||
} else {
|
||||
out["executives"] = ensureSlice(out["executives"])
|
||||
}
|
||||
if _, ok := out["legalRepresentativeOtherPositions"]; !ok {
|
||||
out["legalRepresentativeOtherPositions"] = []interface{}{}
|
||||
} else {
|
||||
out["legalRepresentativeOtherPositions"] = ensureSlice(out["legalRepresentativeOtherPositions"])
|
||||
}
|
||||
if _, ok := out["employeeCount"]; !ok || out["employeeCount"] == nil {
|
||||
out["employeeCount"] = float64(0)
|
||||
}
|
||||
if _, ok := out["femaleEmployeeCount"]; !ok || out["femaleEmployeeCount"] == nil {
|
||||
out["femaleEmployeeCount"] = float64(0)
|
||||
}
|
||||
if out["socialSecurity"] == nil {
|
||||
out["socialSecurity"] = map[string]interface{}{}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func mergeAssetsDefaults(v interface{}) map[string]interface{} {
|
||||
out, _ := v.(map[string]interface{})
|
||||
if out == nil {
|
||||
out = map[string]interface{}{}
|
||||
}
|
||||
if _, ok := out["years"]; !ok {
|
||||
out["years"] = []interface{}{}
|
||||
} else {
|
||||
out["years"] = ensureSlice(out["years"])
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func mergeLicensesDefaults(v interface{}) map[string]interface{} {
|
||||
out, _ := v.(map[string]interface{})
|
||||
if out == nil {
|
||||
out = map[string]interface{}{}
|
||||
}
|
||||
for _, k := range []string{"permits", "permitChanges", "ipPledges", "otherLicenses"} {
|
||||
if _, ok := out[k]; !ok {
|
||||
out[k] = []interface{}{}
|
||||
} else {
|
||||
out[k] = ensureSlice(out[k])
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func mergeActivitiesDefaults(v interface{}) map[string]interface{} {
|
||||
out, _ := v.(map[string]interface{})
|
||||
if out == nil {
|
||||
out = map[string]interface{}{}
|
||||
}
|
||||
if _, ok := out["bids"]; !ok {
|
||||
out["bids"] = []interface{}{}
|
||||
} else {
|
||||
out["bids"] = ensureSlice(out["bids"])
|
||||
}
|
||||
if _, ok := out["websites"]; !ok {
|
||||
out["websites"] = []interface{}{}
|
||||
} else {
|
||||
out["websites"] = ensureSlice(out["websites"])
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func litigationTypeKeys() []string {
|
||||
return []string{
|
||||
"administrative", "implement", "preservation", "civil", "criminal",
|
||||
"bankrupt", "jurisdict", "compensate",
|
||||
}
|
||||
}
|
||||
|
||||
func defaultLitigationShell() map[string]interface{} {
|
||||
out := map[string]interface{}{"totalCases": 0}
|
||||
for _, k := range litigationTypeKeys() {
|
||||
out[k] = map[string]interface{}{
|
||||
"count": 0,
|
||||
"cases": []interface{}{},
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func mergeLitigationShape(v interface{}) map[string]interface{} {
|
||||
out := defaultLitigationShell()
|
||||
if v == nil {
|
||||
return out
|
||||
}
|
||||
m, ok := v.(map[string]interface{})
|
||||
if !ok {
|
||||
return out
|
||||
}
|
||||
known := map[string]struct{}{}
|
||||
for _, k := range litigationTypeKeys() {
|
||||
known[k] = struct{}{}
|
||||
}
|
||||
for k, val := range m {
|
||||
if k == "totalCases" {
|
||||
out["totalCases"] = intFromAny(val)
|
||||
continue
|
||||
}
|
||||
if _, isCat := known[k]; isCat {
|
||||
sm, ok := val.(map[string]interface{})
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
out[k] = map[string]interface{}{
|
||||
"count": intFromAny(sm["count"]),
|
||||
"cases": ensureSlice(sm["cases"]),
|
||||
}
|
||||
continue
|
||||
}
|
||||
out[k] = val
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func defaultQuickCancelShell() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"entName": "",
|
||||
"creditCode": "",
|
||||
"regNo": "",
|
||||
"regOrg": "",
|
||||
"noticeFromDate": "",
|
||||
"noticeToDate": "",
|
||||
"cancelResult": "",
|
||||
"dissents": []interface{}{},
|
||||
}
|
||||
}
|
||||
|
||||
func defaultLiquidationShell() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"principal": "",
|
||||
"members": []interface{}{},
|
||||
}
|
||||
}
|
||||
|
||||
func mergeRisksDefaults(v interface{}) map[string]interface{} {
|
||||
out, _ := v.(map[string]interface{})
|
||||
if out == nil {
|
||||
out = map[string]interface{}{}
|
||||
}
|
||||
boolKeys := []string{
|
||||
"hasCourtJudgments", "hasJudicialAssists", "hasDishonestDebtors", "hasLimitHighDebtors",
|
||||
"hasAdminPenalty", "hasException", "hasSeriousIllegal", "hasTaxOwing", "hasSeriousTaxIllegal",
|
||||
"hasMortgage", "hasEquityPledges", "hasQuickCancel",
|
||||
}
|
||||
for _, k := range boolKeys {
|
||||
if _, ok := out[k]; !ok {
|
||||
out[k] = false
|
||||
}
|
||||
}
|
||||
if _, ok := out["riskLevel"]; !ok {
|
||||
out["riskLevel"] = "低"
|
||||
}
|
||||
if _, ok := out["riskScore"]; !ok {
|
||||
out["riskScore"] = 80
|
||||
}
|
||||
for _, k := range []string{"dishonestDebtorCount", "limitHighDebtorCount"} {
|
||||
if _, ok := out[k]; !ok {
|
||||
out[k] = 0
|
||||
}
|
||||
}
|
||||
for _, k := range []string{
|
||||
"courtJudgments", "judicialAssists", "dishonestDebtors", "limitHighDebtors",
|
||||
"adminPenalties", "adminPenaltyUpdates", "exceptions", "seriousIllegals", "mortgages",
|
||||
} {
|
||||
if _, ok := out[k]; !ok {
|
||||
out[k] = []interface{}{}
|
||||
} else {
|
||||
out[k] = ensureSlice(out[k])
|
||||
}
|
||||
}
|
||||
out["litigation"] = mergeLitigationShape(out["litigation"])
|
||||
if out["quickCancel"] == nil {
|
||||
out["quickCancel"] = defaultQuickCancelShell()
|
||||
} else if qm, ok := out["quickCancel"].(map[string]interface{}); ok {
|
||||
dc := defaultQuickCancelShell()
|
||||
for k, def := range dc {
|
||||
if _, ok := qm[k]; !ok {
|
||||
qm[k] = def
|
||||
}
|
||||
}
|
||||
if qm["dissents"] == nil {
|
||||
qm["dissents"] = []interface{}{}
|
||||
} else {
|
||||
qm["dissents"] = ensureSlice(qm["dissents"])
|
||||
}
|
||||
out["quickCancel"] = qm
|
||||
}
|
||||
if out["liquidation"] == nil {
|
||||
out["liquidation"] = defaultLiquidationShell()
|
||||
} else if lm, ok := out["liquidation"].(map[string]interface{}); ok {
|
||||
dc := defaultLiquidationShell()
|
||||
for k, def := range dc {
|
||||
if _, ok := lm[k]; !ok {
|
||||
lm[k] = def
|
||||
}
|
||||
}
|
||||
if lm["members"] == nil {
|
||||
lm["members"] = []interface{}{}
|
||||
} else {
|
||||
lm["members"] = ensureSlice(lm["members"])
|
||||
}
|
||||
out["liquidation"] = lm
|
||||
}
|
||||
tr, _ := out["taxRecords"].(map[string]interface{})
|
||||
if tr == nil {
|
||||
tr = map[string]interface{}{}
|
||||
}
|
||||
for _, k := range []string{"taxLevelAYears", "seriousTaxIllegal", "taxOwings"} {
|
||||
if _, ok := tr[k]; !ok {
|
||||
tr[k] = []interface{}{}
|
||||
} else {
|
||||
tr[k] = ensureSlice(tr[k])
|
||||
}
|
||||
}
|
||||
out["taxRecords"] = tr
|
||||
return out
|
||||
}
|
||||
|
||||
// normalizeListedStock 无股票结构时用 JSON null,避免前端把 {} 当成有值而 JSON.stringify 出 "{}"。
|
||||
func normalizeListedStock(v interface{}) interface{} {
|
||||
if v == nil {
|
||||
return nil
|
||||
}
|
||||
m, ok := v.(map[string]interface{})
|
||||
if !ok {
|
||||
return v
|
||||
}
|
||||
if len(m) == 0 {
|
||||
return nil
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
func mergeListedDefaults(v interface{}) map[string]interface{} {
|
||||
if m, ok := v.(map[string]interface{}); ok && m != nil {
|
||||
if _, ok := m["isListed"].(bool); !ok {
|
||||
m["isListed"] = false
|
||||
}
|
||||
co, _ := m["company"].(map[string]interface{})
|
||||
if co == nil {
|
||||
co = map[string]interface{}{}
|
||||
}
|
||||
for k, def := range map[string]interface{}{
|
||||
"bizScope": "", "creditCode": "", "regAddr": "", "regCapital": "",
|
||||
"orgCode": "", "cur": "", "curName": "",
|
||||
} {
|
||||
if _, ok := co[k]; !ok {
|
||||
co[k] = def
|
||||
}
|
||||
}
|
||||
m["company"] = co
|
||||
m["stock"] = normalizeListedStock(m["stock"])
|
||||
if _, ok := m["topShareholders"]; !ok {
|
||||
m["topShareholders"] = []interface{}{}
|
||||
} else {
|
||||
m["topShareholders"] = ensureSlice(m["topShareholders"])
|
||||
}
|
||||
if _, ok := m["listedManagers"]; !ok {
|
||||
m["listedManagers"] = []interface{}{}
|
||||
} else {
|
||||
m["listedManagers"] = ensureSlice(m["listedManagers"])
|
||||
}
|
||||
return m
|
||||
}
|
||||
return map[string]interface{}{
|
||||
"isListed": false,
|
||||
"company": map[string]interface{}{
|
||||
"bizScope": "", "creditCode": "", "regAddr": "", "regCapital": "",
|
||||
"orgCode": "", "cur": "", "curName": "",
|
||||
},
|
||||
"stock": nil,
|
||||
"topShareholders": []interface{}{},
|
||||
"listedManagers": []interface{}{},
|
||||
}
|
||||
}
|
||||
|
||||
func mergeTaxViolationsDefaults(v interface{}) map[string]interface{} {
|
||||
out, _ := v.(map[string]interface{})
|
||||
if out == nil {
|
||||
out = map[string]interface{}{}
|
||||
}
|
||||
if _, ok := out["total"]; !ok {
|
||||
out["total"] = 0
|
||||
}
|
||||
if _, ok := out["items"]; !ok {
|
||||
out["items"] = []interface{}{}
|
||||
} else {
|
||||
out["items"] = ensureSlice(out["items"])
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func mergeOwnTaxNoticesDefaults(v interface{}) map[string]interface{} {
|
||||
return mergeTaxViolationsDefaults(v)
|
||||
}
|
||||
|
||||
func mergeRiskOverviewDefaults(v interface{}) map[string]interface{} {
|
||||
out, _ := v.(map[string]interface{})
|
||||
if out == nil {
|
||||
out = map[string]interface{}{}
|
||||
}
|
||||
if _, ok := out["riskLevel"]; !ok {
|
||||
out["riskLevel"] = "低"
|
||||
}
|
||||
if _, ok := out["riskScore"]; !ok {
|
||||
out["riskScore"] = 100
|
||||
}
|
||||
if _, ok := out["tags"]; !ok {
|
||||
out["tags"] = []interface{}{}
|
||||
} else {
|
||||
out["tags"] = ensureSlice(out["tags"])
|
||||
}
|
||||
if _, ok := out["items"]; !ok {
|
||||
out["items"] = []interface{}{}
|
||||
} else {
|
||||
out["items"] = ensureSlice(out["items"])
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func ensureStrKeys(m map[string]interface{}, keys []string) {
|
||||
if m == nil {
|
||||
return
|
||||
}
|
||||
for _, k := range keys {
|
||||
if _, ok := m[k]; !ok {
|
||||
m[k] = ""
|
||||
} else if m[k] == nil {
|
||||
m[k] = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// qyglJ1U9ReportHasSubstantiveData 判断合并后的报告是否至少含一项可展示的企业要素。
|
||||
// 当所有子数据源均失败或等价于无数据时返回 false,用于 QYGLJ1U9 整体返回「查询为空」。
|
||||
func qyglJ1U9ReportHasSubstantiveData(report map[string]interface{}) bool {
|
||||
if report == nil {
|
||||
return false
|
||||
}
|
||||
trim := func(v interface{}) string { return strings.TrimSpace(str(v)) }
|
||||
|
||||
basic, _ := report["basic"].(map[string]interface{})
|
||||
if basic != nil {
|
||||
if trim(basic["entName"]) != "" || trim(basic["creditCode"]) != "" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
if trim(report["entName"]) != "" || trim(report["creditCode"]) != "" {
|
||||
return true
|
||||
}
|
||||
if ar, ok := report["annualReports"].([]interface{}); ok && len(ar) > 0 {
|
||||
return true
|
||||
}
|
||||
if tv, ok := report["taxViolations"].(map[string]interface{}); ok {
|
||||
if intFromAny(tv["total"]) > 0 {
|
||||
return true
|
||||
}
|
||||
if items, ok := tv["items"].([]interface{}); ok && len(items) > 0 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
if ot, ok := report["ownTaxNotices"].(map[string]interface{}); ok {
|
||||
if intFromAny(ot["total"]) > 0 {
|
||||
return true
|
||||
}
|
||||
if items, ok := ot["items"].([]interface{}); ok && len(items) > 0 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
if br, ok := report["branches"].([]interface{}); ok && len(br) > 0 {
|
||||
return true
|
||||
}
|
||||
if bl, ok := report["basicList"].([]interface{}); ok && len(bl) > 0 {
|
||||
return true
|
||||
}
|
||||
if sh, ok := report["shareholding"].(map[string]interface{}); ok {
|
||||
if arr, ok := sh["shareholders"].([]interface{}); ok && len(arr) > 0 {
|
||||
return true
|
||||
}
|
||||
if intFromAny(sh["shareholderCount"]) > 0 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
if inv, ok := report["investments"].(map[string]interface{}); ok {
|
||||
if arr, ok := inv["list"].([]interface{}); ok && len(arr) > 0 {
|
||||
return true
|
||||
}
|
||||
if intFromAny(inv["totalCount"]) > 0 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
if ben, ok := report["beneficiaries"].([]interface{}); ok && len(ben) > 0 {
|
||||
return true
|
||||
}
|
||||
if tl, ok := report["timeline"].([]interface{}); ok && len(tl) > 0 {
|
||||
return true
|
||||
}
|
||||
if ctl, _ := report["controller"].(map[string]interface{}); ctl != nil && trim(ctl["name"]) != "" {
|
||||
return true
|
||||
}
|
||||
if risks, ok := report["risks"].(map[string]interface{}); ok {
|
||||
for _, key := range []string{
|
||||
"dishonestDebtors", "limitHighDebtors", "adminPenalties", "exceptions",
|
||||
"seriousIllegals", "mortgages", "courtJudgments", "judicialAssists",
|
||||
} {
|
||||
if arr, ok := risks[key].([]interface{}); ok && len(arr) > 0 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
if lit, ok := risks["litigation"].(map[string]interface{}); ok {
|
||||
for _, v := range lit {
|
||||
sub, ok := v.(map[string]interface{})
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if arr, ok := sub["cases"].([]interface{}); ok && len(arr) > 0 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// jiguangWithoutYearReportTables 浅拷贝全量 map,并去掉企业全量 V2 中与「公示年报」对应的 YEARREPORT* 键。
|
||||
// 在已接入 QYGLDJ12 且年报列表非空时使用,避免 build 与 HTML 中与「十六、企业年报」重复展示。
|
||||
func jiguangWithoutYearReportTables(jiguang map[string]interface{}) map[string]interface{} {
|
||||
|
||||
Reference in New Issue
Block a user