From 39705f3e041f85c94c0ec8c67e9f7129af6d006f Mon Sep 17 00:00:00 2001 From: yumoqing Date: Mon, 23 Mar 2026 18:27:34 +0800 Subject: [PATCH] bugfiix --- json/pricing_program.json | 6 +- models/pricing_program.xlsx | Bin 18381 -> 18584 bytes pricing/init.py | 2 + pricing/pricing.py | 105 +++++++++++++++++++++------------ pricing/test.xlsx | Bin 0 -> 9726 bytes pricing/write_pattern.py | 112 ++++++++++++++++++++++++++++++++++++ 6 files changed, 188 insertions(+), 37 deletions(-) create mode 100644 pricing/test.xlsx create mode 100644 pricing/write_pattern.py diff --git a/json/pricing_program.json b/json/pricing_program.json index c465a16..f120724 100644 --- a/json/pricing_program.json +++ b/json/pricing_program.json @@ -6,7 +6,11 @@ "logined_userorgid": "ownerid", "browserfields": { "exclouded": ["id", "ownerid" ], - "alters": {} + "alters": { + "providerid":{ + "dataurl":"{{entire_url('/rbac/get_provider.dspy')}}" + } + } }, "editexclouded": [ "id", "ownerid" diff --git a/models/pricing_program.xlsx b/models/pricing_program.xlsx index 6c713aaa7ee1ee1e28a358a8d485cd7ff528cb12..ae33fc2b7c44a3b4b59332118d48e2cb4f998909 100644 GIT binary patch delta 3836 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 delta 3654 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 WVn>5C6bQ>;=*JqeBxTC~-Te>!=)D5~ diff --git a/pricing/init.py b/pricing/init.py index 0f1e8d8..c7f7367 100644 --- a/pricing/init.py +++ b/pricing/init.py @@ -1,8 +1,10 @@ from pricing.pricing import ( PricingProgram ) +from write_pattern import write_pattern_xlsx from ahserver.serverenv import ServerEnv def load_pricing(): env = ServerEnv() + env.write_patten = PricingProgram.write_patten env.calculate_prices = PricingProgram.pricing diff --git a/pricing/pricing.py b/pricing/pricing.py index 361d65e..eb184d7 100644 --- a/pricing/pricing.py +++ b/pricing/pricing.py @@ -4,46 +4,66 @@ from ahserver.serverenv import ServerEnv from sqlor.dbpools import DBPools, get_sor_context from appPublic.log import debug, exception from appPublic.dictObject import DictObject - +from .write_pattern import write_pattern_xlsx import yaml """ 采用yaml描述定价策略, -一下是一个例子 -pricing_unit: 1000 -- id: input_token_pricing_1 - field: prompt_tokens - between: 0 ~= 1000 -- id: input_token_pricing_2 - - cnt_field: prompt_tokens - between: 1000 ~= 100000 -- id: input_token_pricing_2 - - cnt_field: prompt_tokens - between: 100000 ~= -- id: output_pricing - - cnt_field: completion_tokens +在pricing_program的pricing_spec表中定义定价的数据字段 +遵循一下规格: +字典结构,key是字段名,需定义字段的type(类型),label(标题),value_mode(值方式)(可选),options(可选项)(可选) +必须要有一个price字段,其type: float -视频定价 -fields: - resolution: - type: str - label: 分辨率 - value_mode: - - between - - in - - = - - > - - >= - - < - - <= +value_mode 有下列可能的取值 +between # 定价表中此字段以如此格式给出: + # "小值 ~ 大值", "~"的前面或后面可以加"=", + # 表示含小值,或含大值 +in # 定价表中此字段值有如下格式:值1 值2 ... += # 缺省,给定单一值 +> # +>= +< +<= - duration: - type: int - label: 时长 - audio: - type: boolean - label: 音频 +例子(vidu定价字段): +''' +model: + type: str + label: "模型" + options: + - "viduq3-pro" + - "viduq3-turbo" + +resolution: + type: str + label: "分辨率" + options: + - "1024p" + - "720p" + - "540p" + +duration: + type: int # 建议改为 int 或 str,times 不是标准类型 + label: "时长" + # 如果时长也有选项,需要补全,例如: + # options: + # - 5 + # - 10 + +off_peak: + type: int # 建议改为 int 或 str,因为值是 0 和 1 + label: "错峰执行" + options: + - off_peak # 正常时段 + - normal # 错峰 +price: + type: float + label: 单价 +''' + +pricing_program_timing表中的pricing_data字段的数据是一个只有一个属性"pricings"的字典 +其值为定价条目列表,每个定价条目是个字典,key值为pricing_spec字段定义的字段, pricings: - resolution: 480p duration: 4 @@ -81,11 +101,8 @@ pricings: - resolution: 720p duration: 12 audio: true - - """ -""" typefuncs = { 'int': int, 'float': float @@ -139,6 +156,22 @@ def check_value(field, spec_value, data_value): return x class PricingProgram: + @staticmethod + async def load_pricing(ppid, webpath_xlsx): + pass + @staticmethod + async def write_patten(request, ppid): + async with get_sor_context(request._run_ns, 'pricing') as sor: + env = request._run_ns + recs = await sor.R('pricing_program', {'id': ppid}) + if not recs: + debug(f'id={ppid} pricing_program not found') + r = recs[0] + PricingProgram.pp_db2app(r) + x = [ DictObject(**f) for f in r.pricing_spec ] + webpath = env.quote(write_pattern_xlsx(x)) + return entire_url(f'/idfile?path={webpath}') + @staticmethod def pp_db2app(pp): try: diff --git a/pricing/test.xlsx b/pricing/test.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..77b092ae4bb5c61954a390c98c757045e84dd8cb GIT binary patch literal 9726 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 sLpF literal 0 HcmV?d00001 diff --git a/pricing/write_pattern.py b/pricing/write_pattern.py new file mode 100644 index 0000000..4786783 --- /dev/null +++ b/pricing/write_pattern.py @@ -0,0 +1,112 @@ +import yaml +from openpyxl import Workbook +from openpyxl import load_workbook +from openpyxl.worksheet.datavalidation import DataValidation +from appPublic.dictObject import DictObject +from appPublic.uniqueID import getID +from ahserver.filestorage import FileStorage + +def create_colnames(): + r = {} + fls = ['', 'A', 'B'] + i = 1 + for fl in fls: + for c in "ABCDEFGHIJKLMNOPQRSTUVWXYZ": + r[f'{fl}{c}'] = i + i = i + 1 + return r + +colnames = create_colnames() +reverse_colnames = {v:k for k,v in colnames.items()} + +def write_pattern_xlsx(fields: dict) -> str: + wb = Workbook() + ws_data = wb.active + hidden = wb.create_sheet('dict') + hidden.sheet_status = 'hidden' + # 3. 写入表头 + headers = [] + c = 1 + opt_id = 0 + for f in fields.values(): + ws_data.cell(row=1, column=c, value=f.label or f.name) + if f.options: + create_options(ws_data, c, hidden, opt_id, f.options) + opt_id = opt_id + 1 + c += 1 + fs = FileStorage() + fp = fs._name2path(f'pricing_{getID}.xlsx') + wb.save(fp) + webpath = fs.webpath(fp) + return webpath + +def create_options(ws, dcol, sheet, opt_id, options): + r = 2 + vc = opt_id + 1 + for v in options: + sheet.cell(row=r, column=vc, value=v) + r = r + 1 + colname = reverse_colnames[vc] + dv = DataValidation(type="list", + formula1=f'dict!${colname}$1:${colname}$4', + allow_blank=True) + dv.error = '请选择下拉菜单中的有效职位。' + dv.errorTitle = '输入无效' + ws.add_data_validation(dv) + cn = reverse_colnames[dcol] + dv.add(f'{cn}2:{cn}1048576') + +def load_xlsx_pricing(xlsxpath): + wb = load_workbook(xlsxpath) + ws = wb.active + d = [] + for row in ws.iter_rows(min_row=2, values_only=True): + r = {} + for c, cell in enumerate(row): + r.update({ws.cell(row=1, column=c+1).value:cell}) + d.append(r) + print(d) + return d + +if __name__ == '__main__': + fields_str = """model: + type: str + label: "模型" + options: + - "viduq3-pro" + - "viduq3-turbo" + +resolution: + type: str + label: "分辨率" + options: + - "1024p" + - "720p" + - "540p" + +duration: + type: int # 建议改为 int 或 str,times 不是标准类型 + label: "时长" + # 如果时长也有选项,需要补全,例如: + # options: + # - 5 + # - 10 + +off_peak: + type: int # 建议改为 int 或 str,因为值是 0 和 1 + label: "错峰执行" + options: + - off_peak # 正常时段 + - normal # 错峰 +price: + type: float + label: 单价 + +""" + """ + fields = DictObject(**yaml.safe_load(fields_str)) + print(f'{fields=}, {type(fields)=}') + write_pattern_xlsx(fields) + """ + load_xlsx_pricing('./test.xlsx') +