tt-help-cli-ycl 1.4.149 → 1.4.151

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1703,6 +1703,194 @@ td.user-id:hover {
1703
1703
  display: block;
1704
1704
  }
1705
1705
 
1706
+ .settings-layout {
1707
+ display: flex;
1708
+ gap: 20px;
1709
+ max-width: 860px;
1710
+ margin: 0 auto;
1711
+ align-items: flex-start;
1712
+ }
1713
+
1714
+ .settings-nav {
1715
+ width: 170px;
1716
+ flex-shrink: 0;
1717
+ display: flex;
1718
+ flex-direction: column;
1719
+ gap: 6px;
1720
+ position: sticky;
1721
+ top: 16px;
1722
+ }
1723
+
1724
+ .settings-nav-item {
1725
+ text-align: left;
1726
+ padding: 10px 14px;
1727
+ background: #1a1a24;
1728
+ border: 1px solid transparent;
1729
+ border-radius: 10px;
1730
+ color: #999;
1731
+ cursor: pointer;
1732
+ font-size: 13px;
1733
+ transition: color 0.15s, background 0.15s, border-color 0.15s;
1734
+ }
1735
+
1736
+ .settings-nav-item:hover {
1737
+ color: #ccc;
1738
+ }
1739
+
1740
+ .settings-nav-item.active {
1741
+ color: #60a5fa;
1742
+ border-color: rgba(96, 165, 250, 0.4);
1743
+ background: rgba(96, 165, 250, 0.08);
1744
+ }
1745
+
1746
+ .settings-panels {
1747
+ flex: 1;
1748
+ min-width: 0;
1749
+ }
1750
+
1751
+ .settings-panel {
1752
+ display: none;
1753
+ }
1754
+
1755
+ .settings-panel.active {
1756
+ display: block;
1757
+ }
1758
+
1759
+ .settings-panel .settings-card {
1760
+ margin: 0;
1761
+ }
1762
+
1763
+ @media (max-width: 720px) {
1764
+ .settings-layout {
1765
+ flex-direction: column;
1766
+ }
1767
+ .settings-nav {
1768
+ width: 100%;
1769
+ flex-direction: row;
1770
+ flex-wrap: wrap;
1771
+ position: static;
1772
+ }
1773
+ }
1774
+
1775
+ /* ---- 目标国家宫格(拖拽排序) ---- */
1776
+ .loc-chips {
1777
+ display: flex;
1778
+ flex-wrap: wrap;
1779
+ gap: 10px;
1780
+ }
1781
+
1782
+ .loc-chip {
1783
+ display: flex;
1784
+ align-items: center;
1785
+ gap: 6px;
1786
+ padding: 8px 10px;
1787
+ background: #1a1a24;
1788
+ border: 1px solid #333;
1789
+ border-radius: 10px;
1790
+ cursor: grab;
1791
+ user-select: none;
1792
+ font-size: 13px;
1793
+ color: #e0e0e0;
1794
+ }
1795
+
1796
+ .loc-chip:active {
1797
+ cursor: grabbing;
1798
+ }
1799
+
1800
+ .loc-chip.dragging {
1801
+ opacity: 0.4;
1802
+ cursor: grabbing;
1803
+ }
1804
+
1805
+ .loc-chip.drop-before {
1806
+ box-shadow: -3px 0 0 0 #60a5fa;
1807
+ }
1808
+
1809
+ .loc-chip.drop-after {
1810
+ box-shadow: 3px 0 0 0 #60a5fa;
1811
+ }
1812
+
1813
+ .loc-chip-idx {
1814
+ min-width: 18px;
1815
+ height: 18px;
1816
+ display: inline-flex;
1817
+ align-items: center;
1818
+ justify-content: center;
1819
+ background: rgba(96, 165, 250, 0.15);
1820
+ color: #60a5fa;
1821
+ border-radius: 5px;
1822
+ font-size: 11px;
1823
+ font-weight: 600;
1824
+ }
1825
+
1826
+ .loc-chip-flag {
1827
+ font-size: 15px;
1828
+ }
1829
+
1830
+ .loc-chip-code {
1831
+ font-weight: 600;
1832
+ letter-spacing: 0.5px;
1833
+ }
1834
+
1835
+ .loc-chip-del {
1836
+ background: none;
1837
+ border: none;
1838
+ color: #666;
1839
+ font-size: 14px;
1840
+ cursor: pointer;
1841
+ padding: 0 2px;
1842
+ line-height: 1;
1843
+ }
1844
+
1845
+ .loc-chip-del:hover {
1846
+ color: #f87171;
1847
+ }
1848
+
1849
+ .loc-chip-add {
1850
+ border: 1px dashed #555;
1851
+ color: #888;
1852
+ background: transparent;
1853
+ font-size: 16px;
1854
+ cursor: pointer;
1855
+ padding: 8px 14px;
1856
+ }
1857
+
1858
+ .loc-chip-add:hover {
1859
+ border-color: #60a5fa;
1860
+ color: #60a5fa;
1861
+ }
1862
+
1863
+ .country-picker {
1864
+ margin-top: 12px;
1865
+ padding: 14px;
1866
+ background: #14141c;
1867
+ border: 1px solid #2a2a38;
1868
+ border-radius: 10px;
1869
+ }
1870
+
1871
+ .country-picker-title {
1872
+ font-size: 12px;
1873
+ color: #888;
1874
+ margin-bottom: 10px;
1875
+ }
1876
+
1877
+ .country-picker .custom-loc-row {
1878
+ display: flex;
1879
+ gap: 8px;
1880
+ margin-top: 12px;
1881
+ }
1882
+
1883
+ .country-picker .custom-loc-input {
1884
+ flex: 1;
1885
+ padding: 8px 10px;
1886
+ background: #111;
1887
+ border: 1px solid #333;
1888
+ color: #e0e0e0;
1889
+ border-radius: 6px;
1890
+ font-size: 12px;
1891
+ text-transform: uppercase;
1892
+ }
1893
+
1706
1894
  .settings-card {
1707
1895
  background: #1a1a24;
1708
1896
  border-radius: 12px;
@@ -1908,6 +2096,85 @@ td.user-id:hover {
1908
2096
  }
1909
2097
 
1910
2098
  /* ===== 精准商家:视频卡片视图 ===== */
2099
+ /* ── 精准商家页 SKU 列与弹窗 ── */
2100
+ .sku-cell {
2101
+ cursor: pointer;
2102
+ color: #60a5fa;
2103
+ white-space: nowrap;
2104
+ }
2105
+ .sku-cell:hover {
2106
+ text-decoration: underline;
2107
+ }
2108
+ .sku-modal {
2109
+ width: 640px;
2110
+ display: flex;
2111
+ flex-direction: column;
2112
+ max-height: 80vh;
2113
+ }
2114
+ .sku-modal-meta {
2115
+ font-size: 12px;
2116
+ color: #9ca3af;
2117
+ margin: 6px 0 12px;
2118
+ display: flex;
2119
+ flex-direction: column;
2120
+ gap: 4px;
2121
+ }
2122
+ .sku-modal-name {
2123
+ color: #e0e0e0;
2124
+ font-size: 13px;
2125
+ }
2126
+ .sku-modal-link {
2127
+ color: #60a5fa;
2128
+ text-decoration: none;
2129
+ font-size: 12px;
2130
+ }
2131
+ .sku-modal-link:hover {
2132
+ text-decoration: underline;
2133
+ }
2134
+ .sku-table-wrap {
2135
+ overflow: auto;
2136
+ border: 1px solid #2a2a3a;
2137
+ border-radius: 8px;
2138
+ }
2139
+ .sku-table {
2140
+ width: 100%;
2141
+ border-collapse: collapse;
2142
+ font-size: 12px;
2143
+ }
2144
+ .sku-table th {
2145
+ position: sticky;
2146
+ top: 0;
2147
+ background: #14141d;
2148
+ color: #9ca3af;
2149
+ text-align: left;
2150
+ padding: 8px 10px;
2151
+ border-bottom: 1px solid #2a2a3a;
2152
+ }
2153
+ .sku-table td {
2154
+ padding: 6px 10px;
2155
+ border-bottom: 1px solid #22222e;
2156
+ color: #d1d5db;
2157
+ }
2158
+ .sku-spec {
2159
+ max-width: 320px;
2160
+ overflow: hidden;
2161
+ text-overflow: ellipsis;
2162
+ white-space: nowrap;
2163
+ }
2164
+ .sku-id {
2165
+ color: #6b7280;
2166
+ font-family: monospace;
2167
+ }
2168
+ .sku-ok {
2169
+ color: #4ade80;
2170
+ }
2171
+ .sku-low {
2172
+ color: #fbbf24;
2173
+ }
2174
+ .sku-oos {
2175
+ color: #f87171;
2176
+ }
2177
+
1911
2178
  .precise-list-header {
1912
2179
  display: flex;
1913
2180
  align-items: center;
@@ -592,6 +592,9 @@ export function startWatchServer(
592
592
  "CREATE INDEX IF NOT EXISTS idx_videos_user_update ON videos(user_update_count)",
593
593
  // product-fill 领任务查询的部分索引:只索引候选行,避免全表扫描 164 万行
594
594
  "CREATE INDEX IF NOT EXISTS idx_jobs_product_fill ON jobs(claimed_at, updated_at) WHERE top_video_seo_url IS NOT NULL AND top_video_seo_url != '' AND (product_name IS NULL OR product_name = '') AND product_rating IS NULL AND product_sold_count IS NULL",
595
+ // precheck 候选查询部分索引:预缩候选集且天然按 refresh_time 有序,
596
+ // 消除 TEMP B-TREE 排序(76 万行实测 ~1s → 毫秒级)
597
+ "CREATE INDEX IF NOT EXISTS idx_jobs_precheck ON jobs(refresh_time) WHERE tt_seller = 1 AND verified = 0 AND (pending_refresh IS NULL OR pending_refresh = 0)",
595
598
  ];
596
599
  for (const sql of ensureIdx) {
597
600
  try {
@@ -1607,6 +1610,17 @@ export function startWatchServer(
1607
1610
  productReviewCount: u.productReviewCount ?? null,
1608
1611
  productSoldCount: u.productSoldCount ?? null,
1609
1612
  productName: u.productName || null,
1613
+ skuCount: u.skuCount || 0,
1614
+ skuTotalStock: u.skuTotalStock || 0,
1615
+ productSkus: (() => {
1616
+ try {
1617
+ return Array.isArray(u.productSkus)
1618
+ ? u.productSkus
1619
+ : JSON.parse(u.productSkus || "[]");
1620
+ } catch {
1621
+ return [];
1622
+ }
1623
+ })(),
1610
1624
  ecOver1k: u.ecOver1k || 0,
1611
1625
  maxEcPlay: u.maxEcPlay || null,
1612
1626
  recentEcVideos: (() => {
@@ -2169,7 +2183,7 @@ export function startWatchServer(
2169
2183
  }
2170
2184
  const targetCountries = Array.isArray(body.countries)
2171
2185
  ? body.countries
2172
- : ["ES"];
2186
+ : getTargetLocations();
2173
2187
  const serverUrl = body.serverUrl || null;
2174
2188
 
2175
2189
  const { scoreTag } = await import("./tag-service.js");
@@ -2192,7 +2206,7 @@ export function startWatchServer(
2192
2206
  const limit = Math.min(parseInt(body.limit) || 10, 50);
2193
2207
  const targetCountries = Array.isArray(body.countries)
2194
2208
  ? body.countries
2195
- : ["ES"];
2209
+ : getTargetLocations();
2196
2210
  const serverUrl = body.serverUrl || null;
2197
2211
 
2198
2212
  const pendingTags = store.getTagsByStatus("new", limit);