From cf47ee13db7d0bfdfb1743cc0a83696d9c7182f0 Mon Sep 17 00:00:00 2001 From: ping <1017253325@qq.com> Date: Mon, 1 Jun 2026 15:01:37 +0800 Subject: [PATCH 1/5] =?UTF-8?q?update=20=E5=8D=87=E9=99=8D=E9=85=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- b/baiducloud/get_baidu_orderlist.dspy | 11 +++++++++-- b/bz_order/getbz_order.dspy | 2 +- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/b/baiducloud/get_baidu_orderlist.dspy b/b/baiducloud/get_baidu_orderlist.dspy index 5f9e2d0..0f246f7 100644 --- a/b/baiducloud/get_baidu_orderlist.dspy +++ b/b/baiducloud/get_baidu_orderlist.dspy @@ -75,7 +75,7 @@ async def affirmbz_order(ns={}): await sor.U('customer_goods', {'id': resource_find_id, 'del_flg': '1'}) # 处理续费逻辑 - elif order_type == 'RENEW': + elif order_type == 'RENEW' or order_type == 'DILATATION': # 找到资源并更新时间 resource_find_sql = """select id from customer_goods where FIND_IN_SET('%s', resourceid) and del_flg = '0';""" % j['resourceids'] resource_find_li = await sor.sqlExe(resource_find_sql, {}) @@ -488,6 +488,8 @@ async def get_baidu_orderlist(ns={}): business_op = 'BUY' elif order_type == 'RENEW': business_op = 'RENEW' + elif order_type == 'DILATATION': + business_op = 'DILATATION' elif order_type == 'REFUND': business_op = 'BUY_REVERSE' else: @@ -498,6 +500,8 @@ async def get_baidu_orderlist(ns={}): 'reason': '支付形式目前仅包含购买,续费,退订' } await user_action_record(ns_record) + # 取消订单 + await baidu_order_cancel({'baidu_id': baidu_users[0]['baidu_id'], 'order_id': ns.get('order_id')}) return { 'status': False, 'msg': '线上暂不支持, 请联系售后' @@ -605,8 +609,11 @@ async def get_baidu_orderlist(ns={}): with open('baidu_error.log', 'a') as f: f.write('保存配置configurations失败' + str(e) + '\n') + if order_type == 'DILATATION': + # 暂时不确定升降配是否需要重新计算日期 + pass # 如果是续费订单 由于没有返回日期, 重新计算日期 - if order_type == 'RENEW': + elif order_type == 'RENEW': history_time_sql = "select resourcestarttime, resourceendtime from order_goods where FIND_IN_SET('%s', resourceids) order by resourceendtime desc;" % \ nss['resourceids'] history_time = await sor.sqlExe(history_time_sql, {}) diff --git a/b/bz_order/getbz_order.dspy b/b/bz_order/getbz_order.dspy index 77626ad..eb720eb 100644 --- a/b/bz_order/getbz_order.dspy +++ b/b/bz_order/getbz_order.dspy @@ -178,7 +178,7 @@ async def getbz_order(ns={}): 'BUY': '购买', 'RENEW': '续费', 'BUY_REVERSE': '退款', - # 'UPGRADE': '升级' + 'DILATATION': '升降配' } item['business_op_text'] = business_op_mapping.get(item['business_op'], item['business_op']) From 38f849d346958ac3df24ae19e3ccce0903dc5eaa Mon Sep 17 00:00:00 2001 From: ping <1017253325@qq.com> Date: Mon, 1 Jun 2026 17:45:17 +0800 Subject: [PATCH 2/5] update bill --- b/.mcp.json | 18 ++++ b/bill/finance_order_report.dspy | 101 +++++++++------------- b/bill/finance_order_report_overview.dspy | 88 ++++++++----------- 3 files changed, 94 insertions(+), 113 deletions(-) create mode 100644 b/.mcp.json diff --git a/b/.mcp.json b/b/.mcp.json new file mode 100644 index 0000000..c823eab --- /dev/null +++ b/b/.mcp.json @@ -0,0 +1,18 @@ +{ + "mcpServers": { + "mysql": { + "command": "npx", + "args": ["-y", "mcp-mysql-multi-db"], + "env": { // <-- 就是这里!env 是一个对象 + "MYSQL_HOST": "localhost", + "MYSQL_PORT": "3306", + "MYSQL_USER": "root", + "MYSQL_PASSWORD": "lima2018", + "MYSQL_DATABASE": "kprod", + // 👇 要执行 INSERT/UPDATE 等写操作,就在这里添加下面两行 + // "ALLOW_DML": "true", + // "ALLOW_DDL": "true" + } + } + } +} \ No newline at end of file diff --git a/b/bill/finance_order_report.dspy b/b/bill/finance_order_report.dspy index d9ede32..426f023 100644 --- a/b/bill/finance_order_report.dspy +++ b/b/bill/finance_order_report.dspy @@ -75,7 +75,6 @@ SALEMODE_LABEL = { } INCOME_SUBJECTS = ('折扣收入', '底价收入') -PARENT_SETTLE_SUBJECT = '分销商存放资金' SUPPLIER_SETTLE_PREFIX = '待结转' _SALEMODE_SQL_OWN = """ @@ -194,9 +193,12 @@ async def _org_name(sor, orgid): async def _is_business_owner(sor, orgid): + # 业主机构 parentid 为空串(非 NULL),org_type='0';两者都视为顶级机构。 rows = await sor.sqlExe( - "SELECT id FROM organization WHERE id=${id}$ AND parentid IS NULL AND del_flg='0'", - {'id': orgid}, + """SELECT id FROM organization + WHERE id=${id}$ AND del_flg='0' + AND ((parentid IS NULL OR parentid='') OR org_type=${owner_type}$)""", + {'id': orgid, 'owner_type': OWNER_OGR}, ) return len(rows) > 0 @@ -324,8 +326,12 @@ async def _protocol_snapshot(sor, accounting_orgid, customerid, providerid, prod } -def _estimate_finance(catalog_amount, protocol, is_owner): - """未记账:估算本级利润与本级应付(不含代付费单独字段)。""" +def _estimate_finance(catalog_amount, protocol): + """未记账:估算本级利润与本级应付(本级成本)。 + + 与已记账口径一致,本级应付取「本级作为采购方(bid)的协议」即 own_*, + 对业主机构与分销商统一(own_discount 即上级给本级的折扣/底价)。 + """ catalog_amount = float(catalog_amount or 0) qty = protocol.get('quantity') or 1 profit = None @@ -335,29 +341,20 @@ def _estimate_finance(catalog_amount, protocol, is_owner): cust_mode = protocol.get('customer_salemode') own_disc = protocol.get('own_discount') cust_disc = protocol.get('customer_discount') - reseller_disc = protocol.get('reseller_discount') if own_mode == '0' or cust_mode == '0': if own_disc is not None and cust_disc is not None: profit = catalog_amount * (float(cust_disc) - float(own_disc)) - if is_owner: - if own_disc is not None: - settle_upstream = catalog_amount * float(own_disc) - elif reseller_disc is not None: - settle_upstream = catalog_amount * float(reseller_disc) + if own_disc is not None: + settle_upstream = catalog_amount * float(own_disc) elif own_mode == '2' or cust_mode == '2': own_price = protocol.get('own_floor_unit_price') cust_price = protocol.get('customer_floor_unit_price') - reseller_price = protocol.get('reseller_floor_unit_price') if own_price is not None and cust_price is not None: profit = (float(cust_price) - float(own_price)) * qty - if is_owner and own_price is not None: + if own_price is not None: settle_upstream = float(own_price) * qty - elif not is_owner and reseller_price is not None: - settle_upstream = float(reseller_price) * qty - elif not is_owner and cust_price is not None: - settle_upstream = float(cust_price) * qty return { 'profit_amount': _round_money(profit), @@ -379,8 +376,13 @@ async def _bill_detail_rows(sor, billid): )) -async def _finance_from_bill_detail(sor, billid, accounting_orgid, is_owner, parent_orgid): - """已记账:从 bill_detail 取本级利润与本级应付。""" +async def _finance_from_bill_detail(sor, billid, accounting_orgid): + """已记账:从 bill_detail 取本级利润与本级应付。 + + 统一口径(业主机构与分销商一致): + - profit_amount = 本级账本「折扣收入/底价收入」贷方合计 + - settle_upstream = 本级账本「待结转*销售收入」贷方合计(本级成本/本级应付上级) + """ rows = await _bill_detail_rows(sor, billid) profit = 0.0 settle_upstream = 0.0 @@ -400,24 +402,10 @@ async def _finance_from_bill_detail(sor, billid, accounting_orgid, is_owner, par subj = r['subjectname'] or '' direction = r['accounting_dir'] - if book == accounting_orgid and subj in INCOME_SUBJECTS and direction == '贷': - profit += amt - - if is_owner: - if ( - book == accounting_orgid - and subj.startswith(SUPPLIER_SETTLE_PREFIX) - and direction == '贷' - ): - settle_upstream += amt - else: - if ( - parent_orgid - and book == parent_orgid - and subj == PARENT_SETTLE_SUBJECT - and direction == '借' - and r.get('participantid') == accounting_orgid - ): + if book == accounting_orgid and direction == '贷': + if subj in INCOME_SUBJECTS: + profit += amt + elif subj.startswith(SUPPLIER_SETTLE_PREFIX): settle_upstream += amt return { @@ -442,16 +430,13 @@ async def _build_report_row(sor, row, accounting_orgid, is_owner): protocol = await _protocol_snapshot( sor, accounting_orgid, customerid, providerid, productid, bill_date, quantity, ) - parent_orgid = protocol['parent_orgid'] settle_meta = await _settle_upstream_meta(sor, accounting_orgid, providerid) bill_state = _row_get(row, 'bill_state') if str(bill_state) == '1': - amounts = await _finance_from_bill_detail( - sor, bill_id, accounting_orgid, is_owner, parent_orgid, - ) + amounts = await _finance_from_bill_detail(sor, bill_id, accounting_orgid) else: - amounts = _estimate_finance(catalog_amount, protocol, is_owner) + amounts = _estimate_finance(catalog_amount, protocol) amounts['bill_detail_legs'] = [] product_name = _row_get(row, 'product_name') @@ -652,7 +637,7 @@ def _customer_segment(customer_parentid, accounting_orgid, reseller_id_set): return None -async def _bill_finance_amounts(sor, row, accounting_orgid, is_owner, parent_orgid): +async def _bill_finance_amounts(sor, row, accounting_orgid): """单笔:销售额、本级利润、本级应付上级/供应商。""" sales = float(_row_get(row, 'customer_pay_amount') or 0) bill_id = _row_get(row, 'bill_id') @@ -660,9 +645,7 @@ async def _bill_finance_amounts(sor, row, accounting_orgid, is_owner, parent_org quantity = int(_row_get(row, 'quantity') or 1) if str(bill_state) == '1': - fin = await _finance_from_bill_detail( - sor, bill_id, accounting_orgid, is_owner, parent_orgid, - ) + fin = await _finance_from_bill_detail(sor, bill_id, accounting_orgid) else: catalog = float(_row_get(row, 'catalog_amount') or 0) protocol = await _protocol_snapshot( @@ -674,7 +657,7 @@ async def _bill_finance_amounts(sor, row, accounting_orgid, is_owner, parent_org _row_get(row, 'bill_date'), quantity, ) - fin = _estimate_finance(catalog, protocol, is_owner) + fin = _estimate_finance(catalog, protocol) profit = float(fin.get('profit_amount') or 0) settle = float(fin.get('settle_upstream_amount') or 0) @@ -878,9 +861,9 @@ async def finance_order_report(ns=None): userid, start_date, end_date, customerid, productid, order_id, bill_state current_page (默认1), page_size (默认20, 最大100) - 返回 finance.settle_upstream_*: - - 本机构:应付供应商(待结转* 贷方,仅本机构账本) - - 分销商:应付直接上级(上级账本「分销商存放资金」借方,participant=本级) + 返回 finance.settle_upstream_*(统一口径,取本级账本「待结转*销售收入」贷方): + - 本机构:应付供应商 + - 分销商:应付直接上级机构(金额=本级成本,与本级账本待结转一致) """ ns = ns or {} accounting_orgid = ns.get('accounting_orgid') @@ -1053,7 +1036,7 @@ async def finance_billing_overview(ns=None): 口径(与订单明细接口一致): sales_total = 客户实付合计 bill.amount profit_total = 本级账本折扣收入+底价收入(bill_detail)或协议估算 - settle_upstream_total= 本机构→供应商待结转;分销→上级账本分销商存放资金借方 + settle_upstream_total= 本级账本「待结转*销售收入」贷方合计(本级成本/应付上级,业主与分销统一) 分段: direct_customers 直属客户(cust.parentid = accounting_orgid) @@ -1084,7 +1067,6 @@ async def finance_billing_overview(ns=None): sor, accounting_orgid, include_sub, ) is_owner = await _is_business_owner(sor, accounting_orgid) - parent_orgid = await get_parent_orgid(sor, accounting_orgid) conditions = ["b.del_flg = '0'", "o.del_flg = '0'", scope_sql] params = dict(scope_params) @@ -1128,7 +1110,7 @@ async def finance_billing_overview(ns=None): continue try: sales, profit, settle, _src = await _bill_finance_amounts( - sor, row, accounting_orgid, is_owner, parent_orgid, + sor, row, accounting_orgid, ) except Exception as exc: errors.append({ @@ -1230,11 +1212,10 @@ async def finance_billing_overview(ns=None): # _report = params_kw.get('report') or params_kw.get('api') or 'order_list' _report = None -if _report in ('overview', 'billing_overview', 'finance_billing_overview'): - ret = await finance_billing_overview(params_kw) -elif _report in ('detail', 'order_detail'): - ret = await finance_order_report_detail(params_kw) -else: - ret = await finance_order_report(params_kw) +# if _report in ('overview', 'billing_overview', 'finance_billing_overview'): +# ret = await finance_billing_overview(params_kw) +# elif _report in ('detail', 'order_detail'): +# ret = await finance_order_report_detail(params_kw) +# else: +ret = await finance_order_report(params_kw) return ret -return ret \ No newline at end of file diff --git a/b/bill/finance_order_report_overview.dspy b/b/bill/finance_order_report_overview.dspy index 43af926..2049911 100644 --- a/b/bill/finance_order_report_overview.dspy +++ b/b/bill/finance_order_report_overview.dspy @@ -75,7 +75,6 @@ SALEMODE_LABEL = { } INCOME_SUBJECTS = ('折扣收入', '底价收入') -PARENT_SETTLE_SUBJECT = '分销商存放资金' SUPPLIER_SETTLE_PREFIX = '待结转' _SALEMODE_SQL_OWN = """ @@ -194,9 +193,12 @@ async def _org_name(sor, orgid): async def _is_business_owner(sor, orgid): + # 业主机构 parentid 为空串(非 NULL),org_type='0';两者都视为顶级机构。 rows = await sor.sqlExe( - "SELECT id FROM organization WHERE id=${id}$ AND parentid IS NULL AND del_flg='0'", - {'id': orgid}, + """SELECT id FROM organization + WHERE id=${id}$ AND del_flg='0' + AND ((parentid IS NULL OR parentid='') OR org_type=${owner_type}$)""", + {'id': orgid, 'owner_type': OWNER_OGR}, ) return len(rows) > 0 @@ -324,8 +326,12 @@ async def _protocol_snapshot(sor, accounting_orgid, customerid, providerid, prod } -def _estimate_finance(catalog_amount, protocol, is_owner): - """未记账:估算本级利润与本级应付(不含代付费单独字段)。""" +def _estimate_finance(catalog_amount, protocol): + """未记账:估算本级利润与本级应付(本级成本)。 + + 与已记账口径一致,本级应付取「本级作为采购方(bid)的协议」即 own_*, + 对业主机构与分销商统一(own_discount 即上级给本级的折扣/底价)。 + """ catalog_amount = float(catalog_amount or 0) qty = protocol.get('quantity') or 1 profit = None @@ -335,29 +341,20 @@ def _estimate_finance(catalog_amount, protocol, is_owner): cust_mode = protocol.get('customer_salemode') own_disc = protocol.get('own_discount') cust_disc = protocol.get('customer_discount') - reseller_disc = protocol.get('reseller_discount') if own_mode == '0' or cust_mode == '0': if own_disc is not None and cust_disc is not None: profit = catalog_amount * (float(cust_disc) - float(own_disc)) - if is_owner: - if own_disc is not None: - settle_upstream = catalog_amount * float(own_disc) - elif reseller_disc is not None: - settle_upstream = catalog_amount * float(reseller_disc) + if own_disc is not None: + settle_upstream = catalog_amount * float(own_disc) elif own_mode == '2' or cust_mode == '2': own_price = protocol.get('own_floor_unit_price') cust_price = protocol.get('customer_floor_unit_price') - reseller_price = protocol.get('reseller_floor_unit_price') if own_price is not None and cust_price is not None: profit = (float(cust_price) - float(own_price)) * qty - if is_owner and own_price is not None: + if own_price is not None: settle_upstream = float(own_price) * qty - elif not is_owner and reseller_price is not None: - settle_upstream = float(reseller_price) * qty - elif not is_owner and cust_price is not None: - settle_upstream = float(cust_price) * qty return { 'profit_amount': _round_money(profit), @@ -379,8 +376,13 @@ async def _bill_detail_rows(sor, billid): )) -async def _finance_from_bill_detail(sor, billid, accounting_orgid, is_owner, parent_orgid): - """已记账:从 bill_detail 取本级利润与本级应付。""" +async def _finance_from_bill_detail(sor, billid, accounting_orgid): + """已记账:从 bill_detail 取本级利润与本级应付。 + + 统一口径(业主机构与分销商一致): + - profit_amount = 本级账本「折扣收入/底价收入」贷方合计 + - settle_upstream = 本级账本「待结转*销售收入」贷方合计(本级成本/本级应付上级) + """ rows = await _bill_detail_rows(sor, billid) profit = 0.0 settle_upstream = 0.0 @@ -400,24 +402,10 @@ async def _finance_from_bill_detail(sor, billid, accounting_orgid, is_owner, par subj = r['subjectname'] or '' direction = r['accounting_dir'] - if book == accounting_orgid and subj in INCOME_SUBJECTS and direction == '贷': - profit += amt - - if is_owner: - if ( - book == accounting_orgid - and subj.startswith(SUPPLIER_SETTLE_PREFIX) - and direction == '贷' - ): - settle_upstream += amt - else: - if ( - parent_orgid - and book == parent_orgid - and subj == PARENT_SETTLE_SUBJECT - and direction == '借' - and r.get('participantid') == accounting_orgid - ): + if book == accounting_orgid and direction == '贷': + if subj in INCOME_SUBJECTS: + profit += amt + elif subj.startswith(SUPPLIER_SETTLE_PREFIX): settle_upstream += amt return { @@ -442,16 +430,13 @@ async def _build_report_row(sor, row, accounting_orgid, is_owner): protocol = await _protocol_snapshot( sor, accounting_orgid, customerid, providerid, productid, bill_date, quantity, ) - parent_orgid = protocol['parent_orgid'] settle_meta = await _settle_upstream_meta(sor, accounting_orgid, providerid) bill_state = _row_get(row, 'bill_state') if str(bill_state) == '1': - amounts = await _finance_from_bill_detail( - sor, bill_id, accounting_orgid, is_owner, parent_orgid, - ) + amounts = await _finance_from_bill_detail(sor, bill_id, accounting_orgid) else: - amounts = _estimate_finance(catalog_amount, protocol, is_owner) + amounts = _estimate_finance(catalog_amount, protocol) amounts['bill_detail_legs'] = [] product_name = _row_get(row, 'product_name') @@ -652,7 +637,7 @@ def _customer_segment(customer_parentid, accounting_orgid, reseller_id_set): return None -async def _bill_finance_amounts(sor, row, accounting_orgid, is_owner, parent_orgid): +async def _bill_finance_amounts(sor, row, accounting_orgid): """单笔:销售额、本级利润、本级应付上级/供应商。""" sales = float(_row_get(row, 'customer_pay_amount') or 0) bill_id = _row_get(row, 'bill_id') @@ -660,9 +645,7 @@ async def _bill_finance_amounts(sor, row, accounting_orgid, is_owner, parent_org quantity = int(_row_get(row, 'quantity') or 1) if str(bill_state) == '1': - fin = await _finance_from_bill_detail( - sor, bill_id, accounting_orgid, is_owner, parent_orgid, - ) + fin = await _finance_from_bill_detail(sor, bill_id, accounting_orgid) else: catalog = float(_row_get(row, 'catalog_amount') or 0) protocol = await _protocol_snapshot( @@ -674,7 +657,7 @@ async def _bill_finance_amounts(sor, row, accounting_orgid, is_owner, parent_org _row_get(row, 'bill_date'), quantity, ) - fin = _estimate_finance(catalog, protocol, is_owner) + fin = _estimate_finance(catalog, protocol) profit = float(fin.get('profit_amount') or 0) settle = float(fin.get('settle_upstream_amount') or 0) @@ -878,9 +861,9 @@ async def finance_order_report(ns=None): userid, start_date, end_date, customerid, productid, order_id, bill_state current_page (默认1), page_size (默认20, 最大100) - 返回 finance.settle_upstream_*: - - 本机构:应付供应商(待结转* 贷方,仅本机构账本) - - 分销商:应付直接上级(上级账本「分销商存放资金」借方,participant=本级) + 返回 finance.settle_upstream_*(统一口径,取本级账本「待结转*销售收入」贷方): + - 本机构:应付供应商 + - 分销商:应付直接上级机构(金额=本级成本,与本级账本待结转一致) """ ns = ns or {} accounting_orgid = ns.get('accounting_orgid') @@ -1053,7 +1036,7 @@ async def finance_billing_overview(ns=None): 口径(与订单明细接口一致): sales_total = 客户实付合计 bill.amount profit_total = 本级账本折扣收入+底价收入(bill_detail)或协议估算 - settle_upstream_total= 本机构→供应商待结转;分销→上级账本分销商存放资金借方 + settle_upstream_total= 本级账本「待结转*销售收入」贷方合计(本级成本/应付上级,业主与分销统一) 分段: direct_customers 直属客户(cust.parentid = accounting_orgid) @@ -1084,7 +1067,6 @@ async def finance_billing_overview(ns=None): sor, accounting_orgid, include_sub, ) is_owner = await _is_business_owner(sor, accounting_orgid) - parent_orgid = await get_parent_orgid(sor, accounting_orgid) conditions = ["b.del_flg = '0'", "o.del_flg = '0'", scope_sql] params = dict(scope_params) @@ -1128,7 +1110,7 @@ async def finance_billing_overview(ns=None): continue try: sales, profit, settle, _src = await _bill_finance_amounts( - sor, row, accounting_orgid, is_owner, parent_orgid, + sor, row, accounting_orgid, ) except Exception as exc: errors.append({ From 5a6524ffa5643dd6e906fc0a574f9f4f58315893 Mon Sep 17 00:00:00 2001 From: ping <1017253325@qq.com> Date: Wed, 3 Jun 2026 10:12:51 +0800 Subject: [PATCH 3/5] update bill report --- b/bill/finance_order_report.dspy | 45 +++++++++++++++++++---- b/bill/finance_order_report_overview.dspy | 45 +++++++++++++++++++---- 2 files changed, 74 insertions(+), 16 deletions(-) diff --git a/b/bill/finance_order_report.dspy b/b/bill/finance_order_report.dspy index 426f023..79a964d 100644 --- a/b/bill/finance_order_report.dspy +++ b/b/bill/finance_order_report.dspy @@ -115,6 +115,15 @@ def _round_money(v): return round(float(v), 2) +def _is_reverse_op(business_op): + """退订/红冲类操作(BUY_REVERSE 等 *_REVERSE)。 + + 数据中退订账单的 bill_detail 方向与正常单一致(均为贷),仅靠 business_op 区分。 + 退订口径:销售额、利润取反(减少);上游结算/应付供应商仍正向累加(增加)。 + """ + return str(business_op or '').upper().endswith('_REVERSE') + + def _salemode_label(code): if code is None: return None @@ -326,11 +335,13 @@ async def _protocol_snapshot(sor, accounting_orgid, customerid, providerid, prod } -def _estimate_finance(catalog_amount, protocol): +def _estimate_finance(catalog_amount, protocol, is_reverse=False): """未记账:估算本级利润与本级应付(本级成本)。 与已记账口径一致,本级应付取「本级作为采购方(bid)的协议」即 own_*, 对业主机构与分销商统一(own_discount 即上级给本级的折扣/底价)。 + + 退订(is_reverse):利润取反(减少);上游结算仍正向(增加)。 """ catalog_amount = float(catalog_amount or 0) qty = protocol.get('quantity') or 1 @@ -356,6 +367,9 @@ def _estimate_finance(catalog_amount, protocol): if own_price is not None: settle_upstream = float(own_price) * qty + if is_reverse and profit is not None: + profit = -profit + return { 'profit_amount': _round_money(profit), 'settle_upstream_amount': _round_money(settle_upstream), @@ -376,12 +390,14 @@ async def _bill_detail_rows(sor, billid): )) -async def _finance_from_bill_detail(sor, billid, accounting_orgid): +async def _finance_from_bill_detail(sor, billid, accounting_orgid, is_reverse=False): """已记账:从 bill_detail 取本级利润与本级应付。 统一口径(业主机构与分销商一致): - profit_amount = 本级账本「折扣收入/底价收入」贷方合计 - settle_upstream = 本级账本「待结转*销售收入」贷方合计(本级成本/本级应付上级) + + 退订(is_reverse):利润取反(减少);上游结算仍正向累加(增加)。 """ rows = await _bill_detail_rows(sor, billid) profit = 0.0 @@ -408,6 +424,9 @@ async def _finance_from_bill_detail(sor, billid, accounting_orgid): elif subj.startswith(SUPPLIER_SETTLE_PREFIX): settle_upstream += amt + if is_reverse: + profit = -profit + return { 'profit_amount': _round_money(profit), 'settle_upstream_amount': _round_money(settle_upstream) if settle_upstream else _round_money(0), @@ -426,6 +445,10 @@ async def _build_report_row(sor, row, accounting_orgid, is_owner): catalog_amount = _round_money(_row_get(row, 'catalog_amount')) customer_pay = _round_money(_row_get(row, 'customer_pay_amount')) customer_parentid = _row_get(row, 'customer_parentid') + is_reverse = _is_reverse_op(_row_get(row, 'business_op')) + if is_reverse and customer_pay is not None: + # 退订:客户实付(销售额)取负,使汇总相应减少 + customer_pay = _round_money(-customer_pay) protocol = await _protocol_snapshot( sor, accounting_orgid, customerid, providerid, productid, bill_date, quantity, @@ -434,9 +457,9 @@ async def _build_report_row(sor, row, accounting_orgid, is_owner): bill_state = _row_get(row, 'bill_state') if str(bill_state) == '1': - amounts = await _finance_from_bill_detail(sor, bill_id, accounting_orgid) + amounts = await _finance_from_bill_detail(sor, bill_id, accounting_orgid, is_reverse) else: - amounts = _estimate_finance(catalog_amount, protocol) + amounts = _estimate_finance(catalog_amount, protocol, is_reverse) amounts['bill_detail_legs'] = [] product_name = _row_get(row, 'product_name') @@ -638,14 +661,20 @@ def _customer_segment(customer_parentid, accounting_orgid, reseller_id_set): async def _bill_finance_amounts(sor, row, accounting_orgid): - """单笔:销售额、本级利润、本级应付上级/供应商。""" + """单笔:销售额、本级利润、本级应付上级/供应商。 + + 退订(BUY_REVERSE 等):销售额、利润取负(减少);应付上级仍正向(增加)。 + """ sales = float(_row_get(row, 'customer_pay_amount') or 0) bill_id = _row_get(row, 'bill_id') bill_state = _row_get(row, 'bill_state') quantity = int(_row_get(row, 'quantity') or 1) + is_reverse = _is_reverse_op(_row_get(row, 'business_op')) + if is_reverse: + sales = -sales if str(bill_state) == '1': - fin = await _finance_from_bill_detail(sor, bill_id, accounting_orgid) + fin = await _finance_from_bill_detail(sor, bill_id, accounting_orgid, is_reverse) else: catalog = float(_row_get(row, 'catalog_amount') or 0) protocol = await _protocol_snapshot( @@ -657,7 +686,7 @@ async def _bill_finance_amounts(sor, row, accounting_orgid): _row_get(row, 'bill_date'), quantity, ) - fin = _estimate_finance(catalog, protocol) + fin = _estimate_finance(catalog, protocol, is_reverse) profit = float(fin.get('profit_amount') or 0) settle = float(fin.get('settle_upstream_amount') or 0) @@ -769,7 +798,7 @@ async def _fetch_bill_row_via_R(sor, bill_id): 'customer_pay_amount': b.get('amount'), 'quantity': b.get('quantity'), 'order_date': o.get('order_date'), - 'business_op': o.get('business_op'), + 'business_op': b.get('business_op') or o.get('business_op'), 'servicename': o.get('servicename'), 'customer_name': cust.get('orgname'), 'customer_parentid': cust.get('parentid'), diff --git a/b/bill/finance_order_report_overview.dspy b/b/bill/finance_order_report_overview.dspy index 2049911..0202ca3 100644 --- a/b/bill/finance_order_report_overview.dspy +++ b/b/bill/finance_order_report_overview.dspy @@ -115,6 +115,15 @@ def _round_money(v): return round(float(v), 2) +def _is_reverse_op(business_op): + """退订/红冲类操作(BUY_REVERSE 等 *_REVERSE)。 + + 数据中退订账单的 bill_detail 方向与正常单一致(均为贷),仅靠 business_op 区分。 + 退订口径:销售额、利润取反(减少);上游结算/应付供应商仍正向累加(增加)。 + """ + return str(business_op or '').upper().endswith('_REVERSE') + + def _salemode_label(code): if code is None: return None @@ -326,11 +335,13 @@ async def _protocol_snapshot(sor, accounting_orgid, customerid, providerid, prod } -def _estimate_finance(catalog_amount, protocol): +def _estimate_finance(catalog_amount, protocol, is_reverse=False): """未记账:估算本级利润与本级应付(本级成本)。 与已记账口径一致,本级应付取「本级作为采购方(bid)的协议」即 own_*, 对业主机构与分销商统一(own_discount 即上级给本级的折扣/底价)。 + + 退订(is_reverse):利润取反(减少);上游结算仍正向(增加)。 """ catalog_amount = float(catalog_amount or 0) qty = protocol.get('quantity') or 1 @@ -356,6 +367,9 @@ def _estimate_finance(catalog_amount, protocol): if own_price is not None: settle_upstream = float(own_price) * qty + if is_reverse and profit is not None: + profit = -profit + return { 'profit_amount': _round_money(profit), 'settle_upstream_amount': _round_money(settle_upstream), @@ -376,12 +390,14 @@ async def _bill_detail_rows(sor, billid): )) -async def _finance_from_bill_detail(sor, billid, accounting_orgid): +async def _finance_from_bill_detail(sor, billid, accounting_orgid, is_reverse=False): """已记账:从 bill_detail 取本级利润与本级应付。 统一口径(业主机构与分销商一致): - profit_amount = 本级账本「折扣收入/底价收入」贷方合计 - settle_upstream = 本级账本「待结转*销售收入」贷方合计(本级成本/本级应付上级) + + 退订(is_reverse):利润取反(减少);上游结算仍正向累加(增加)。 """ rows = await _bill_detail_rows(sor, billid) profit = 0.0 @@ -408,6 +424,9 @@ async def _finance_from_bill_detail(sor, billid, accounting_orgid): elif subj.startswith(SUPPLIER_SETTLE_PREFIX): settle_upstream += amt + if is_reverse: + profit = -profit + return { 'profit_amount': _round_money(profit), 'settle_upstream_amount': _round_money(settle_upstream) if settle_upstream else _round_money(0), @@ -426,6 +445,10 @@ async def _build_report_row(sor, row, accounting_orgid, is_owner): catalog_amount = _round_money(_row_get(row, 'catalog_amount')) customer_pay = _round_money(_row_get(row, 'customer_pay_amount')) customer_parentid = _row_get(row, 'customer_parentid') + is_reverse = _is_reverse_op(_row_get(row, 'business_op')) + if is_reverse and customer_pay is not None: + # 退订:客户实付(销售额)取负,使汇总相应减少 + customer_pay = _round_money(-customer_pay) protocol = await _protocol_snapshot( sor, accounting_orgid, customerid, providerid, productid, bill_date, quantity, @@ -434,9 +457,9 @@ async def _build_report_row(sor, row, accounting_orgid, is_owner): bill_state = _row_get(row, 'bill_state') if str(bill_state) == '1': - amounts = await _finance_from_bill_detail(sor, bill_id, accounting_orgid) + amounts = await _finance_from_bill_detail(sor, bill_id, accounting_orgid, is_reverse) else: - amounts = _estimate_finance(catalog_amount, protocol) + amounts = _estimate_finance(catalog_amount, protocol, is_reverse) amounts['bill_detail_legs'] = [] product_name = _row_get(row, 'product_name') @@ -638,14 +661,20 @@ def _customer_segment(customer_parentid, accounting_orgid, reseller_id_set): async def _bill_finance_amounts(sor, row, accounting_orgid): - """单笔:销售额、本级利润、本级应付上级/供应商。""" + """单笔:销售额、本级利润、本级应付上级/供应商。 + + 退订(BUY_REVERSE 等):销售额、利润取负(减少);应付上级仍正向(增加)。 + """ sales = float(_row_get(row, 'customer_pay_amount') or 0) bill_id = _row_get(row, 'bill_id') bill_state = _row_get(row, 'bill_state') quantity = int(_row_get(row, 'quantity') or 1) + is_reverse = _is_reverse_op(_row_get(row, 'business_op')) + if is_reverse: + sales = -sales if str(bill_state) == '1': - fin = await _finance_from_bill_detail(sor, bill_id, accounting_orgid) + fin = await _finance_from_bill_detail(sor, bill_id, accounting_orgid, is_reverse) else: catalog = float(_row_get(row, 'catalog_amount') or 0) protocol = await _protocol_snapshot( @@ -657,7 +686,7 @@ async def _bill_finance_amounts(sor, row, accounting_orgid): _row_get(row, 'bill_date'), quantity, ) - fin = _estimate_finance(catalog, protocol) + fin = _estimate_finance(catalog, protocol, is_reverse) profit = float(fin.get('profit_amount') or 0) settle = float(fin.get('settle_upstream_amount') or 0) @@ -769,7 +798,7 @@ async def _fetch_bill_row_via_R(sor, bill_id): 'customer_pay_amount': b.get('amount'), 'quantity': b.get('quantity'), 'order_date': o.get('order_date'), - 'business_op': o.get('business_op'), + 'business_op': b.get('business_op') or o.get('business_op'), 'servicename': o.get('servicename'), 'customer_name': cust.get('orgname'), 'customer_parentid': cust.get('parentid'), From 425137c7c377b5cc8a77b3e1aae177c753982d82 Mon Sep 17 00:00:00 2001 From: ping <1017253325@qq.com> Date: Wed, 3 Jun 2026 11:03:31 +0800 Subject: [PATCH 4/5] update --- b/cntoai/model_usage_user_report.dspy | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/b/cntoai/model_usage_user_report.dspy b/b/cntoai/model_usage_user_report.dspy index 1cb5896..256d66d 100644 --- a/b/cntoai/model_usage_user_report.dspy +++ b/b/cntoai/model_usage_user_report.dspy @@ -95,7 +95,7 @@ def _normalize_usage_row(row, bill_amount_map=None): 'prompt_tokens': int(usage.get('prompt_tokens') or 0), 'completion_tokens': int(usage.get('completion_tokens') or 0), 'total_tokens': int(usage.get('total_tokens') or 0), - 'amount': round(amount, 8), + 'amount': round(amount, 4), 'bill_status': row.get('bill_status'), 'orderid': orderid, 'usage_time': row.get('created_at'), @@ -224,7 +224,7 @@ def _aggregate_admin_summary(items, user_map, org_map): bucket['prompt_tokens'] += item.get('prompt_tokens') or 0 bucket['completion_tokens'] += item.get('completion_tokens') or 0 bucket['total_tokens'] += item.get('total_tokens') or 0 - bucket['amount'] = round(bucket['amount'] + float(item.get('amount') or 0), 8) + bucket['amount'] = round(bucket['amount'] + float(item.get('amount') or 0), 4) bucket['request_count'] += 1 usage_time = item.get('usage_time') if usage_time: @@ -267,7 +267,7 @@ def _aggregate_items(items, group_by=None): bucket['prompt_tokens'] += item.get('prompt_tokens') or 0 bucket['completion_tokens'] += item.get('completion_tokens') or 0 bucket['total_tokens'] += item.get('total_tokens') or 0 - bucket['amount'] = round(bucket['amount'] + float(item.get('amount') or 0), 8) + bucket['amount'] = round(bucket['amount'] + float(item.get('amount') or 0), 4) bucket['request_count'] += 1 return sorted(buckets.values(), key=lambda x: x['period'], reverse=True) @@ -279,7 +279,7 @@ def _summarize(items): 'prompt_tokens': sum(i.get('prompt_tokens') or 0 for i in items), 'completion_tokens': sum(i.get('completion_tokens') or 0 for i in items), 'total_tokens': sum(i.get('total_tokens') or 0 for i in items), - 'amount': round(sum(float(i.get('amount') or 0) for i in items), 8), + 'amount': round(sum(float(i.get('amount') or 0) for i in items), 4), } From 90037cae9e1fd81e9492400bc06fd8f847e128a6 Mon Sep 17 00:00:00 2001 From: hrx <18603305412@163.com> Date: Wed, 3 Jun 2026 17:46:01 +0800 Subject: [PATCH 5/5] updata --- f/web-kboss/src/api/model/model.js | 6 +- .../views/finance/billingStatistics/index.vue | 6 +- .../views/finance/financialOverview/index.vue | 6 +- .../modelInfoConfig/ModelInfoEditDialog.vue | 1053 +++++------------ .../views/operation/modelInfoConfig/index.vue | 2 +- f/web-kboss/src/views/tokenUsage/index.vue | 39 +- 6 files changed, 359 insertions(+), 753 deletions(-) diff --git a/f/web-kboss/src/api/model/model.js b/f/web-kboss/src/api/model/model.js index 07fb52c..7ff58d4 100644 --- a/f/web-kboss/src/api/model/model.js +++ b/f/web-kboss/src/api/model/model.js @@ -129,19 +129,19 @@ export const reqModelInfoConfig = (params = {}) => { const isFormData = params instanceof FormData return request({ url: '/cntoai/model_management_add.dspy', - method: isFormData ? 'post' : 'get', + method: 'post', params: isFormData ? undefined : params, data: isFormData ? params : undefined, headers: isFormData ? { 'Content-Type': 'multipart/form-data' } : undefined }) } -// 模型信息配置编辑(编辑时需要额外传 id) +// 模型信息配置编辑 export const reqModelInfoConfigEdit = (params = {}) => { const isFormData = params instanceof FormData return request({ url: '/cntoai/model_management_update.dspy', - method: isFormData ? 'post' : 'get', + method: 'post', params: isFormData ? undefined : params, data: isFormData ? params : undefined, headers: isFormData ? { 'Content-Type': 'multipart/form-data' } : undefined diff --git a/f/web-kboss/src/views/finance/billingStatistics/index.vue b/f/web-kboss/src/views/finance/billingStatistics/index.vue index 8275f74..e4ad326 100644 --- a/f/web-kboss/src/views/finance/billingStatistics/index.vue +++ b/f/web-kboss/src/views/finance/billingStatistics/index.vue @@ -10,10 +10,10 @@

