购买指定商品多选功能测试.html 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>购买指定商品多选功能测试</title>
  7. <style>
  8. body {
  9. font-family: Arial, sans-serif;
  10. max-width: 800px;
  11. margin: 0 auto;
  12. padding: 20px;
  13. background-color: #f5f5f5;
  14. }
  15. .demo-container {
  16. background: white;
  17. padding: 30px;
  18. border-radius: 8px;
  19. box-shadow: 0 2px 10px rgba(0,0,0,0.1);
  20. margin-bottom: 30px;
  21. }
  22. .demo-title {
  23. font-size: 20px;
  24. color: #333;
  25. margin-bottom: 20px;
  26. border-bottom: 2px solid #007bff;
  27. padding-bottom: 10px;
  28. }
  29. .demo-section {
  30. margin-bottom: 25px;
  31. }
  32. .section-title {
  33. font-size: 16px;
  34. color: #555;
  35. margin-bottom: 15px;
  36. font-weight: bold;
  37. }
  38. .form-group {
  39. margin-bottom: 20px;
  40. }
  41. .label {
  42. display: inline-block;
  43. margin-right: 10px;
  44. font-weight: normal;
  45. }
  46. .btn {
  47. display: inline-block;
  48. padding: 8px 16px;
  49. background-color: #28a745;
  50. color: white;
  51. text-decoration: none;
  52. border-radius: 4px;
  53. border: none;
  54. cursor: pointer;
  55. font-size: 14px;
  56. }
  57. .btn:hover {
  58. background-color: #218838;
  59. }
  60. .btn i {
  61. margin-right: 5px;
  62. }
  63. .goods-description-box {
  64. min-height: 60px;
  65. padding: 15px;
  66. border: 1px dashed #ddd;
  67. border-radius: 4px;
  68. background-color: #fafafa;
  69. font-size: 13px;
  70. line-height: 1.5;
  71. color: #666;
  72. margin-top: 15px;
  73. }
  74. .goods-list-container {
  75. border: 1px solid #e0e0e0;
  76. border-radius: 4px;
  77. background: white;
  78. }
  79. .goods-list-item {
  80. display: flex;
  81. align-items: center;
  82. padding: 12px;
  83. border-bottom: 1px solid #f0f0f0;
  84. background: #fafafa;
  85. }
  86. .goods-list-item:last-child {
  87. border-bottom: none;
  88. }
  89. .goods-image {
  90. width: 50px;
  91. height: 50px;
  92. border-radius: 4px;
  93. margin-right: 12px;
  94. flex-shrink: 0;
  95. }
  96. .goods-info {
  97. flex: 1;
  98. margin-right: 12px;
  99. }
  100. .goods-name {
  101. font-size: 14px;
  102. color: #333;
  103. margin-bottom: 4px;
  104. line-height: 1.4;
  105. }
  106. .goods-price {
  107. font-size: 12px;
  108. color: #e74c3c;
  109. font-weight: bold;
  110. margin-bottom: 2px;
  111. }
  112. .goods-meta {
  113. font-size: 11px;
  114. color: #999;
  115. }
  116. .goods-actions {
  117. flex-shrink: 0;
  118. }
  119. .remove-btn {
  120. color: #3c8dbc;
  121. text-decoration: none;
  122. font-size: 12px;
  123. }
  124. .remove-btn:hover {
  125. text-decoration: underline;
  126. }
  127. .label-tag {
  128. display: inline-block;
  129. padding: 2px 6px;
  130. background: #dc3545;
  131. color: white;
  132. font-size: 10px;
  133. border-radius: 3px;
  134. margin-right: 6px;
  135. }
  136. .spec-tag {
  137. display: inline-block;
  138. padding: 2px 6px;
  139. font-size: 10px;
  140. border-radius: 3px;
  141. margin-left: 8px;
  142. }
  143. .spec-single {
  144. background: #17a2b8;
  145. color: white;
  146. }
  147. .spec-multi {
  148. background: #ffc107;
  149. color: #333;
  150. }
  151. .code-block {
  152. background: #f8f9fa;
  153. border: 1px solid #e9ecef;
  154. border-radius: 4px;
  155. padding: 15px;
  156. font-family: 'Courier New', monospace;
  157. font-size: 13px;
  158. line-height: 1.4;
  159. margin-top: 15px;
  160. overflow-x: auto;
  161. }
  162. .highlight {
  163. background: #fff3cd;
  164. padding: 15px;
  165. border: 1px solid #ffeaa7;
  166. border-radius: 4px;
  167. margin-bottom: 20px;
  168. }
  169. .highlight h4 {
  170. margin: 0 0 10px 0;
  171. color: #856404;
  172. }
  173. .steps {
  174. background: #d1ecf1;
  175. padding: 15px;
  176. border: 1px solid #bee5eb;
  177. border-radius: 4px;
  178. margin-bottom: 20px;
  179. }
  180. .steps h4 {
  181. margin: 0 0 10px 0;
  182. color: #0c5460;
  183. }
  184. .steps ol {
  185. margin: 0;
  186. padding-left: 20px;
  187. }
  188. .steps li {
  189. margin-bottom: 5px;
  190. }
  191. </style>
  192. </head>
  193. <body>
  194. <div class="demo-container">
  195. <div class="demo-title">🛒 购买指定商品多选功能测试</div>
  196. <div class="highlight">
  197. <h4>✅ 功能更新说明</h4>
  198. <p>消费抽奖活动中的"购买指定商品"任务现在支持多选模式,用户可以选择多个商品作为参与条件。</p>
  199. </div>
  200. <div class="steps">
  201. <h4>🔧 更新内容</h4>
  202. <ol>
  203. <li>将"添加商品"按钮的调用从 <code>selectGoods()</code> 改为 <code>selectTaskGoods('#selected-goods')</code></li>
  204. <li>修改默认的 <code>selectGoods()</code> 函数为多选模式</li>
  205. <li>确保模板能够正确处理多选商品的表单数据</li>
  206. </ol>
  207. </div>
  208. <div class="demo-section">
  209. <div class="section-title">📝 任务设置界面模拟</div>
  210. <div class="form-group">
  211. <label class="label"><span style="color: red;">*</span> 选择商品:</label>
  212. <label style="margin-right: 20px;">
  213. <input type="radio" name="goods_select_type" value="include" checked> 指定商品参与
  214. </label>
  215. <label>
  216. <input type="radio" name="goods_select_type" value="exclude"> 指定商品不可参与
  217. </label>
  218. </div>
  219. <div style="margin-bottom: 15px;">
  220. <button type="button" class="btn" onclick="simulateAddGoods()">
  221. <i>+</i> 添加商品
  222. </button>
  223. </div>
  224. <div id="selected-goods" class="goods-description-box">
  225. <span style="color: #999;">该商品下单后将自动触发抽奖活动且发放一次抽奖机会,若用户产生维权退款,已发放的奖励自动回收。</span>
  226. </div>
  227. </div>
  228. <div class="demo-section">
  229. <div class="section-title">🎯 多选商品示例</div>
  230. <div id="demo-goods-list" class="goods-list-container">
  231. <!-- 这里将显示模拟的多选商品 -->
  232. </div>
  233. </div>
  234. <div class="demo-section">
  235. <div class="section-title">📊 生成的表单数据</div>
  236. <div class="code-block" id="form-data">
  237. <!-- 这里将显示生成的表单字段 -->
  238. </div>
  239. </div>
  240. </div>
  241. <div class="demo-container">
  242. <div class="demo-title">🔧 技术实现细节</div>
  243. <div class="demo-section">
  244. <div class="section-title">1. 按钮调用修改</div>
  245. <div class="code-block">
  246. &lt;!-- 修改前 --&gt;
  247. &lt;button onclick="selectGoods()"&gt;添加商品&lt;/button&gt;
  248. &lt;!-- 修改后 --&gt;
  249. &lt;button onclick="selectTaskGoods('#selected-goods')"&gt;添加商品&lt;/button&gt;
  250. </div>
  251. </div>
  252. <div class="demo-section">
  253. <div class="section-title">2. JavaScript函数配置</div>
  254. <div class="code-block">
  255. // selectTaskGoods函数配置(多选模式)
  256. selectTaskGoods: function(container) {
  257. Controller.api.selectGoods({
  258. mode: 'multiple', // 多选模式
  259. title: '选择参与商品', // 弹窗标题
  260. container: container || '#task-goods-container',
  261. template: 'goods-list-template'
  262. });
  263. }
  264. </div>
  265. </div>
  266. <div class="demo-section">
  267. <div class="section-title">3. 模板智能字段名处理</div>
  268. <div class="code-block">
  269. &lt;!-- 模板会根据选择数量自动决定字段名 --&gt;
  270. &lt;% if(goods.length === 1) { %&gt;
  271. &lt;input type="hidden" name="goods_id" value="&lt;%=goods[i].id%&gt;" /&gt;
  272. &lt;% } else { %&gt;
  273. &lt;input type="hidden" name="task_goods_ids[]" value="&lt;%=goods[i].id%&gt;" /&gt;
  274. &lt;% } %&gt;
  275. </div>
  276. </div>
  277. </div>
  278. <script>
  279. // 模拟商品数据
  280. const mockGoods = [
  281. {
  282. id: 1,
  283. name: "清凉飞行家易打理4代弹力套西",
  284. image: "https://via.placeholder.com/50x50/007bff/ffffff?text=商品1",
  285. price: "999.00",
  286. goods_sn: "G001",
  287. type_text: "荐",
  288. spec_type: 1,
  289. category: { name: "服装" },
  290. type_name: "普通商品"
  291. },
  292. {
  293. id: 2,
  294. name: "时尚休闲运动鞋",
  295. image: "https://via.placeholder.com/50x50/28a745/ffffff?text=商品2",
  296. price: "299.00",
  297. goods_sn: "G002",
  298. type_text: "热",
  299. spec_type: 0,
  300. category: { name: "鞋类" },
  301. type_name: "普通商品"
  302. },
  303. {
  304. id: 3,
  305. name: "智能手表运动版",
  306. image: "https://via.placeholder.com/50x50/dc3545/ffffff?text=商品3",
  307. price: "1299.00",
  308. goods_sn: "G003",
  309. type_text: "新",
  310. spec_type: 1,
  311. category: { name: "数码" },
  312. type_name: "虚拟商品"
  313. }
  314. ];
  315. let selectedGoods = [];
  316. // 模拟添加商品
  317. function simulateAddGoods() {
  318. // 随机选择1-3个商品
  319. const count = Math.floor(Math.random() * 3) + 1;
  320. selectedGoods = mockGoods.slice(0, count);
  321. // 更新显示
  322. updateGoodsDisplay();
  323. updateFormData();
  324. }
  325. // 更新商品显示
  326. function updateGoodsDisplay() {
  327. const container = document.getElementById('demo-goods-list');
  328. const descBox = document.getElementById('selected-goods');
  329. if (selectedGoods.length === 0) {
  330. container.innerHTML = '<div style="padding: 20px; text-align: center; color: #999;">暂无选择商品</div>';
  331. descBox.innerHTML = '<span style="color: #999;">该商品下单后将自动触发抽奖活动且发放一次抽奖机会,若用户产生维权退款,已发放的奖励自动回收。</span>';
  332. return;
  333. }
  334. let html = '';
  335. selectedGoods.forEach(goods => {
  336. html += `
  337. <div class="goods-list-item" data-id="${goods.id}">
  338. <img src="${goods.image}" class="goods-image" alt="${goods.name}">
  339. <div class="goods-info">
  340. <div class="goods-name">
  341. <span class="label-tag">${goods.type_text}</span>
  342. ${goods.name}
  343. </div>
  344. <div class="goods-price">¥${goods.price}</div>
  345. <div class="goods-meta">
  346. 编码: ${goods.goods_sn} | 分类: ${goods.category.name} | 类型: ${goods.type_name}
  347. <span class="spec-tag ${goods.spec_type == 0 ? 'spec-single' : 'spec-multi'}">
  348. ${goods.spec_type == 0 ? '单规格' : '多规格'}
  349. </span>
  350. </div>
  351. </div>
  352. <div class="goods-actions">
  353. <a href="javascript:;" class="remove-btn" onclick="removeGoods(${goods.id})">删除</a>
  354. </div>
  355. </div>
  356. `;
  357. });
  358. container.innerHTML = html;
  359. // 更新描述框
  360. descBox.innerHTML = `
  361. <div class="goods-list-container">
  362. ${html}
  363. </div>
  364. `;
  365. }
  366. // 删除商品
  367. function removeGoods(id) {
  368. selectedGoods = selectedGoods.filter(goods => goods.id != id);
  369. updateGoodsDisplay();
  370. updateFormData();
  371. }
  372. // 更新表单数据显示
  373. function updateFormData() {
  374. const container = document.getElementById('form-data');
  375. if (selectedGoods.length === 0) {
  376. container.innerHTML = '暂无商品选择,不会生成表单字段';
  377. return;
  378. }
  379. let html = '';
  380. if (selectedGoods.length === 1) {
  381. // 单选模式
  382. html = `&lt;!-- 单选模式:只选择了 1 个商品 --&gt;\n&lt;input type="hidden" name="goods_id" value="${selectedGoods[0].id}" /&gt;`;
  383. } else {
  384. // 多选模式
  385. html = '&lt;!-- 多选模式:选择了 ' + selectedGoods.length + ' 个商品 --&gt;\n';
  386. selectedGoods.forEach(goods => {
  387. html += `&lt;input type="hidden" name="task_goods_ids[]" value="${goods.id}" /&gt;\n`;
  388. });
  389. }
  390. container.innerHTML = html;
  391. }
  392. // 初始化显示
  393. updateGoodsDisplay();
  394. updateFormData();
  395. </script>
  396. </body>
  397. </html>