@yjzf/mcp-server-yjzf 0.2.5 → 0.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/dist/index.js +20 -9
  2. package/dist/index.js.map +1 -1
  3. package/dist/tools/contract/investment_contract.d.ts +8 -0
  4. package/dist/tools/contract/investment_contract.d.ts.map +1 -0
  5. package/dist/tools/contract/investment_contract.js +100 -0
  6. package/dist/tools/contract/investment_contract.js.map +1 -0
  7. package/dist/tools/contract/lease_sale_contract_export.d.ts +30 -0
  8. package/dist/tools/contract/lease_sale_contract_export.d.ts.map +1 -0
  9. package/dist/tools/contract/lease_sale_contract_export.js +171 -0
  10. package/dist/tools/contract/lease_sale_contract_export.js.map +1 -0
  11. package/dist/tools/contract/new_house_contract_export.d.ts +14 -0
  12. package/dist/tools/contract/new_house_contract_export.d.ts.map +1 -0
  13. package/dist/tools/contract/new_house_contract_export.js +205 -0
  14. package/dist/tools/contract/new_house_contract_export.js.map +1 -0
  15. package/dist/tools/data/count_all_statement.d.ts +46 -0
  16. package/dist/tools/data/count_all_statement.d.ts.map +1 -0
  17. package/dist/tools/data/count_all_statement.js +322 -0
  18. package/dist/tools/data/count_all_statement.js.map +1 -0
  19. package/dist/tools/data/overview_by_c.d.ts +26 -0
  20. package/dist/tools/data/overview_by_c.d.ts.map +1 -0
  21. package/dist/tools/data/overview_by_c.js +190 -0
  22. package/dist/tools/data/overview_by_c.js.map +1 -0
  23. package/dist/tools/data/statement_query.d.ts +43 -0
  24. package/dist/tools/data/statement_query.d.ts.map +1 -0
  25. package/dist/tools/data/statement_query.js +430 -0
  26. package/dist/tools/data/statement_query.js.map +1 -0
  27. package/dist/tools/util/branch_select.d.ts +26 -0
  28. package/dist/tools/util/branch_select.d.ts.map +1 -0
  29. package/dist/tools/util/branch_select.js +50 -0
  30. package/dist/tools/util/branch_select.js.map +1 -0
  31. package/dist/tools/util/date_to_timestamp.d.ts +19 -0
  32. package/dist/tools/util/date_to_timestamp.d.ts.map +1 -0
  33. package/dist/tools/util/date_to_timestamp.js +45 -0
  34. package/dist/tools/util/date_to_timestamp.js.map +1 -0
  35. package/dist/tools/util/get_current_time.d.ts +13 -0
  36. package/dist/tools/util/get_current_time.d.ts.map +1 -0
  37. package/dist/tools/util/get_current_time.js +23 -0
  38. package/dist/tools/util/get_current_time.js.map +1 -0
  39. package/dist/tools/util/hello_world.d.ts +20 -0
  40. package/dist/tools/util/hello_world.d.ts.map +1 -0
  41. package/dist/tools/util/hello_world.js +47 -0
  42. package/dist/tools/util/hello_world.js.map +1 -0
  43. package/dist/utils/async-export.d.ts +37 -0
  44. package/dist/utils/async-export.d.ts.map +1 -0
  45. package/dist/utils/async-export.js +73 -0
  46. package/dist/utils/async-export.js.map +1 -0
  47. package/dist/utils/cities.d.ts +11 -0
  48. package/dist/utils/cities.d.ts.map +1 -0
  49. package/dist/utils/cities.js +22 -0
  50. package/dist/utils/cities.js.map +1 -0
  51. package/dist/utils/http.d.ts.map +1 -1
  52. package/dist/utils/http.js +4 -0
  53. package/dist/utils/http.js.map +1 -1
  54. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,26 +1,35 @@
1
1
  #!/usr/bin/env node
2
+ import { createRequire } from "node:module";
2
3
  import * as path from "node:path";
3
4
  import { fileURLToPath } from "node:url";
4
5
  import dotenv from "dotenv";
5
6
  // 以脚本自身位置为基准加载 .env,避免因 cwd 不同导致环境变量丢失
6
7
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
7
8
  dotenv.config({ path: path.resolve(__dirname, "../.env"), quiet: true });
9
+ const require = createRequire(import.meta.url);
10
+ const { version } = require("../package.json");
8
11
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
9
12
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
10
- import * as helloWorldTool from "./tools/hello_world.js";
11
- import * as overviewByCTool from "./tools/overview_by_c.js";
12
- import * as countAllStatementTool from "./tools/count_all_statement.js";
13
- import * as getCurrentTimeTool from "./tools/get_current_time.js";
14
- import * as dateToTimestampTool from "./tools/date_to_timestamp.js";
15
- import * as investmentContractExportTool from "./tools/investment_contract.js";
16
- import * as newHouseContractExportTool from "./tools/new_house_contract_export.js";
17
- import * as statementQueryTool from "./tools/statement_query.js";
13
+ import * as helloWorldTool from "./tools/util/hello_world.js";
14
+ import * as overviewByCTool from "./tools/data/overview_by_c.js";
15
+ import * as countAllStatementTool from "./tools/data/count_all_statement.js";
16
+ import * as getCurrentTimeTool from "./tools/util/get_current_time.js";
17
+ import * as dateToTimestampTool from "./tools/util/date_to_timestamp.js";
18
+ import * as investmentContractExportTool from "./tools/contract/investment_contract.js";
19
+ import * as newHouseContractExportTool from "./tools/contract/new_house_contract_export.js";
20
+ import * as statementQueryTool from "./tools/data/statement_query.js";
21
+ import * as branchSelectTool from "./tools/util/branch_select.js";
22
+ import * as leaseSaleContractExportTool from "./tools/contract/lease_sale_contract_export.js";
18
23
  // ---------------------------------------------------------------------------
