Merge pull request #137 from leordsong/feature/douyin-productlink
Browse files
sau_frontend/src/views/PublishCenter.vue
CHANGED
|
@@ -529,9 +529,19 @@ const defaultTabInit = {
|
|
| 529 |
publishStatus: null // 发布状态,包含message和type
|
| 530 |
}
|
| 531 |
|
| 532 |
-
//
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 533 |
const tabs = reactive([
|
| 534 |
-
|
| 535 |
])
|
| 536 |
|
| 537 |
// 账号相关状态
|
|
@@ -568,9 +578,9 @@ const recommendedTopics = [
|
|
| 568 |
// 添加新tab
|
| 569 |
const addTab = () => {
|
| 570 |
tabCounter++
|
| 571 |
-
const newTab =
|
| 572 |
-
newTab
|
| 573 |
-
newTab
|
| 574 |
tabs.push(newTab)
|
| 575 |
activeTab.value = newTab.name
|
| 576 |
}
|
|
|
|
| 529 |
publishStatus: null // 发布状态,包含message和type
|
| 530 |
}
|
| 531 |
|
| 532 |
+
// helper to create a fresh deep-copied tab from defaultTabInit
|
| 533 |
+
const makeNewTab = () => {
|
| 534 |
+
// prefer structuredClone when available (newer browsers/node), fallback to JSON
|
| 535 |
+
try {
|
| 536 |
+
return typeof structuredClone === 'function' ? structuredClone(defaultTabInit) : JSON.parse(JSON.stringify(defaultTabInit))
|
| 537 |
+
} catch (e) {
|
| 538 |
+
return JSON.parse(JSON.stringify(defaultTabInit))
|
| 539 |
+
}
|
| 540 |
+
}
|
| 541 |
+
|
| 542 |
+
// tab页数据 - 默认只有一个tab (use deep copy to avoid shared refs)
|
| 543 |
const tabs = reactive([
|
| 544 |
+
makeNewTab()
|
| 545 |
])
|
| 546 |
|
| 547 |
// 账号相关状态
|
|
|
|
| 578 |
// 添加新tab
|
| 579 |
const addTab = () => {
|
| 580 |
tabCounter++
|
| 581 |
+
const newTab = makeNewTab()
|
| 582 |
+
newTab.name = `tab${tabCounter}`
|
| 583 |
+
newTab.label = `发布${tabCounter}`
|
| 584 |
tabs.push(newTab)
|
| 585 |
activeTab.value = newTab.name
|
| 586 |
}
|
uploader/douyin_uploader/main.py
CHANGED
|
@@ -257,6 +257,7 @@ class DouYinVideo(object):
|
|
| 257 |
"""处理商品编辑弹窗"""
|
| 258 |
|
| 259 |
await page.wait_for_timeout(2000)
|
|
|
|
| 260 |
short_title_input = page.locator('input[placeholder="请输入商品短标题"]')
|
| 261 |
if not await short_title_input.count():
|
| 262 |
douyin_logger.error("[-] 未找到商品短标题输入框")
|
|
@@ -292,6 +293,7 @@ class DouYinVideo(object):
|
|
| 292 |
"""设置商品链接功能"""
|
| 293 |
try:
|
| 294 |
# 定位"添加标签"文本,然后向上导航到容器,再找到下拉框
|
|
|
|
| 295 |
dropdown = page.get_by_text('添加标签').locator("..").locator("..").locator("..").locator(".semi-select").first
|
| 296 |
if not await dropdown.count():
|
| 297 |
douyin_logger.error("[-] 未找到标签下拉框")
|
|
@@ -321,6 +323,15 @@ class DouYinVideo(object):
|
|
| 321 |
return False
|
| 322 |
await add_button.click()
|
| 323 |
douyin_logger.debug("[+] 成功点击'添加链接'按钮")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 324 |
|
| 325 |
# 填写商品短标题
|
| 326 |
if not await self.handle_product_dialog(page, product_title):
|
|
|
|
| 257 |
"""处理商品编辑弹窗"""
|
| 258 |
|
| 259 |
await page.wait_for_timeout(2000)
|
| 260 |
+
await page.wait_for_selector('input[placeholder="请输入商品短标题"]', timeout=10000)
|
| 261 |
short_title_input = page.locator('input[placeholder="请输入商品短标题"]')
|
| 262 |
if not await short_title_input.count():
|
| 263 |
douyin_logger.error("[-] 未找到商品短标题输入框")
|
|
|
|
| 293 |
"""设置商品链接功能"""
|
| 294 |
try:
|
| 295 |
# 定位"添加标签"文本,然后向上导航到容器,再找到下拉框
|
| 296 |
+
await page.wait_for_selector('text=添加标签', timeout=10000)
|
| 297 |
dropdown = page.get_by_text('添加标签').locator("..").locator("..").locator("..").locator(".semi-select").first
|
| 298 |
if not await dropdown.count():
|
| 299 |
douyin_logger.error("[-] 未找到标签下拉框")
|
|
|
|
| 323 |
return False
|
| 324 |
await add_button.click()
|
| 325 |
douyin_logger.debug("[+] 成功点击'添加链接'按钮")
|
| 326 |
+
## 如果链接不可用
|
| 327 |
+
await page.wait_for_timeout(2000)
|
| 328 |
+
error_modal = page.locator('text=未搜索到对应商品')
|
| 329 |
+
if await error_modal.count():
|
| 330 |
+
confirm_button = page.locator('button:has-text("确定")')
|
| 331 |
+
await confirm_button.click()
|
| 332 |
+
# await page.wait_for_selector('.semi-modal-content', state='hidden', timeout=5000)
|
| 333 |
+
douyin_logger.error("[-] 商品链接无效")
|
| 334 |
+
return False
|
| 335 |
|
| 336 |
# 填写商品短标题
|
| 337 |
if not await self.handle_product_dialog(page, product_title):
|