feat: 供应合同和分销协议支持附件上传下载
contract_attach.ui: 附件管理页面(Tabular文件列表 + 上传按钮) contract_attach_list.dspy: 查询合同附件列表 init.py: ensure_contract_folder() 自动创建附件目录 supply_contracts_list + distribution_agreements_list: 新增'合同附件'toolbar 实现: filemgr folder(contract_id=id, fiid=type)自动管理
This commit is contained in:
parent
1d99375578
commit
fa5a1a3a8e
@ -83,6 +83,15 @@
|
||||
"title": "产品分销折扣",
|
||||
"url": "{{entire_url('../distribution_agreement_items_list')}}",
|
||||
"subtable": "distribution_agreement_items"
|
||||
},
|
||||
{
|
||||
"field": "contract_id",
|
||||
"title": "合同附件",
|
||||
"url": "{{entire_url('../api/contract_attach.ui')}}?contract_type=distribution",
|
||||
"subtable": "contract_attach",
|
||||
"mapping": {
|
||||
"contract_id": "id"
|
||||
}
|
||||
}
|
||||
],
|
||||
"editable": {
|
||||
|
||||
@ -88,6 +88,15 @@
|
||||
"title": "产品折扣明细",
|
||||
"url": "{{entire_url('../supply_contract_items_list')}}",
|
||||
"subtable": "supply_contract_items"
|
||||
},
|
||||
{
|
||||
"field": "contract_id",
|
||||
"title": "合同附件",
|
||||
"url": "{{entire_url('../api/contract_attach.ui')}}?contract_type=supply",
|
||||
"subtable": "contract_attach",
|
||||
"mapping": {
|
||||
"contract_id": "id"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@ -924,4 +924,26 @@ def load_supplychain():
|
||||
env.delete_product_supplier_mapping = delete_product_supplier_mapping
|
||||
# Calculation API
|
||||
env.calculate_sale_amounts = calculate_sale_amounts
|
||||
# Attachment folder helper
|
||||
env.ensure_contract_folder = ensure_contract_folder
|
||||
return True
|
||||
|
||||
|
||||
async def ensure_contract_folder(request, contract_id, fiid):
|
||||
"""Ensure a filemgr folder exists for a contract attachment.
|
||||
Returns the folderid (uses contract_id as folder id)."""
|
||||
db, dbname = _get_sor()
|
||||
async with db.sqlorContext(dbname) as sor:
|
||||
recs = await sor.sqlExe(
|
||||
"SELECT id FROM folder WHERE fiid=${fiid}$ AND name=${name}$",
|
||||
{'fiid': fiid, 'name': contract_id}
|
||||
)
|
||||
if recs and len(recs) > 0:
|
||||
return recs[0].id
|
||||
# Create new folder
|
||||
fid = getID()
|
||||
await sor.sqlExe(
|
||||
"INSERT INTO folder (id, parentid, fiid, name, ownerid) VALUES (${id}$, ${pid}$, ${fiid}$, ${name}$, ${oid}$)",
|
||||
{'id': fid, 'pid': '0', 'fiid': fiid, 'name': contract_id, 'oid': '0'}
|
||||
)
|
||||
return fid
|
||||
|
||||
83
wwwroot/api/contract_attach.ui
Normal file
83
wwwroot/api/contract_attach.ui
Normal file
@ -0,0 +1,83 @@
|
||||
{% set contract_id = params_kw.get('contract_id', '') %}
|
||||
{% set contract_type = params_kw.get('contract_type', 'supply') %}
|
||||
{% if contract_type == 'supply' %}
|
||||
{% set fiid = 'supply_contract_attach' %}
|
||||
{% else %}
|
||||
{% set fiid = 'dist_agreement_attach' %}
|
||||
{% endif %}
|
||||
{% set folder = ensure_contract_folder(request, contract_id, fiid) %}
|
||||
{
|
||||
"widgettype": "VBox",
|
||||
"options": {
|
||||
"width": "100%",
|
||||
"padding": "8px"
|
||||
},
|
||||
"subwidgets": [
|
||||
{
|
||||
"widgettype": "HBox",
|
||||
"options": {
|
||||
"alignItems": "center",
|
||||
"marginBottom": "12px"
|
||||
},
|
||||
"subwidgets": [
|
||||
{
|
||||
"widgettype": "Title4",
|
||||
"options": {
|
||||
"fontWeight": "600",
|
||||
"otext": "合同附件",
|
||||
"i18n": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"widgettype": "Filler"
|
||||
},
|
||||
{
|
||||
"widgettype": "Button",
|
||||
"options": {
|
||||
"label": "上传附件",
|
||||
"css": "primary",
|
||||
"borderRadius": "6px",
|
||||
"padding": "4px 12px"
|
||||
},
|
||||
"binds": [{
|
||||
"wid": "self",
|
||||
"event": "click",
|
||||
"actiontype": "urlwidget",
|
||||
"target": "PopupWindow",
|
||||
"popup_options": {
|
||||
"title": "上传附件",
|
||||
"width": "450px",
|
||||
"height": "200px",
|
||||
"dismiss_events": ["cancel"]
|
||||
},
|
||||
"options": {
|
||||
"url": "{{entire_url('/filemgr/upload_file.ui')}}?id={{folder}}&fiid={{fiid}}"
|
||||
}
|
||||
}]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"widgettype": "Tabular",
|
||||
"options": {
|
||||
"css": "card",
|
||||
"width": "100%",
|
||||
"height": "auto",
|
||||
"data_url": "{{entire_url('contract_attach_list.dspy')}}?folderid={{folder}}&fiid={{fiid}}",
|
||||
"data_method": "GET",
|
||||
"page_rows": 50,
|
||||
"row_options": {
|
||||
"browserfields": {
|
||||
"exclouded": [],
|
||||
"cwidth": {}
|
||||
},
|
||||
"fields": [
|
||||
{"name": "filename", "title": "文件名", "type": "str", "uitype": "str", "label": "文件名", "cwidth": 30},
|
||||
{"name": "filesize", "title": "大小(bytes)", "type": "int", "uitype": "int", "label": "大小", "cwidth": 10},
|
||||
{"name": "filetype", "title": "类型", "type": "str", "uitype": "str", "label": "类型", "cwidth": 8}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
29
wwwroot/api/contract_attach_list.dspy
Normal file
29
wwwroot/api/contract_attach_list.dspy
Normal file
@ -0,0 +1,29 @@
|
||||
# coding=utf-8
|
||||
"""获取合同附件文件列表。
|
||||
输入: folderid, fiid
|
||||
输出: {rows: [{id, filename, filesize, filetype, webpath}]}
|
||||
"""
|
||||
folderid = params_kw.get('folderid', '')
|
||||
fiid = params_kw.get('fiid', '')
|
||||
|
||||
if not folderid:
|
||||
return json.dumps({'total': 0, 'rows': []})
|
||||
|
||||
dbname = get_module_dbname('supplychain')
|
||||
db = DBPools()
|
||||
|
||||
async with db.sqlorContext(dbname) as sor:
|
||||
recs = await sor.sqlExe(
|
||||
"SELECT id, name, filesize, filetype, webpath FROM file WHERE folderid=${folderid}$ AND fiid=${fiid}$ ORDER BY id",
|
||||
{'folderid': folderid, 'fiid': fiid}
|
||||
)
|
||||
rows = []
|
||||
for r in recs:
|
||||
rows.append({
|
||||
'id': r.id,
|
||||
'filename': r.name,
|
||||
'filesize': r.filesize or 0,
|
||||
'filetype': r.filetype or '',
|
||||
'webpath': r.webpath or ''
|
||||
})
|
||||
return json.dumps({'total': len(rows), 'rows': rows})
|
||||
Loading…
x
Reference in New Issue
Block a user