核算机构:{{ displayValue(billingData.accounting_orgname) }}

机构编号:{{ displayValue(billingData.accounting_orgid) }}

-
+
@@ -179,7 +179,7 @@ {{ displayValue(leg.subjectname) }} {{ displayValue(leg.accounting_dir) }} {{ displayValue(leg.participanttype) }} - {{ displayValue(leg.accounting_orgid) }} + {{ displayValue(leg.accounting_orgid) }} {{ money(leg.amount) }} diff --git a/f/web-kboss/src/views/finance/financialOverview/index.vue b/f/web-kboss/src/views/finance/financialOverview/index.vue index 3d0f4b6..c284a22 100644 --- a/f/web-kboss/src/views/finance/financialOverview/index.vue +++ b/f/web-kboss/src/views/finance/financialOverview/index.vue @@ -18,9 +18,9 @@ 数据截断:{{ financialOverview.truncated ? '是' : '否' }}
-
- 查看计费统计 -
+
diff --git a/f/web-kboss/src/views/operation/modelInfoConfig/ModelInfoEditDialog.vue b/f/web-kboss/src/views/operation/modelInfoConfig/ModelInfoEditDialog.vue index ee2e91e..267cdd6 100644 --- a/f/web-kboss/src/views/operation/modelInfoConfig/ModelInfoEditDialog.vue +++ b/f/web-kboss/src/views/operation/modelInfoConfig/ModelInfoEditDialog.vue @@ -6,7 +6,8 @@ class="model-edit-dialog" append-to-body > - + +
智能识别
@@ -15,66 +16,54 @@ type="textarea" :rows="3" placeholder="可粘贴模型介绍、API文档等内容,自动识别并填充下方表单..." - > + /> 识别
+
基础信息
- + - + - - + + - + - - - - - - + + + + + +
- -
- model logo + +
+ logo
- 选择文件 - 移除 - {{ editForm.logo || (editForm.modelLogoPreview ? '已上传图片' : '未选择任何文件') }} + 选择文件 + 移除
- + - + - @@ -84,66 +73,68 @@
+
价格与计费
- + - + - + - + - +
+
模型能力
- + - + - - - - - + + + + + - - - - - + + + + + - + 支持 不支持 - + 支持 不支持 - + 支持 不支持 @@ -151,105 +142,48 @@
+
模型亮点 - 添加亮点 + 添加亮点
-
- {{ index + 1 }} - - - +
+ {{ idx + 1 }} + + +
+
模型限制 - 添加限制 + 添加限制
-
- {{ index + 1 }} - - - +
+ {{ idx + 1 }} + + +
+
API 文档信息
- - - - - - - + - + -
@@ -264,55 +198,37 @@