19
24
  // MCP Server
20
25
  // ---------------------------------------------------------------------------
21
26
  const server = new McpServer({
22
27
  name: "mcp-server-yjzf",
23
- version: "0.1.0",
28
+ version,
29
+ title: "U+优居找房数据助手",
30
+ description: "优居找房(U+)房地产交易平台数据查询与导出服务,支持经营指标报表、招商合同、新房合同、C端行为数据等。",
31
+ }, {
32
+ instructions: "本服务属于「U+优居找房」平台(品牌名:U+),请始终使用此名称,不要自行命名。",
24
33
  });
25
34
  server.registerTool(helloWorldTool.name, helloWorldTool.schema, helloWorldTool.handler);
26
35
  server.registerTool(overviewByCTool.name, overviewByCTool.schema, overviewByCTool.handler);
@@ -30,6 +39,8 @@ server.registerTool(dateToTimestampTool.name, dateToTimestampTool.schema, dateTo
30
39
  server.registerTool(investmentContractExportTool.name, investmentContractExportTool.schema, investmentContractExportTool.handler);
31
40
  server.registerTool(newHouseContractExportTool.name, newHouseContractExportTool.schema, newHouseContractExportTool.handler);
32
41
  server.registerTool(statementQueryTool.name, statementQueryTool.schema, statementQueryTool.handler);
42
+ server.registerTool(branchSelectTool.name, branchSelectTool.schema, branchSelectTool.handler);
43
+ server.registerTool(leaseSaleContractExportTool.name, leaseSaleContractExportTool.schema, leaseSaleContractExportTool.handler);
33
44
  // ---------------------------------------------------------------------------
34
45
  // Start
35
46
  // ---------------------------------------------------------------------------
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B,uCAAuC;AACvC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC/D,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,SAAS,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AAEzE,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,KAAK,cAAc,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,eAAe,MAAM,0BAA0B,CAAC;AAC5D,OAAO,KAAK,qBAAqB,MAAM,gCAAgC,CAAC;AACxE,OAAO,KAAK,kBAAkB,MAAM,6BAA6B,CAAC;AAClE,OAAO,KAAK,mBAAmB,MAAM,8BAA8B,CAAC;AACpE,OAAO,KAAK,4BAA4B,MAAM,gCAAgC,CAAC;AAC/E,OAAO,KAAK,0BAA0B,MAAM,sCAAsC,CAAC;AACnF,OAAO,KAAK,kBAAkB,MAAM,4BAA4B,CAAC;AAEjE,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;IAC3B,IAAI,EAAE,iBAAiB;IACvB,OAAO,EAAE,OAAO;CACjB,CAAC,CAAC;AAEH,MAAM,CAAC,YAAY,CACjB,cAAc,CAAC,IAAI,EACnB,cAAc,CAAC,MAAM,EACrB,cAAc,CAAC,OAAO,CACvB,CAAC;AAEF,MAAM,CAAC,YAAY,CACjB,eAAe,CAAC,IAAI,EACpB,eAAe,CAAC,MAAM,EACtB,eAAe,CAAC,OAAO,CACxB,CAAC;AAEF,MAAM,CAAC,YAAY,CACjB,qBAAqB,CAAC,IAAI,EAC1B,qBAAqB,CAAC,MAAM,EAC5B,qBAAqB,CAAC,OAAO,CAC9B,CAAC;AAEF,MAAM,CAAC,YAAY,CACjB,kBAAkB,CAAC,IAAI,EACvB,kBAAkB,CAAC,MAAM,EACzB,kBAAkB,CAAC,OAAO,CAC3B,CAAC;AAEF,MAAM,CAAC,YAAY,CACjB,mBAAmB,CAAC,IAAI,EACxB,mBAAmB,CAAC,MAAM,EAC1B,mBAAmB,CAAC,OAAO,CAC5B,CAAC;AAEF,MAAM,CAAC,YAAY,CACjB,4BAA4B,CAAC,IAAI,EACjC,4BAA4B,CAAC,MAAM,EACnC,4BAA4B,CAAC,OAAO,CACrC,CAAC;AAEF,MAAM,CAAC,YAAY,CACjB,0BAA0B,CAAC,IAAI,EAC/B,0BAA0B,CAAC,MAAM,EACjC,0BAA0B,CAAC,OAAO,CACnC,CAAC;AAEF,MAAM,CAAC,YAAY,CACjB,kBAAkB,CAAC,IAAI,EACvB,kBAAkB,CAAC,MAAM,EACzB,kBAAkB,CAAC,OAAO,CAC3B,CAAC;AAEF,8EAA8E;AAC9E,QAAQ;AACR,8EAA8E;AAE9E,KAAK,UAAU,IAAI;IACjB,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import * as z from "zod/v4";
2
+ export declare const name = "investment_contract";
3
+ export declare const schema: {
4
+ description: string;
5
+ inputSchema: z.ZodObject<{}, z.core.$strip>;
6
+ };
7
+ export declare function handler(): Promise<import("../../utils/http.js").ToolResult>;
8
+ //# sourceMappingURL=investment_contract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"investment_contract.d.ts","sourceRoot":"","sources":["../../../src/tools/contract/investment_contract.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AA4E5B,eAAO,MAAM,IAAI,wBAAwB,CAAC;AAE1C,eAAO,MAAM,MAAM;;;CAGlB,CAAC;AAEF,wBAAsB,OAAO,sDA4D5B"}
@@ -0,0 +1,100 @@
1
+ import * as z from "zod/v4";
2
+ import { buildGatewayHeaders, createErrorResult, createSuccessResult } from "../../utils/http.js";
3
+ import { saveWorkbook, formatTimestamp } from "../../utils/excel.js";
4
+ import { generateDatedFileName, getGatewayBaseUrl } from "../../utils/env.js";
5
+ import { debug } from "../../utils/debug.js";
6
+ import { fetchZyCities } from "../../utils/cities.js";
7
+ // ---------------------------------------------------------------------------
8
+ // 枚举映射
9
+ // ---------------------------------------------------------------------------
10
+ const LOCKING_STATE_MAP = {
11
+ 1: "是",
12
+ 0: "否",
13
+ };
14
+ const CONTRACT_STATE_MAP = {
15
+ 1: "审核通过",
16
+ 2: "审核否决",
17
+ 3: "待审核",
18
+ 4: "草稿",
19
+ 5: "已撤回",
20
+ 6: "已回收",
21
+ 8: "已签署",
22
+ };
23
+ const SIGN_METHOD_MAP = {
24
+ 1: "线上",
25
+ 2: "线下",
26
+ };
27
+ const ORDER_STATUS_MAP = {
28
+ 0: "已关闭",
29
+ 1: "跟进中",
30
+ 2: "已完成",
31
+ };
32
+ const COLUMNS = [
33
+ ["城市", "cityName"],
34
+ ["锁定状态", "lockingState", (v) => LOCKING_STATE_MAP[Number(v)] ?? ""],
35
+ ["合同名称", "title"],
36
+ ["合同编号", "econtractNo"],
37
+ ["合同状态", "state", (v) => CONTRACT_STATE_MAP[Number(v)] ?? String(v)],
38
+ ["甲方", "companyA"],
39
+ ["乙方", "companyB"],
40
+ ["签署方式", "isOutside", (v) => SIGN_METHOD_MAP[Number(v)] ?? String(v)],
41
+ ["剩余打印次数", "plusPrintNumber"],
42
+ ["关联订单编号", "linkOrderNo"],
43
+ ["对应订单状态", "orderStatus", (v) => ORDER_STATUS_MAP[Number(v)] ?? String(v)],
44
+ ["添加人", "createdBy"],
45
+ ["添加时间", "createTm", (v) => formatTimestamp(Number(v))],
46
+ ];
47
+ // ---------------------------------------------------------------------------
48
+ // 工具导出
49
+ // ---------------------------------------------------------------------------
50
+ export const name = "investment_contract";
51
+ export const schema = {
52
+ description: "从 ERP 系统查询直营城市招商加盟合同列表数据,生成 Excel 文件",
53
+ inputSchema: z.object({}),
54
+ };
55
+ export async function handler() {
56
+ const headers = buildGatewayHeaders();
57
+ try {
58
+ // Step 1: 获取城市列表
59
+ const cities = await fetchZyCities();
60
+ debug("zy_cities", cities);
61
+ // Step 2: 调用 Gateway 获取合同数据
62
+ const response = await fetch(`${getGatewayBaseUrl()}/investment_contract`, {
63
+ method: "POST",
64
+ headers,
65
+ body: JSON.stringify({ cities }),
66
+ });
67
+ if (!response.ok) {
68
+ return createErrorResult(`请求 investment_contract 失败: ${response.status} ${response.statusText}`);
69
+ }
70
+ const apiResponse = await response.json();
71
+ debug("investment_contract response", apiResponse);
72
+ if (!apiResponse.succeed) {
73
+ return createErrorResult(`网关返回错误: ${apiResponse.msg}`);
74
+ }
75
+ const { list } = apiResponse.data;
76
+ if (list.length === 0) {
77
+ return createSuccessResult("未查询到任何合同数据");
78
+ }
79
+ // Step 3: 构建 Excel 数据
80
+ const headerRow = COLUMNS.map(([label]) => label);
81
+ const dataRows = list.map((item) => COLUMNS.map(([, field, transform]) => {
82
+ const val = item[field];
83
+ if (transform) {
84
+ return transform(val);
85
+ }
86
+ return val != null ? String(val) : "";
87
+ }));
88
+ const sheetData = [headerRow, ...dataRows];
89
+ // Step 4: 保存 Excel 文件
90
+ const fileName = generateDatedFileName("招商加盟合同列表导出", "xlsx", false);
91
+ const sheets = [{ name: "合同数据", data: sheetData }];
92
+ const filePath = saveWorkbook(sheets, fileName);
93
+ return createSuccessResult(`成功导出招商加盟合同数据!\n共 ${list.length} 条记录\n文件路径: ${filePath}`);
94
+ }
95
+ catch (error) {
96
+ const errorMessage = error instanceof Error ? error.message : String(error);
97
+ return createErrorResult(`执行过程中发生错误: ${errorMessage}`);
98
+ }
99
+ }
100
+ //# sourceMappingURL=investment_contract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"investment_contract.js","sourceRoot":"","sources":["../../../src/tools/contract/investment_contract.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAClG,OAAO,EAAE,YAAY,EAAE,eAAe,EAAiB,MAAM,sBAAsB,CAAC;AACpF,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC9E,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEtD,8EAA8E;AAC9E,OAAO;AACP,8EAA8E;AAE9E,MAAM,iBAAiB,GAA2B;IAChD,CAAC,EAAE,GAAG;IACN,CAAC,EAAE,GAAG;CACP,CAAC;AAEF,MAAM,kBAAkB,GAA2B;IACjD,CAAC,EAAE,MAAM;IACT,CAAC,EAAE,MAAM;IACT,CAAC,EAAE,KAAK;IACR,CAAC,EAAE,IAAI;IACP,CAAC,EAAE,KAAK;IACR,CAAC,EAAE,KAAK;IACR,CAAC,EAAE,KAAK;CACT,CAAC;AAEF,MAAM,eAAe,GAA2B;IAC9C,CAAC,EAAE,IAAI;IACP,CAAC,EAAE,IAAI;CACR,CAAC;AAEF,MAAM,gBAAgB,GAA2B;IAC/C,CAAC,EAAE,KAAK;IACR,CAAC,EAAE,KAAK;IACR,CAAC,EAAE,KAAK;CACT,CAAC;AAQF,MAAM,OAAO,GAAgB;IAC3B,CAAC,IAAI,EAAE,UAAU,CAAC;IAClB,CAAC,MAAM,EAAE,cAAc,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACnE,CAAC,MAAM,EAAE,OAAO,CAAC;IACjB,CAAC,MAAM,EAAE,aAAa,CAAC;IACvB,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC;IACpE,CAAC,IAAI,EAAE,UAAU,CAAC;IAClB,CAAC,IAAI,EAAE,UAAU,CAAC;IAClB,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC;IACrE,CAAC,QAAQ,EAAE,iBAAiB,CAAC;IAC7B,CAAC,QAAQ,EAAE,aAAa,CAAC;IACzB,CAAC,QAAQ,EAAE,aAAa,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC;IAC1E,CAAC,KAAK,EAAE,WAAW,CAAC;IACpB,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;CACxD,CAAC;AAeF,8EAA8E;AAC9E,OAAO;AACP,8EAA8E;AAE9E,MAAM,CAAC,MAAM,IAAI,GAAG,qBAAqB,CAAC;AAE1C,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,WAAW,EAAE,sCAAsC;IACnD,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;CAC1B,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,OAAO;IAC3B,MAAM,OAAO,GAAG,mBAAmB,EAAE,CAAC;IAEtC,IAAI,CAAC;QACH,iBAAiB;QACjB,MAAM,MAAM,GAAG,MAAM,aAAa,EAAE,CAAC;QACrC,KAAK,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QAE3B,4BAA4B;QAC5B,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,iBAAiB,EAAE,sBAAsB,EAAE;YACzE,MAAM,EAAE,MAAM;YACd,OAAO;YACP,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;SACjC,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,OAAO,iBAAiB,CACtB,8BAA8B,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CACvE,CAAC;QACJ,CAAC;QAED,MAAM,WAAW,GAA4B,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnE,KAAK,CAAC,8BAA8B,EAAE,WAAW,CAAC,CAAC;QAEnD,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC;YACzB,OAAO,iBAAiB,CAAC,WAAW,WAAW,CAAC,GAAG,EAAE,CAAC,CAAC;QACzD,CAAC;QAED,MAAM,EAAE,IAAI,EAAE,GAAG,WAAW,CAAC,IAAI,CAAC;QAElC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO,mBAAmB,CAAC,YAAY,CAAC,CAAC;QAC3C,CAAC;QAED,sBAAsB;QACtB,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC;QAClD,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CACjC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,EAAE,EAAE;YACnC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;YACxB,IAAI,SAAS,EAAE,CAAC;gBACd,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC;YACxB,CAAC;YACD,OAAO,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACxC,CAAC,CAAC,CACH,CAAC;QAEF,MAAM,SAAS,GAA0B,CAAC,SAAS,EAAE,GAAG,QAAQ,CAAC,CAAC;QAElE,sBAAsB;QACtB,MAAM,QAAQ,GAAG,qBAAqB,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;QACpE,MAAM,MAAM,GAAe,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;QAC/D,MAAM,QAAQ,GAAG,YAAY,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QAEhD,OAAO,mBAAmB,CACxB,oBAAoB,IAAI,CAAC,MAAM,eAAe,QAAQ,EAAE,CACzD,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,YAAY,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC5E,OAAO,iBAAiB,CAAC,cAAc,YAAY,EAAE,CAAC,CAAC;IACzD,CAAC;AACH,CAAC"}
@@ -0,0 +1,30 @@
1
+ import * as z from "zod/v4";
2
+ type Action = "get_contract_types" | "export";
3
+ interface ContractDataReportArgs {
4
+ action: Action;
5
+ branchId: string;
6
+ cityCode: string;
7
+ branchName: string;
8
+ contractTypeList?: string[];
9
+ signTmStart?: number;
10
+ signTmEnd?: number;
11
+ }
12
+ export declare const name = "lease_sale_contract_export";
13
+ export declare const schema: {
14
+ description: string;
15
+ inputSchema: z.ZodObject<{
16
+ action: z.ZodEnum<{
17
+ get_contract_types: "get_contract_types";
18
+ export: "export";
19
+ }>;
20
+ branchId: z.ZodString;
21
+ cityCode: z.ZodString;
22
+ branchName: z.ZodString;
23
+ contractTypeList: z.ZodOptional<z.ZodArray<z.ZodString>>;
24
+ signTmStart: z.ZodOptional<z.ZodNumber>;
25
+ signTmEnd: z.ZodOptional<z.ZodNumber>;
26
+ }, z.core.$strip>;
27
+ };
28
+ export declare function handler(args: ContractDataReportArgs): Promise<import("../../utils/http.js").ToolResult>;
29
+ export {};
30
+ //# sourceMappingURL=lease_sale_contract_export.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lease_sale_contract_export.d.ts","sourceRoot":"","sources":["../../../src/tools/contract/lease_sale_contract_export.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAU5B,KAAK,MAAM,GAAG,oBAAoB,GAAG,QAAQ,CAAC;AAE9C,UAAU,sBAAsB;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AA6CD,eAAO,MAAM,IAAI,+BAA+B,CAAC;AAEjD,eAAO,MAAM,MAAM;;;;;;;;;;;;;;CAuBlB,CAAC;AAEF,wBAAsB,OAAO,CAAC,IAAI,EAAE,sBAAsB,qDASzD"}
@@ -0,0 +1,171 @@
1
+ import * as z from "zod/v4";
2
+ import { buildGatewayHeaders, createErrorResult, createSuccessResult } from "../../utils/http.js";
3
+ import { getGatewayBaseUrl, generateDatedFileName } from "../../utils/env.js";
4
+ import { debug } from "../../utils/debug.js";
5
+ import { pollAsyncExport, downloadToDataDir } from "../../utils/async-export.js";
6
+ // ---------------------------------------------------------------------------
7
+ // 常量
8
+ // ---------------------------------------------------------------------------
9
+ const ONE_YEAR_MS = 365 * 24 * 60 * 60 * 1000;
10
+ // ---------------------------------------------------------------------------
11
+ // 工具函数
12
+ // ---------------------------------------------------------------------------
13
+ /**
14
+ * 获取默认签单日期范围:12个月前次日 00:00:00 → 今天 23:59:59.999
15
+ */
16
+ function getDefaultSignTimeRange() {
17
+ const now = new Date();
18
+ const start = new Date(now.getFullYear(), now.getMonth() - 12, now.getDate() + 1, 0, 0, 0, 0);
19
+ const end = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 23, 59, 59, 999);
20
+ return {
21
+ startTime: start.getTime(),
22
+ endTime: end.getTime(),
23
+ };
24
+ }
25
+ /**
26
+ * 生成唯一 fileName,用于在导出状态列表中精确匹配
27
+ */
28
+ function generateUniqueExportName() {
29
+ const ts = Date.now();
30
+ const rand = Math.random().toString(36).slice(2, 6);
31
+ return `MCP_租售合同(成交数据表)_${ts}_${rand}`;
32
+ }
33
+ // ---------------------------------------------------------------------------
34
+ // 工具导出
35
+ // ---------------------------------------------------------------------------
36
+ export const name = "lease_sale_contract_export";
37
+ export const schema = {
38
+ description: "从ERP系统导出租售合同(成交数据表)Excel文件。必须先调用 branch_select 获取 branchId 和 cityCode。支持2个action: get_contract_types获取合同类型选项, export执行导出。",
39
+ inputSchema: z.object({
40
+ action: z.enum(["get_contract_types", "export"])
41
+ .describe("要执行的动作"),
42
+ // 城市公司参数(所有 action 都需要,必须通过 branch_select 工具获取)
43
+ branchId: z.string()
44
+ .describe("城市公司ID(即organId),必须通过 branch_select 工具获取,禁止自行编造"),
45
+ cityCode: z.string()
46
+ .describe("城市编码,必须通过 branch_select 工具获取,禁止自行编造"),
47
+ branchName: z.string()
48
+ .describe("城市公司名称,必须通过 branch_select 工具获取,禁止自行编造"),
49
+ // 以下仅 export action 使用
50
+ contractTypeList: z.array(z.string()).optional()
51
+ .describe("合同类型列表,通过 get_contract_types 获取可选值"),
52
+ signTmStart: z.number().optional()
53
+ .describe("签单开始时间(毫秒时间戳),不传默认12个月前"),
54
+ signTmEnd: z.number().optional()
55
+ .describe("签单结束时间(毫秒时间戳),不传默认今天结束"),
56
+ }),
57
+ };
58
+ export async function handler(args) {
59
+ debug("lease_sale_contract_export args", args);
60
+ switch (args.action) {
61
+ case "get_contract_types":
62
+ return await fetchContractTypes(args.branchId, args.cityCode);
63
+ case "export":
64
+ return await executeExport(args);
65
+ }
66
+ }
67
+ // ---------------------------------------------------------------------------
68
+ // Action 实现
69
+ // ---------------------------------------------------------------------------
70
+ async function fetchContractTypes(branchId, cityCode) {
71
+ const headers = buildGatewayHeaders();
72
+ const resp = await fetch(`${getGatewayBaseUrl()}/lease_sale_contract/options`, {
73
+ method: "POST",
74
+ headers,
75
+ body: JSON.stringify({ branchId, cityCode }),
76
+ });
77
+ if (!resp.ok) {
78
+ return createErrorResult(`获取合同类型选项失败: ${resp.status} ${resp.statusText}`);
79
+ }
80
+ const data = await resp.json();
81
+ debug("fetchContractTypes response", data);
82
+ if (!data.succeed) {
83
+ return createErrorResult(`获取合同类型选项失败: ${data.msg}`);
84
+ }
85
+ return {
86
+ content: [{ type: "text", text: JSON.stringify(data.data) }],
87
+ };
88
+ }
89
+ async function executeExport(args) {
90
+ const { branchId, cityCode } = args;
91
+ // 签单日期默认值
92
+ const defaults = getDefaultSignTimeRange();
93
+ const signTmStart = args.signTmStart ?? defaults.startTime;
94
+ const signTmEnd = args.signTmEnd ?? defaults.endTime;
95
+ // 校验签单日期范围不超过1年
96
+ if (signTmEnd - signTmStart > ONE_YEAR_MS) {
97
+ return createErrorResult("签单日期范围最长1年");
98
+ }
99
+ // 生成唯一 fileName 用于状态匹配
100
+ const uniqueName = generateUniqueExportName();
101
+ debug("export uniqueName", uniqueName);
102
+ const headers = buildGatewayHeaders();
103
+ const gatewayBaseUrl = getGatewayBaseUrl();
104
+ // 提交导出任务(roleType 由 Gateway 内部固定为全公司)
105
+ const exportBody = {
106
+ branchId,
107
+ cityCode,
108
+ contractTypeList: args.contractTypeList ?? [],
109
+ signTmStart,
110
+ signTmEnd,
111
+ fileName: uniqueName,
112
+ };
113
+ debug("export body", exportBody);
114
+ const submitResp = await fetch(`${gatewayBaseUrl}/lease_sale_contract/export`, {
115
+ method: "POST",
116
+ headers,
117
+ body: JSON.stringify(exportBody),
118
+ });
119
+ if (!submitResp.ok) {
120
+ return createErrorResult(`提交导出任务失败: ${submitResp.status} ${submitResp.statusText}`);
121
+ }
122
+ const submitResult = await submitResp.json();
123
+ debug("export submit result", submitResult);
124
+ if (!submitResult.succeed) {
125
+ return createErrorResult(`提交导出任务失败: ${submitResult.msg}`);
126
+ }
127
+ // 轮询导出状态
128
+ try {
129
+ const submittedAt = Date.now();
130
+ const downloadUrl = await pollAsyncExport({
131
+ logTag: "lease_sale_contract",
132
+ checkStatus: async () => {
133
+ const statusBody = {
134
+ branchId,
135
+ cityCode,
136
+ startInc: submittedAt - 5 * 60 * 1000,
137
+ endExc: Date.now(),
138
+ };
139
+ const statusResp = await fetch(`${gatewayBaseUrl}/lease_sale_contract/export_status`, {
140
+ method: "POST",
141
+ headers,
142
+ body: JSON.stringify(statusBody),
143
+ });
144
+ if (!statusResp.ok) {
145
+ throw new Error(`查询导出状态失败: ${statusResp.status}`);
146
+ }
147
+ const statusData = await statusResp.json();
148
+ if (!statusData.succeed) {
149
+ throw new Error("查询导出状态接口返回失败");
150
+ }
151
+ const match = statusData.data?.find((item) => item.fileName === uniqueName);
152
+ if (!match || !match.finishTm) {
153
+ return { state: "pending" };
154
+ }
155
+ if (match.source) {
156
+ return { state: "success", downloadUrl: match.source };
157
+ }
158
+ return { state: "failed", reason: "ERP导出任务执行失败" };
159
+ },
160
+ });
161
+ // 下载文件(命名格式:日期_时间_城市名_报表名.xlsx)
162
+ const localFileName = generateDatedFileName(`${args.branchName}_租售合同(成交数据表)`, "xlsx", false);
163
+ const filePath = await downloadToDataDir(downloadUrl, localFileName);
164
+ return createSuccessResult(`成功导出租售合同(成交数据表)!\n文件路径: ${filePath}`);
165
+ }
166
+ catch (error) {
167
+ const errorMessage = error instanceof Error ? error.message : String(error);
168
+ return createErrorResult(`导出过程中发生错误: ${errorMessage}`);
169
+ }
170
+ }
171
+ //# sourceMappingURL=lease_sale_contract_export.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lease_sale_contract_export.js","sourceRoot":"","sources":["../../../src/tools/contract/lease_sale_contract_export.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import * as z from "zod/v4";
2
+ export declare const name = "new_house_contract_export";
3
+ export declare const schema: {
4
+ description: string;
5
+ inputSchema: z.ZodObject<{
6
+ startTime: z.ZodOptional<z.ZodNumber>;
7
+ endTime: z.ZodOptional<z.ZodNumber>;
8
+ }, z.core.$strip>;
9
+ };
10
+ export declare function handler(args: {
11
+ startTime?: number;
12
+ endTime?: number;
13
+ }): Promise<import("../../utils/http.js").ToolResult>;
14
+ //# sourceMappingURL=new_house_contract_export.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"new_house_contract_export.d.ts","sourceRoot":"","sources":["../../../src/tools/contract/new_house_contract_export.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AA+G5B,eAAO,MAAM,IAAI,8BAA8B,CAAC;AAEhD,eAAO,MAAM,MAAM;;;;;;CAalB,CAAC;AAEF,wBAAsB,OAAO,CAAC,IAAI,EAAE;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB,qDAgJA"}
@@ -0,0 +1,205 @@
1
+ import * as fs from "node:fs";
2
+ import * as path from "node:path";
3
+ import * as z from "zod/v4";
4
+ import { buildGatewayHeaders, createErrorResult, createSuccessResult } from "../../utils/http.js";
5
+ import { getDataDir, getGatewayBaseUrl } from "../../utils/env.js";
6
+ import { debug } from "../../utils/debug.js";
7
+ import { pollAsyncExport, downloadToDataDir } from "../../utils/async-export.js";
8
+ // ---------------------------------------------------------------------------
9
+ // 常量
10
+ // ---------------------------------------------------------------------------
11
+ const BRAND_ID = "593347894961426496";
12
+ const CITY_CODE = "450100";
13
+ const ORGAN_ID = "625864877560328320";
14
+ // const BRAND_ID = "565998180494215232";
15
+ // const CITY_CODE = "450100";
16
+ // const ORGAN_ID = "552692373611008128";
17
+ // ---------------------------------------------------------------------------
18
+ // 工具函数
19
+ // ---------------------------------------------------------------------------
20
+ /**
21
+ * 生成文件名:认购合同_20260423_1000.xlsx
22
+ */
23
+ function buildFileName(label) {
24
+ const now = new Date();
25
+ const Y = now.getFullYear();
26
+ const M = String(now.getMonth() + 1).padStart(2, "0");
27
+ const D = String(now.getDate()).padStart(2, "0");
28
+ const h = String(now.getHours()).padStart(2, "0");
29
+ const m = String(now.getMinutes()).padStart(2, "0");
30
+ return `${label}_${Y}${M}${D}_${h}${m}.xlsx`;
31
+ }
32
+ /**
33
+ * 获取默认时间范围:当月第一天 00:00:00 ~ 今天 23:59:59.999(本地时间)。
34
+ */
35
+ function getDefaultTimeRange() {
36
+ const now = new Date();
37
+ const monthStart = new Date(now.getFullYear(), now.getMonth(), 1);
38
+ const todayEnd = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 23, 59, 59, 999);
39
+ return {
40
+ startTime: monthStart.getTime(),
41
+ endTime: todayEnd.getTime(),
42
+ };
43
+ }
44
+ /**
45
+ * 将 base64 编码的 Excel 数据保存为文件,返回文件绝对路径。
46
+ */
47
+ function saveBase64ToFile(base64Data, fileName) {
48
+ const dataDir = getDataDir();
49
+ fs.mkdirSync(dataDir, { recursive: true });
50
+ const filePath = path.join(dataDir, fileName);
51
+ const buffer = Buffer.from(base64Data, "base64");
52
+ fs.writeFileSync(filePath, buffer);
53
+ return filePath;
54
+ }
55
+ /**
56
+ * 判断时间范围是否超过3个月(基于日历月)。
57
+ */
58
+ function isRangeExceedsThreeMonths(startTime, endTime) {
59
+ const start = new Date(startTime);
60
+ const threeMonthsLater = new Date(start);
61
+ threeMonthsLater.setMonth(threeMonthsLater.getMonth() + 3);
62
+ return endTime > threeMonthsLater.getTime();
63
+ }
64
+ /**
65
+ * 生成唯一的 bookName,用于在异步导出列表中精确匹配。
66
+ */
67
+ function generateUniqueBookName(label) {
68
+ const ts = Date.now();
69
+ const rand = Math.random().toString(36).slice(2, 6);
70
+ return `MCP_${label}_${ts}_${rand}`;
71
+ }
72
+ // ---------------------------------------------------------------------------
73
+ // 工具导出
74
+ // ---------------------------------------------------------------------------
75
+ export const name = "new_house_contract_export";
76
+ export const schema = {
77
+ description: "从 ERP 系统导出新房合同数据(认购合同、签约合同、解约合同),生成三个独立的 Excel 文件。不传时间时默认查询当月第一天到今天。时间范围超过3个月时自动使用异步导出。",
78
+ inputSchema: z.object({
79
+ startTime: z
80
+ .number()
81
+ .optional()
82
+ .describe("开始时间,毫秒时间戳,可选,不传则默认当月第一天"),
83
+ endTime: z
84
+ .number()
85
+ .optional()
86
+ .describe("结束时间,毫秒时间戳,可选,不传则默认今天"),
87
+ }),
88
+ };
89
+ export async function handler(args) {
90
+ const headers = buildGatewayHeaders();
91
+ const defaults = getDefaultTimeRange();
92
+ const startTime = args.startTime ?? defaults.startTime;
93
+ const endTime = args.endTime ?? defaults.endTime;
94
+ debug("date range", { startTime, endTime });
95
+ // 校验时间范围
96
+ if (startTime > endTime) {
97
+ return createErrorResult("开始时间不能晚于结束时间");
98
+ }
99
+ const useAsync = isRangeExceedsThreeMonths(startTime, endTime);
100
+ if (useAsync) {
101
+ console.error(`[new_house_contract_export] 时间范围>3个月,使用异步导出模式`);
102
+ }
103
+ try {
104
+ // 分别导出认购合同、签约合同和解约合同
105
+ const contractTypes = [
106
+ { type: "subscription", label: "认购合同" },
107
+ { type: "signed", label: "签约合同" },
108
+ { type: "cancelled", label: "解约合同" },
109
+ ];
110
+ const results = [];
111
+ for (const ct of contractTypes) {
112
+ console.error(`[new_house_contract_export] 正在导出${ct.label}...`);
113
+ if (useAsync) {
114
+ // 异步导出路径
115
+ const bookName = generateUniqueBookName(ct.label);
116
+ console.error(`[async] bookName=${bookName}`);
117
+ // 1. 提交异步导出任务
118
+ const submitResp = await fetch(`${getGatewayBaseUrl()}/new_house_contract_async_export`, {
119
+ method: "POST",
120
+ headers,
121
+ body: JSON.stringify({
122
+ city_code: CITY_CODE,
123
+ organ_id: ORGAN_ID,
124
+ brand_id: BRAND_ID,
125
+ startTime,
126
+ endTime,
127
+ contractType: ct.type,
128
+ bookName,
129
+ }),
130
+ });
131
+ if (!submitResp.ok) {
132
+ return createErrorResult(`提交${ct.label}异步导出失败: ${submitResp.status} ${submitResp.statusText}`);
133
+ }
134
+ const submitResult = await submitResp.json();
135
+ if (!submitResult.succeed) {
136
+ return createErrorResult(`提交${ct.label}异步导出失败: ${submitResult.msg}`);
137
+ }
138
+ console.error(`[async] ${ct.label} 任务已提交,开始轮询...`);
139
+ // 2. 轮询等待完成
140
+ const fileUrl = await pollAsyncExport({
141
+ logTag: `new_house_contract_${ct.type}`,
142
+ checkStatus: async () => {
143
+ const statusResp = await fetch(`${getGatewayBaseUrl()}/new_house_contract_async_export_status`, {
144
+ method: "POST",
145
+ headers,
146
+ body: JSON.stringify({ city_code: CITY_CODE, organ_id: ORGAN_ID, brand_id: BRAND_ID }),
147
+ });
148
+ const json = await statusResp.json();
149
+ const match = json.data?.list?.find((item) => item.fileName === bookName);
150
+ if (!match)
151
+ return { state: "pending" };
152
+ if (match.status === 1)
153
+ return { state: "success", downloadUrl: match.fileUrl };
154
+ if (match.status === 0)
155
+ return { state: "failed", reason: `ERP异步导出失败: ${bookName}` };
156
+ return { state: "pending" };
157
+ },
158
+ });
159
+ // 3. 下载文件到本地
160
+ const fileName = buildFileName(ct.label);
161
+ const filePath = await downloadToDataDir(fileUrl, fileName);
162
+ results.push(`${ct.label}\n文件路径: ${filePath}`);
163
+ }
164
+ else {
165
+ // 同步导出路径
166
+ const response = await fetch(`${getGatewayBaseUrl()}/new_house_contract_export`, {
167
+ method: "POST",
168
+ headers,
169
+ body: JSON.stringify({
170
+ city_code: CITY_CODE,
171
+ organ_id: ORGAN_ID,
172
+ brand_id: BRAND_ID,
173
+ startTime,
174
+ endTime,
175
+ contractType: ct.type,
176
+ }),
177
+ });
178
+ if (!response.ok) {
179
+ return createErrorResult(`请求 ${ct.label} 导出失败: ${response.status} ${response.statusText}`);
180
+ }
181
+ const apiResponse = await response.json();
182
+ debug(`${ct.label} response`, {
183
+ succeed: apiResponse.succeed,
184
+ msg: apiResponse.msg,
185
+ });
186
+ if (!apiResponse.succeed) {
187
+ return createErrorResult(`${ct.label} 网关返回错误: ${apiResponse.msg}`);
188
+ }
189
+ if (!apiResponse.data?.base64) {
190
+ return createErrorResult(`${ct.label} 返回数据中缺少 base64 字段`);
191
+ }
192
+ // 直接保存原始 Excel 文件
193
+ const fileName = buildFileName(ct.label);
194
+ const filePath = saveBase64ToFile(apiResponse.data.base64, fileName);
195
+ results.push(`${ct.label}\n文件路径: ${filePath}`);
196
+ }
197
+ }
198
+ return createSuccessResult(`成功导出新房合同数据!\n\n${results.join("\n\n")}`);
199
+ }
200
+ catch (error) {
201
+ const errorMessage = error instanceof Error ? error.message : String(error);
202
+ return createErrorResult(`执行过程中发生错误: ${errorMessage}`);
203
+ }
204
+ }
205
+ //# sourceMappingURL=new_house_contract_export.js.map