更改下载类型处理
This commit is contained in:
4
app/.env
4
app/.env
@@ -12,7 +12,7 @@ zn_username=%E8%87%AA%E5%8A%A8%E5%8C%96_Robot
|
|||||||
client_name=ShuFuAI
|
client_name=ShuFuAI
|
||||||
|
|
||||||
|
|
||||||
java_api_base=http://127.0.0.1:18080
|
# java_api_base=http://127.0.0.1:18080
|
||||||
# java_api_base=http://8.136.19.173:18080
|
java_api_base=http://8.136.19.173:18080
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
27
app/main.py
27
app/main.py
@@ -154,17 +154,36 @@ class WindowAPI:
|
|||||||
)
|
)
|
||||||
return result[0] if result else ''
|
return result[0] if result else ''
|
||||||
|
|
||||||
def save_file_from_url(self, url, default_filename='download.zip'):
|
def save_file_from_url(self, url, default_filename='download.bin'):
|
||||||
"""弹窗选择保存位置,从 url 下载文件并保存。用于品牌任务结果 zip 等。"""
|
"""弹窗选择保存位置,从 url 下载文件并保存。根据文件后缀动态设置保存类型。"""
|
||||||
if not url or not url.strip():
|
if not url or not url.strip():
|
||||||
return {'success': False, 'error': '下载地址为空'}
|
return {'success': False, 'error': '下载地址为空'}
|
||||||
|
|
||||||
|
filename = str(default_filename or 'download.bin').strip() or 'download.bin'
|
||||||
|
ext = os.path.splitext(filename)[1].lower()
|
||||||
|
|
||||||
|
# 根据默认文件名后缀动态设置文件类型,避免固定为 zip 造成误导
|
||||||
|
if ext == '.zip':
|
||||||
|
file_types = ('ZIP 压缩包 (*.zip)', '所有文件 (*.*)')
|
||||||
|
elif ext in ('.xlsx', '.xls'):
|
||||||
|
file_types = ('Excel 文件 (*.xlsx;*.xls)', '所有文件 (*.*)')
|
||||||
|
elif ext == '.csv':
|
||||||
|
file_types = ('CSV 文件 (*.csv)', '所有文件 (*.*)')
|
||||||
|
elif ext == '.txt':
|
||||||
|
file_types = ('文本文件 (*.txt)', '所有文件 (*.*)')
|
||||||
|
elif ext == '.json':
|
||||||
|
file_types = ('JSON 文件 (*.json)', '所有文件 (*.*)')
|
||||||
|
else:
|
||||||
|
file_types = ('所有文件 (*.*)',)
|
||||||
|
|
||||||
result = self._window.create_file_dialog(
|
result = self._window.create_file_dialog(
|
||||||
webview.SAVE_DIALOG,
|
webview.SAVE_DIALOG,
|
||||||
save_filename=default_filename,
|
save_filename=filename,
|
||||||
file_types=('ZIP 压缩包 (*.zip)', '所有文件 (*.*)')
|
file_types=file_types
|
||||||
)
|
)
|
||||||
if not result:
|
if not result:
|
||||||
return {'success': False, 'error': '用户取消'}
|
return {'success': False, 'error': '用户取消'}
|
||||||
|
|
||||||
path = result[0] if isinstance(result, (list, tuple)) else result
|
path = result[0] if isinstance(result, (list, tuple)) else result
|
||||||
try:
|
try:
|
||||||
import requests
|
import requests
|
||||||
|
|||||||
@@ -75,6 +75,24 @@
|
|||||||
</div>
|
</div>
|
||||||
<div v-if="countryPrefSaving" class="country-pref-status">保存中…</div>
|
<div v-if="countryPrefSaving" class="country-pref-status">保存中…</div>
|
||||||
|
|
||||||
|
<div class="section-title">商品列表筛选</div>
|
||||||
|
<p class="hint listing-filter-hint">与「推送到 Python 队列」一并下发,供 Python 区分处理场景。</p>
|
||||||
|
<div class="listing-filter-row">
|
||||||
|
<el-select
|
||||||
|
v-model="productRiskListingFilter"
|
||||||
|
class="listing-filter-select"
|
||||||
|
teleported
|
||||||
|
placeholder="选择筛选类型"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="opt in PRODUCT_RISK_LISTING_FILTER_OPTIONS"
|
||||||
|
:key="opt.value"
|
||||||
|
:label="opt.label"
|
||||||
|
:value="opt.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="run-row">
|
<div class="run-row">
|
||||||
<button type="button" class="btn-run" :disabled="matching" @click="runMatch">
|
<button type="button" class="btn-run" :disabled="matching" @click="runMatch">
|
||||||
{{ matching ? '匹配中…' : '匹配店铺' }}
|
{{ matching ? '匹配中…' : '匹配店铺' }}
|
||||||
@@ -271,7 +289,16 @@ const COUNTRY_OPTIONS = [
|
|||||||
{ code: 'ES', label: '西班牙' },
|
{ code: 'ES', label: '西班牙' },
|
||||||
] as const
|
] as const
|
||||||
|
|
||||||
|
/** 与 Python 约定:队列 payload.data.risk_listing_filter */
|
||||||
|
const PRODUCT_RISK_LISTING_FILTER_OPTIONS = [
|
||||||
|
{ value: 'SearchSuppressed', label: '在搜索结果中禁止显示' },
|
||||||
|
{ value: 'ApprovalRequired', label: '需要批准' },
|
||||||
|
] as const
|
||||||
|
|
||||||
|
type ProductRiskListingFilter = (typeof PRODUCT_RISK_LISTING_FILTER_OPTIONS)[number]['value']
|
||||||
|
|
||||||
const orderedCountryCodes = ref<string[]>(['DE', 'UK', 'FR', 'IT', 'ES'])
|
const orderedCountryCodes = ref<string[]>(['DE', 'UK', 'FR', 'IT', 'ES'])
|
||||||
|
const productRiskListingFilter = ref<ProductRiskListingFilter>('SearchSuppressed')
|
||||||
const dragCountryIndex = ref<number | null>(null)
|
const dragCountryIndex = ref<number | null>(null)
|
||||||
const countryPrefSaving = ref(false)
|
const countryPrefSaving = ref(false)
|
||||||
/** 用户已改过顺序/勾选后,忽略晚到的 GET,避免把界面打回全选 */
|
/** 用户已改过顺序/勾选后,忽略晚到的 GET,避免把界面打回全选 */
|
||||||
@@ -928,6 +955,7 @@ async function pushToPythonQueue() {
|
|||||||
taskId: created.taskId,
|
taskId: created.taskId,
|
||||||
items: [item],
|
items: [item],
|
||||||
country_codes: [...orderedCountryCodes.value],
|
country_codes: [...orderedCountryCodes.value],
|
||||||
|
risk_listing_filter: productRiskListingFilter.value,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
queuePayloadText.value = JSON.stringify(payload, null, 2)
|
queuePayloadText.value = JSON.stringify(payload, null, 2)
|
||||||
@@ -1112,6 +1140,28 @@ onUnmounted(() => {
|
|||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.listing-filter-hint {
|
||||||
|
margin-top: -4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.listing-filter-row {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.listing-filter-select {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.listing-filter-row :deep(.el-select__wrapper) {
|
||||||
|
background-color: #2a2a2a;
|
||||||
|
box-shadow: 0 0 0 1px #3a3a3a inset;
|
||||||
|
}
|
||||||
|
|
||||||
|
.listing-filter-row :deep(.el-select__placeholder),
|
||||||
|
.listing-filter-row :deep(.el-select__selected-item) {
|
||||||
|
color: #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
.input-row {
|
.input-row {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
|
|||||||
Reference in New Issue
Block a user