sku.html 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  2. <html xmlns="http://www.w3.org/1999/xhtml">
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  5. <title>SKU</title>
  6. <link type="text/css" rel="stylesheet" href="css/shCore.css" />
  7. <link type="text/css" rel="stylesheet" href="css/shCoreDefault.css"/>
  8. <script type="text/javascript" src="js/jquery-1.4.4.min.js"></script>
  9. <script type="text/javascript" src="js/json2.js"></script>
  10. <script type="text/javascript" src="js/shCore.js"></script>
  11. <script type="text/javascript" src="js/shBrushJScript.js"></script>
  12. <script type="text/javascript">SyntaxHighlighter.all();</script>
  13. <style type="text/css">
  14. .bh-sku-selected {color: red;}
  15. </style>
  16. <script type="text/javascript">
  17. var startTime = new Date().getTime();
  18. //销售属性集
  19. var keys = [
  20. ['10'],
  21. ['20','21','22','23','24'],
  22. ['30','31','32','33','34','35','36','37','38'],
  23. ['40']
  24. ];
  25. //后台读取结果集
  26. var data = {
  27. "10;24;31;40": {
  28. price:366,
  29. count:46
  30. },
  31. "10;24;32;40": {
  32. price:406,
  33. count:66
  34. },
  35. "10;24;33;40": {
  36. price:416,
  37. count:77
  38. },
  39. "10;24;34;40": {
  40. price:456,
  41. count:9
  42. },
  43. "10;24;35;40": {
  44. price:371,
  45. count:33
  46. },
  47. "10;24;36;40": {
  48. price:411,
  49. count:79
  50. },
  51. "10;24;37;40": {
  52. price:421,
  53. count:87
  54. },
  55. "10;24;38;40": {
  56. price:461,
  57. count:9
  58. },
  59. "10;24;30;40": {
  60. price:356,
  61. count:59
  62. },
  63. "10;23;31;40": {
  64. price:366,
  65. count:50
  66. },
  67. "10;23;32;40": {
  68. price:406,
  69. count:9
  70. },
  71. "10;23;33;40": {
  72. price:416,
  73. count:90
  74. },
  75. "10;23;34;40": {
  76. price:456,
  77. count:10
  78. },
  79. "10;23;35;40": {
  80. price:371,
  81. count:79
  82. },
  83. "10;23;36;40": {
  84. price:411,
  85. count:90
  86. },
  87. "10;23;37;40": {
  88. price:421,
  89. count:10
  90. },
  91. "10;23;38;40": {
  92. price:461,
  93. count:9
  94. },
  95. "10;23;30;40": {
  96. price:356,
  97. count:46
  98. },
  99. "10;22;31;40": {
  100. price:356,
  101. count:27
  102. },
  103. "10;22;32;40": {
  104. price:396,
  105. count:38
  106. },
  107. "10;22;33;40": {
  108. price:406,
  109. count:42
  110. },
  111. "10;22;34;40": {
  112. price:446,
  113. count:50
  114. },
  115. "10;22;35;40": {
  116. price:361,
  117. count:25
  118. },
  119. "10;22;36;40": {
  120. price:401,
  121. count:40
  122. },
  123. "10;22;37;40": {
  124. price:411,
  125. count:43
  126. },
  127. "10;22;38;40": {
  128. price:451,
  129. count:42
  130. },
  131. "10;21;31;40": {
  132. price:366,
  133. count:79
  134. },
  135. "10;21;32;40": {
  136. price:406,
  137. count:79
  138. },
  139. "10;21;33;40": {
  140. price:416,
  141. count:10
  142. },
  143. "10;21;34;40": {
  144. price:456,
  145. count:10
  146. },
  147. "10;21;35;40": {
  148. price:371,
  149. count:87
  150. },
  151. "10;21;36;40": {
  152. price:411,
  153. count:10
  154. },
  155. "10;21;37;40": {
  156. price:421,
  157. count:10
  158. },
  159. "10;21;38;40": {
  160. price:461,
  161. count:80
  162. },
  163. "10;21;30;40": {
  164. price:356,
  165. count:43
  166. },
  167. "10;20;31;40": {
  168. price:356,
  169. count:46
  170. },
  171. "10;20;32;40": {
  172. price:396,
  173. count:49
  174. },
  175. "10;20;33;40": {
  176. price:406,
  177. count:65
  178. },
  179. "10;20;34;40": {
  180. price:446,
  181. count:10
  182. },
  183. "10;20;35;40": {
  184. price:361,
  185. count:34
  186. },
  187. "10;20;36;40": {
  188. price:401,
  189. count:41
  190. },
  191. "10;20;37;40": {
  192. price:411,
  193. count:36
  194. },
  195. "10;20;38;40": {
  196. price:451,
  197. count:42
  198. },
  199. "10;20;30;40": {
  200. price:346,
  201. count: 3
  202. }
  203. }
  204. //保存最后的组合结果信息
  205. var SKUResult = {};
  206. //获得对象的key
  207. function getObjKeys(obj) {
  208. if (obj !== Object(obj)) throw new TypeError('Invalid object');
  209. var keys = [];
  210. for (var key in obj)
  211. if (Object.prototype.hasOwnProperty.call(obj, key))
  212. keys[keys.length] = key;
  213. return keys;
  214. }
  215. //把组合的key放入结果集SKUResult
  216. function add2SKUResult(combArrItem, sku) {
  217. var key = combArrItem.join(";");
  218. if(SKUResult[key]) {//SKU信息key属性·
  219. SKUResult[key].count += sku.count;
  220. SKUResult[key].prices.push(sku.price);
  221. } else {
  222. SKUResult[key] = {
  223. count : sku.count,
  224. prices : [sku.price]
  225. };
  226. }
  227. }
  228. //初始化得到结果集
  229. function initSKU() {
  230. var i, j, skuKeys = getObjKeys(data);
  231. for(i = 0; i < skuKeys.length; i++) {
  232. var skuKey = skuKeys[i];//一条SKU信息key
  233. var sku = data[skuKey]; //一条SKU信息value
  234. var skuKeyAttrs = skuKey.split(";"); //SKU信息key属性值数组
  235. skuKeyAttrs.sort(function(value1, value2) {
  236. return parseInt(value1) - parseInt(value2);
  237. });
  238. //对每个SKU信息key属性值进行拆分组合
  239. var combArr = combInArray(skuKeyAttrs);
  240. for(j = 0; j < combArr.length; j++) {
  241. add2SKUResult(combArr[j], sku);
  242. }
  243. //结果集接放入SKUResult
  244. SKUResult[skuKeyAttrs.join(";")] = {
  245. count:sku.count,
  246. prices:[sku.price]
  247. }
  248. }
  249. }
  250. /**
  251. * 从数组中生成指定长度的组合
  252. * 方法: 先生成[0,1...]形式的数组, 然后根据0,1从原数组取元素,得到组合数组
  253. */
  254. function combInArray(aData) {
  255. if(!aData || !aData.length) {
  256. return [];
  257. }
  258. var len = aData.length;
  259. var aResult = [];
  260. for(var n = 1; n < len; n++) {
  261. var aaFlags = getCombFlags(len, n);
  262. while(aaFlags.length) {
  263. var aFlag = aaFlags.shift();
  264. var aComb = [];
  265. for(var i = 0; i < len; i++) {
  266. aFlag[i] && aComb.push(aData[i]);
  267. }
  268. aResult.push(aComb);
  269. }
  270. }
  271. return aResult;
  272. }
  273. /**
  274. * 得到从 m 元素中取 n 元素的所有组合
  275. * 结果为[0,1...]形式的数组, 1表示选中,0表示不选
  276. */
  277. function getCombFlags(m, n) {
  278. if(!n || n < 1) {
  279. return [];
  280. }
  281. var aResult = [];
  282. var aFlag = [];
  283. var bNext = true;
  284. var i, j, iCnt1;
  285. for (i = 0; i < m; i++) {
  286. aFlag[i] = i < n ? 1 : 0;
  287. }
  288. aResult.push(aFlag.concat());
  289. while (bNext) {
  290. iCnt1 = 0;
  291. for (i = 0; i < m - 1; i++) {
  292. if (aFlag[i] == 1 && aFlag[i+1] == 0) {
  293. for(j = 0; j < i; j++) {
  294. aFlag[j] = j < iCnt1 ? 1 : 0;
  295. }
  296. aFlag[i] = 0;
  297. aFlag[i+1] = 1;
  298. var aTmp = aFlag.concat();
  299. aResult.push(aTmp);
  300. if(aTmp.slice(-n).join("").indexOf('0') == -1) {
  301. bNext = false;
  302. }
  303. break;
  304. }
  305. aFlag[i] == 1 && iCnt1++;
  306. }
  307. }
  308. return aResult;
  309. }
  310. //初始化用户选择事件
  311. $(function() {
  312. initSKU();
  313. var endTime = new Date().getTime();
  314. $('#init_time').text('init sku time: ' + (endTime - startTime) + " ms");
  315. $('.sku').each(function() {
  316. var self = $(this);
  317. var attr_id = self.attr('attr_id');
  318. if(!SKUResult[attr_id]) {
  319. self.attr('disabled', 'disabled');
  320. }
  321. }).click(function() {
  322. var self = $(this);
  323. //选中自己,兄弟节点取消选中
  324. self.toggleClass('bh-sku-selected').siblings().removeClass('bh-sku-selected');
  325. //已经选择的节点
  326. var selectedObjs = $('.bh-sku-selected');
  327. if(selectedObjs.length) {
  328. //获得组合key价格
  329. var selectedIds = [];
  330. selectedObjs.each(function() {
  331. selectedIds.push($(this).attr('attr_id'));
  332. });
  333. selectedIds.sort(function(value1, value2) {
  334. return parseInt(value1) - parseInt(value2);
  335. });
  336. var len = selectedIds.length;
  337. var prices = SKUResult[selectedIds.join(';')].prices;
  338. var maxPrice = Math.max.apply(Math, prices);
  339. var minPrice = Math.min.apply(Math, prices);
  340. $('#price').text(maxPrice > minPrice ? minPrice + "-" + maxPrice : maxPrice);
  341. //用已选中的节点验证待测试节点 underTestObjs
  342. $(".sku").not(selectedObjs).not(self).each(function() {
  343. var siblingsSelectedObj = $(this).siblings('.bh-sku-selected');
  344. var testAttrIds = [];//从选中节点中去掉选中的兄弟节点
  345. if(siblingsSelectedObj.length) {
  346. var siblingsSelectedObjId = siblingsSelectedObj.attr('attr_id');
  347. for(var i = 0; i < len; i++) {
  348. (selectedIds[i] != siblingsSelectedObjId) && testAttrIds.push(selectedIds[i]);
  349. }
  350. } else {
  351. testAttrIds = selectedIds.concat();
  352. }
  353. testAttrIds = testAttrIds.concat($(this).attr('attr_id'));
  354. testAttrIds.sort(function(value1, value2) {
  355. return parseInt(value1) - parseInt(value2);
  356. });
  357. if(!SKUResult[testAttrIds.join(';')]) {
  358. $(this).attr('disabled', 'disabled').removeClass('bh-sku-selected');
  359. } else {
  360. $(this).removeAttr('disabled');
  361. }
  362. });
  363. } else {
  364. //设置默认价格
  365. $('#price').text('--');
  366. //设置属性状态
  367. $('.sku').each(function() {
  368. SKUResult[$(this).attr('attr_id')] ? $(this).removeAttr('disabled') : $(this).attr('disabled', 'disabled').removeClass('bh-sku-selected');
  369. })
  370. }
  371. });
  372. });
  373. </script>
  374. </head>
  375. <body>
  376. <div>
  377. 属性1:
  378. <input type="button" class="sku" attr_id="10" value="10"/>
  379. </div>
  380. <div>
  381. 属性2:
  382. <input type="button" class="sku" attr_id="20" value="20"/>
  383. <input type="button" class="sku" attr_id="21" value="21"/>
  384. <input type="button" class="sku" attr_id="22" value="22"/>
  385. <input type="button" class="sku" attr_id="23" value="23"/>
  386. <input type="button" class="sku" attr_id="24" value="24"/>
  387. </div>
  388. <div>
  389. 属性3:
  390. <input type="button" class="sku" attr_id="30" value="30"/>
  391. <input type="button" class="sku" attr_id="31" value="31"/>
  392. <input type="button" class="sku" attr_id="32" value="32"/>
  393. <input type="button" class="sku" attr_id="33" value="33"/>
  394. <input type="button" class="sku" attr_id="34" value="34"/>
  395. <input type="button" class="sku" attr_id="35" value="35"/>
  396. <input type="button" class="sku" attr_id="36" value="36"/>
  397. <input type="button" class="sku" attr_id="37" value="37"/>
  398. <input type="button" class="sku" attr_id="38" value="38"/>
  399. </div>
  400. <div>
  401. 属性4:
  402. <input type="button" class="sku" attr_id="40" value="40"/>
  403. </div>
  404. <span id="init_time">init sku time: </span> </br>
  405. <span id="price">--</span> </br>
  406. <pre class="brush: js;">
  407. //销售属性集
  408. var keys = [
  409. ['10'],
  410. ['20','21','22','23','24'],
  411. ['30','31','32','33','34','35','36','37','38'],
  412. ['40']
  413. ];
  414. //后台读取结果集
  415. var data = {
  416. "10;24;31;40": {
  417. price:366,
  418. count:46
  419. },
  420. "10;24;32;40": {
  421. price:406,
  422. count:66
  423. },
  424. "10;24;33;40": {
  425. price:416,
  426. count:77
  427. },
  428. "10;24;34;40": {
  429. price:456,
  430. count:9
  431. },
  432. "10;24;35;40": {
  433. price:371,
  434. count:33
  435. },
  436. "10;24;36;40": {
  437. price:411,
  438. count:79
  439. },
  440. "10;24;37;40": {
  441. price:421,
  442. count:87
  443. },
  444. "10;24;38;40": {
  445. price:461,
  446. count:9
  447. },
  448. "10;24;30;40": {
  449. price:356,
  450. count:59
  451. },
  452. "10;23;31;40": {
  453. price:366,
  454. count:50
  455. },
  456. "10;23;32;40": {
  457. price:406,
  458. count:9
  459. },
  460. "10;23;33;40": {
  461. price:416,
  462. count:90
  463. },
  464. "10;23;34;40": {
  465. price:456,
  466. count:10
  467. },
  468. "10;23;35;40": {
  469. price:371,
  470. count:79
  471. },
  472. "10;23;36;40": {
  473. price:411,
  474. count:90
  475. },
  476. "10;23;37;40": {
  477. price:421,
  478. count:10
  479. },
  480. "10;23;38;40": {
  481. price:461,
  482. count:9
  483. },
  484. "10;23;30;40": {
  485. price:356,
  486. count:46
  487. },
  488. "10;22;31;40": {
  489. price:356,
  490. count:27
  491. },
  492. "10;22;32;40": {
  493. price:396,
  494. count:38
  495. },
  496. "10;22;33;40": {
  497. price:406,
  498. count:42
  499. },
  500. "10;22;34;40": {
  501. price:446,
  502. count:50
  503. },
  504. "10;22;35;40": {
  505. price:361,
  506. count:25
  507. },
  508. "10;22;36;40": {
  509. price:401,
  510. count:40
  511. },
  512. "10;22;37;40": {
  513. price:411,
  514. count:43
  515. },
  516. "10;22;38;40": {
  517. price:451,
  518. count:42
  519. },
  520. "10;21;31;40": {
  521. price:366,
  522. count:79
  523. },
  524. "10;21;32;40": {
  525. price:406,
  526. count:79
  527. },
  528. "10;21;33;40": {
  529. price:416,
  530. count:10
  531. },
  532. "10;21;34;40": {
  533. price:456,
  534. count:10
  535. },
  536. "10;21;35;40": {
  537. price:371,
  538. count:87
  539. },
  540. "10;21;36;40": {
  541. price:411,
  542. count:10
  543. },
  544. "10;21;37;40": {
  545. price:421,
  546. count:10
  547. },
  548. "10;21;38;40": {
  549. price:461,
  550. count:80
  551. },
  552. "10;21;30;40": {
  553. price:356,
  554. count:43
  555. },
  556. "10;20;31;40": {
  557. price:356,
  558. count:46
  559. },
  560. "10;20;32;40": {
  561. price:396,
  562. count:49
  563. },
  564. "10;20;33;40": {
  565. price:406,
  566. count:65
  567. },
  568. "10;20;34;40": {
  569. price:446,
  570. count:10
  571. },
  572. "10;20;35;40": {
  573. price:361,
  574. count:34
  575. },
  576. "10;20;36;40": {
  577. price:401,
  578. count:41
  579. },
  580. "10;20;37;40": {
  581. price:411,
  582. count:36
  583. },
  584. "10;20;38;40": {
  585. price:451,
  586. count:42
  587. },
  588. "10;20;30;40": {
  589. price:346,
  590. count: 3
  591. }
  592. }
  593. </pre>
  594. </span>
  595. </body>
  596. </html>