Merge dev/koko into master preserving master conflict behavior

Conflict resolution kept master-side changes for non-patrol-delete files as requested. No app/amazon/patrol_delete.py conflict was present. Existing dev/koko assets were retained so /assets resources required by new_web_source pages resolve in the Flask app.

Constraint: User requested authentication-requiring git operations be reported as commands only

Rejected: Rework non-conflicting dev/koko changes during merge | scope was conflict resolution, not feature review

Confidence: high

Scope-risk: moderate

Tested: uv run python -c Flask test client returned 200 for /new_web_source/patrol-delete.html, /assets/patrol-delete.js, /assets/pywebview-C66x_2Dh.js

Tested: uv run python -m py_compile amazon\\patrol_delete.py amazon\\detail_spider.py amazon\\price_match.py main.py

Tested: uv run --group dev pytest tests\\test_patrol_delete.py tests\\test_amazon_base.py

Not-tested: authenticated Git push/pull; Java backend build
This commit is contained in:
koko
2026-04-28 22:31:38 +08:00
186 changed files with 9652 additions and 94 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -625,7 +625,7 @@ class AmzonePriceMatch(AmamzonBase):
if len(page_pamel) > 0:
current_page = page_pamel[0].sr('xpath:.//ul[@class="pages"]//li[@aria-current="true"]').text
#测试=====
# if int(current_page) > 3:
# if int(current_page) > 3:c
# break
# 测试===========
@@ -790,7 +790,7 @@ class AmzonePriceMatch(AmamzonBase):
"cartShopName" : cartShopName,
"shippingFee" : f"{shipping_fee}",
"priceChangeStatus" : f"{adjust_prices}",
"modifyCount" : "1",
"priceChangeStatus" : "改价成功",
})
else:
recommendedPrice = recommend_price + shipping_fee
@@ -808,8 +808,7 @@ class AmzonePriceMatch(AmamzonBase):
"secondPlace": price_2,
"cartShopName": cartShopName,
"shippingFee": f"{shipping_fee}",
"priceChangeStatus": "",
"modifyCount": "0",
"priceChangeStatus": "跳过,无需改价",
})
already_asin.add(asin)
@@ -1333,36 +1332,34 @@ class PriceTask:
"""
url = f"{DELETE_BRAND_API_BASE}/api/price-track/tasks/{task_id}/result"
country_aliases = {name: code for code, name in self.country_info.items()}
country_key = country_aliases.get(str(country_code).strip(), str(country_code).strip())
countries = {}
if asin or status:
countries[country_key] = [
{
"shopMallName": shopMallName,
"asin": asin,
"price": status.get("currentPrice") if status.get("currentPrice") else "",
"recommendedPrice": status.get("recommendedPrice") if status.get("recommendedPrice") else "",
"minimumPrice": status.get("minimumPrice") if status.get("minimumPrice") else "",
"firstPlace": status.get("firstPlace") if status.get("firstPlace") else "",
"secondPlace": status.get("secondPlace") if status.get("secondPlace") else "",
"cartShopName": status.get("cartShopName") if status.get("cartShopName") else "",
"priceChangeStatus": status.get("priceChangeStatus") if status.get("priceChangeStatus") else "",
"deleteSkipAsin": status.get("deleteSkipAsin", False),
"removeAsin": status.get("removeAsin") if status.get("removeAsin") else "",
"modifyCount": status.get("modifyCount") if status.get("modifyCount") else "",
"shippingFee": status.get("shippingFee") if status.get("shippingFee") else "",
"status": status.get("statu")
}
]
payload = {
"shops": [
{
"shopName": shop_name,
"countries": countries,
"countries": {
country_key : [
{
"shopMallName": shopMallName,
"asin": asin,
"price": status.get("currentPrice") if status.get("currentPrice") else "",
"recommendedPrice": status.get("recommendedPrice") if status.get("recommendedPrice") else "",
"minimumPrice": status.get("minimumPrice") if status.get("minimumPrice") else "",
"firstPlace": status.get("firstPlace") if status.get("firstPlace") else "",
"secondPlace": status.get("secondPlace") if status.get("secondPlace") else "",
"cartShopName": status.get("cartShopName") if status.get("cartShopName") else "",
"priceChangeStatus": "UPDATED",
"deleteSkipAsin": status.get("deleteSkipAsin",False),
"removeAsin": status.get("removeAsin") if status.get("removeAsin") else "",
"modifyCount": "1",
"shippingFee" : status.get("shippingFee") if status.get("shippingFee") else "",
"status": status.get("statu"),
"priceChangeStatus" : status.get("priceChangeStatus") if status.get("priceChangeStatus") else "",
}
]
},
"error": ""
}
]
@@ -1449,4 +1446,4 @@ if __name__ == '__main__':
front_end_data, current_Price, current_shop_name,
recommended_price, recommended_shipping
)
print(res)
print(res)

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
.module-page[data-v-e32c69fa]{min-height:100vh;background:#1a1a1a}.main-content[data-v-e32c69fa]{display:flex;height:calc(100vh - 56px);min-height:calc(100vh - 56px)}.left-panel[data-v-e32c69fa]{width:400px;background:#1e1e1e;padding:20px;overflow-y:auto;border-right:1px solid #2a2a2a}.right-panel[data-v-e32c69fa]{flex:1;min-width:0;background:#1a1a1a;display:flex;flex-direction:column}.section-title[data-v-e32c69fa],.subsection-title[data-v-e32c69fa]{font-size:13px;color:#bbb;margin-bottom:10px}.upload-zone[data-v-e32c69fa]{border:1px dashed #3a3a3a;border-radius:10px;padding:18px;background:#252525;margin-bottom:18px}.hint[data-v-e32c69fa],.loading-msg[data-v-e32c69fa],.files[data-v-e32c69fa],.muted[data-v-e32c69fa]{color:#888;font-size:12px;line-height:1.5}.link[data-v-e32c69fa]{color:#6ea8fe;text-decoration:none}.link[data-v-e32c69fa]:hover{color:#9fc5ff}.btns[data-v-e32c69fa],.run-row[data-v-e32c69fa]{display:flex;gap:10px;flex-wrap:wrap}.opt-btn[data-v-e32c69fa],.btn-run[data-v-e32c69fa],.btn-delete[data-v-e32c69fa]{border:none;cursor:pointer;border-radius:7px}.opt-btn[data-v-e32c69fa]{padding:8px 14px;color:#ccc;background:#2a2a2a;border:1px solid #3a3a3a}.btn-run[data-v-e32c69fa]{padding:10px 18px;color:#fff;background:#3498db;font-weight:600}.btn-queue[data-v-e32c69fa]{background:#27ae60}.btn-run[data-v-e32c69fa]:disabled{opacity:.55;cursor:not-allowed}.selected-files[data-v-e32c69fa]{margin-top:14px;color:#999;font-size:12px;word-break:break-all}.selected-files span[data-v-e32c69fa]{display:block;margin:4px 0}.prompt-card[data-v-e32c69fa]{margin-bottom:18px}.prompt-input[data-v-e32c69fa]{width:100%;box-sizing:border-box;resize:vertical;min-height:180px;padding:10px 12px;border:1px solid #333;border-radius:8px;background:#202020;color:#d8d8d8;font-size:12px;line-height:1.6;outline:none}.prompt-input[data-v-e32c69fa]:focus{border-color:#3498db}.prompt-default-label[data-v-e32c69fa]{margin-top:10px;color:#8d8d8d;font-size:12px}.prompt-preview[data-v-e32c69fa]{margin-top:10px;padding:12px;border:1px solid #2a2a2a;border-radius:8px;background:#202020;color:#9ea7b3;font-size:12px;line-height:1.6;white-space:pre-wrap}.parse-card[data-v-e32c69fa],.queue-payload[data-v-e32c69fa]{margin-top:14px;padding:12px;border:1px solid #2a2a2a;border-radius:8px;background:#202020;color:#b8c1cc;font-size:12px}.queue-payload[data-v-e32c69fa]{max-height:220px;overflow:auto;color:#8fd3ff;white-space:pre-wrap}.panel-header[data-v-e32c69fa]{padding:16px 20px;border-bottom:1px solid #2a2a2a;font-size:15px;font-weight:600;color:#ddd}.task-list-wrap[data-v-e32c69fa]{flex:1;padding:16px 20px;overflow:auto}.clean-result-summary[data-v-e32c69fa]{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px;margin-bottom:16px}.summary-card[data-v-e32c69fa]{padding:14px 16px;border:1px solid #2a2a2a;border-radius:8px;background:#1e1e1e}.summary-card strong[data-v-e32c69fa]{display:block;margin-top:8px;color:#eaf4ff;font-size:22px}.summary-label[data-v-e32c69fa]{color:#8d8d8d;font-size:12px}.result-list-wrap[data-v-e32c69fa]{border:1px solid #2a2a2a;border-radius:8px;background:#1e1e1e;min-height:180px;margin:0 0 16px}.result-list-header[data-v-e32c69fa]{display:flex;justify-content:space-between;padding:12px 16px;border-bottom:1px solid #2a2a2a;color:#ddd;font-size:14px}.empty-tasks[data-v-e32c69fa]{color:#666;font-size:13px;padding:18px;text-align:center}.result-table[data-v-e32c69fa]{--el-table-bg-color: #222;--el-table-tr-bg-color: #222;--el-table-header-bg-color: #2a2a2a;--el-table-text-color: #ccc;--el-table-border-color: #333}.task-list[data-v-e32c69fa]{list-style:none;margin:0;padding:12px}.task-item[data-v-e32c69fa]{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;padding:12px 14px;border:1px solid #2a2a2a;border-radius:8px;margin-bottom:8px;background:#222}.left[data-v-e32c69fa]{flex:1;min-width:0}.id[data-v-e32c69fa]{color:#e0e0e0;font-size:13px;font-weight:600}.task-right[data-v-e32c69fa]{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.status[data-v-e32c69fa]{padding:4px 10px;border-radius:6px;font-size:12px}.status.success[data-v-e32c69fa]{background:#2ecc712e;color:#2ecc71}.status.failed[data-v-e32c69fa]{background:#e74c3c2e;color:#ff6b6b}.status.running[data-v-e32c69fa]{background:#3498db2e;color:#3498db}.btn-delete[data-v-e32c69fa]{padding:6px 10px;color:#ff8f8f;background:#e74c3c1f}@media(max-width:1100px){.main-content[data-v-e32c69fa]{flex-direction:column;height:auto}.left-panel[data-v-e32c69fa]{width:100%;border-right:none;border-bottom:1px solid #2a2a2a}.clean-result-summary[data-v-e32c69fa]{grid-template-columns:repeat(2,minmax(0,1fr))}}

View File

@@ -0,0 +1 @@
.module-page[data-v-d71413c4]{min-height:100vh;background:#1a1a1a}.main-content[data-v-d71413c4]{display:flex;height:calc(100vh - 56px);min-height:calc(100vh - 56px)}.left-panel[data-v-d71413c4]{width:400px;background:#1e1e1e;padding:20px;overflow-y:auto;border-right:1px solid #2a2a2a}.right-panel[data-v-d71413c4]{flex:1;min-width:0;background:#1a1a1a;display:flex;flex-direction:column}.section-title[data-v-d71413c4],.subsection-title[data-v-d71413c4]{font-size:13px;color:#bbb;margin-bottom:10px}.upload-zone[data-v-d71413c4]{border:1px dashed #3a3a3a;border-radius:10px;padding:18px;background:#252525;margin-bottom:18px}.hint[data-v-d71413c4],.loading-msg[data-v-d71413c4],.files[data-v-d71413c4],.muted[data-v-d71413c4]{color:#888;font-size:12px;line-height:1.5}.link[data-v-d71413c4]{color:#6ea8fe;text-decoration:none}.link[data-v-d71413c4]:hover{color:#9fc5ff}.btns[data-v-d71413c4],.run-row[data-v-d71413c4]{display:flex;gap:10px;flex-wrap:wrap}.opt-btn[data-v-d71413c4],.btn-run[data-v-d71413c4],.btn-delete[data-v-d71413c4],.download[data-v-d71413c4]{border:none;cursor:pointer;border-radius:7px}.opt-btn[data-v-d71413c4]{padding:8px 14px;color:#ccc;background:#2a2a2a;border:1px solid #3a3a3a}.btn-run[data-v-d71413c4]{padding:10px 18px;color:#fff;background:#3498db;font-weight:600}.btn-queue[data-v-d71413c4]{background:#27ae60}.btn-run[data-v-d71413c4]:disabled{opacity:.55;cursor:not-allowed}.selected-files[data-v-d71413c4]{margin-top:14px;color:#999;font-size:12px;word-break:break-all}.selected-files span[data-v-d71413c4]{display:block;margin:4px 0}.prompt-card[data-v-d71413c4]{margin-bottom:18px}.prompt-input[data-v-d71413c4]{width:100%;box-sizing:border-box;resize:vertical;min-height:180px;padding:10px 12px;border:1px solid #333;border-radius:8px;background:#202020;color:#d8d8d8;font-size:12px;line-height:1.6;outline:none}.prompt-input[data-v-d71413c4]:focus{border-color:#3498db}.prompt-default-label[data-v-d71413c4]{margin-top:10px;color:#8d8d8d;font-size:12px}.prompt-preview[data-v-d71413c4]{margin-top:10px;padding:12px;border:1px solid #2a2a2a;border-radius:8px;background:#202020;color:#9ea7b3;font-size:12px;line-height:1.6;white-space:pre-wrap}.parse-card[data-v-d71413c4],.queue-payload[data-v-d71413c4]{margin-top:14px;padding:12px;border:1px solid #2a2a2a;border-radius:8px;background:#202020;color:#b8c1cc;font-size:12px}.queue-payload[data-v-d71413c4]{max-height:220px;overflow:auto;color:#8fd3ff;white-space:pre-wrap}.panel-header[data-v-d71413c4]{padding:16px 20px;border-bottom:1px solid #2a2a2a;font-size:15px;font-weight:600;color:#ddd}.task-list-wrap[data-v-d71413c4]{flex:1;padding:16px 20px;overflow:auto}.clean-result-summary[data-v-d71413c4]{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px;margin-bottom:16px}.summary-card[data-v-d71413c4]{padding:14px 16px;border:1px solid #2a2a2a;border-radius:8px;background:#1e1e1e}.summary-card strong[data-v-d71413c4]{display:block;margin-top:8px;color:#eaf4ff;font-size:22px}.summary-label[data-v-d71413c4]{color:#8d8d8d;font-size:12px}.result-list-wrap[data-v-d71413c4]{border:1px solid #2a2a2a;border-radius:8px;background:#1e1e1e;min-height:180px;margin:0 0 16px}.result-list-header[data-v-d71413c4]{display:flex;justify-content:space-between;padding:12px 16px;border-bottom:1px solid #2a2a2a;color:#ddd;font-size:14px}.empty-tasks[data-v-d71413c4]{color:#666;font-size:13px;padding:18px;text-align:center}.result-table[data-v-d71413c4]{--el-table-bg-color: #222;--el-table-tr-bg-color: #222;--el-table-header-bg-color: #2a2a2a;--el-table-text-color: #ccc;--el-table-border-color: #333}.task-list[data-v-d71413c4]{list-style:none;margin:0;padding:12px}.task-item[data-v-d71413c4]{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;padding:12px 14px;border:1px solid #2a2a2a;border-radius:8px;margin-bottom:8px;background:#222}.left[data-v-d71413c4]{flex:1;min-width:0}.id[data-v-d71413c4]{color:#e0e0e0;font-size:13px;font-weight:600}.task-right[data-v-d71413c4]{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.status[data-v-d71413c4]{padding:4px 10px;border-radius:6px;font-size:12px}.status.success[data-v-d71413c4]{background:#2ecc712e;color:#2ecc71}.status.failed[data-v-d71413c4]{background:#e74c3c2e;color:#ff6b6b}.status.running[data-v-d71413c4]{background:#3498db2e;color:#3498db}.result-hint[data-v-d71413c4]{margin-top:6px;color:#e0b96d}.download[data-v-d71413c4]{padding:6px 10px;color:#d6ecff;background:#3498db2e}.btn-delete[data-v-d71413c4]{padding:6px 10px;color:#ff8f8f;background:#e74c3c1f}@media(max-width:1100px){.main-content[data-v-d71413c4]{flex-direction:column;height:auto}.left-panel[data-v-d71413c4]{width:100%;border-right:none;border-bottom:1px solid #2a2a2a}.clean-result-summary[data-v-d71413c4]{grid-template-columns:repeat(2,minmax(0,1fr))}}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
import{Q as r}from"./pywebview-V_UIajJm.js";const n="";function s(e){return r(`${n}/api/brand/expand-folder-recursive`,{folder:e})}export{s as e};

View File

@@ -0,0 +1 @@
import{aV as r}from"./pywebview-Bt854mYs.js";const n="";function a(e){return r(`${n}/api/brand/expand-folder-recursive`,{folder:e})}export{a as e};

View File

@@ -0,0 +1 @@
import{Q as r}from"./pywebview-DiP0HdY6.js";const n="";function s(e){return r(`${n}/api/brand/expand-folder-recursive`,{folder:e})}export{s as e};

View File

@@ -0,0 +1 @@
import{aZ as r}from"./pywebview-C66x_2Dh.js";const n="";function a(e){return r(`${n}/api/brand/expand-folder-recursive`,{folder:e})}export{a as e};

View File

@@ -0,0 +1 @@
import{Q as r}from"./pywebview-Cs1Kot1q.js";const n="";function s(e){return r(`${n}/api/brand/expand-folder-recursive`,{folder:e})}export{s as e};

View File

@@ -0,0 +1 @@
import{Q as r}from"./pywebview-BCPdlDdb.js";const n="";function s(e){return r(`${n}/api/brand/expand-folder-recursive`,{folder:e})}export{s as e};

View File

@@ -0,0 +1 @@
import{aO as r}from"./pywebview-DuyK2jB1.js";const n="";function a(e){return r(`${n}/api/brand/expand-folder-recursive`,{folder:e})}export{a as e};

View File

@@ -0,0 +1 @@
import{aO as r}from"./pywebview-9YBa--7x.js";const n="";function a(e){return r(`${n}/api/brand/expand-folder-recursive`,{folder:e})}export{a as e};

View File

@@ -0,0 +1 @@
import{aI as r}from"./pywebview-D4gpiFjY.js";const n="";function a(e){return r(`${n}/api/brand/expand-folder-recursive`,{folder:e})}export{a as e};

View File

@@ -0,0 +1 @@
import{aO as r}from"./pywebview-ClWy2SbE.js";const n="";function a(e){return r(`${n}/api/brand/expand-folder-recursive`,{folder:e})}export{a as e};

View File

@@ -0,0 +1 @@
import{Q as r}from"./pywebview-D808cNhy.js";const n="";function s(e){return r(`${n}/api/brand/expand-folder-recursive`,{folder:e})}export{s as e};

View File

@@ -0,0 +1 @@
import{Q as r}from"./pywebview-Cq_E2BnJ.js";const n="";function s(e){return r(`${n}/api/brand/expand-folder-recursive`,{folder:e})}export{s as e};

View File

@@ -0,0 +1 @@
import{Q as r}from"./pywebview-D7_PdvyM.js";const n="";function s(e){return r(`${n}/api/brand/expand-folder-recursive`,{folder:e})}export{s as e};

View File

@@ -0,0 +1 @@
import{aO as r}from"./pywebview-CeWJDVeG.js";const n="";function a(e){return r(`${n}/api/brand/expand-folder-recursive`,{folder:e})}export{a as e};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
const e=[{value:"SearchSuppressed",label:"在搜索结果中禁止显示"},{value:"ApprovalRequired",label:"需要批准"},{value:"Active",label:"在售"}];export{e as L};

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
const e=[{value:"SearchSuppressed",label:"在搜索结果中禁止显示"},{value:"ApprovalRequired",label:"需要批准"},{value:"Active",label:"在售"},{value:"DetailPageRemoved",label:"详情页面已删除"}];export{e as L};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More