Commit 2a2a4728 authored by GuanHua's avatar GuanHua

feat: 修改商品收藏列表接口,和店铺APP装修开发

parent e6bb5ed2
......@@ -69,7 +69,7 @@
"@umijs/plugin-esbuild": "^1.0.1",
"@umijs/preset-react": "1.x",
"@umijs/test": "^3.2.0",
"antd": "^4.16.6",
"antd": "^4.15.1",
"antd-img-crop": "^3.12.0",
"babel-plugin-transform-remove-console": "^6.9.4",
"bignumber.js": "^9.0.1",
......@@ -89,10 +89,10 @@
"prettier": "^1.19.1",
"qrcode": "^1.4.4",
"query-string": "^6.13.1",
"react": "^16.12.0",
"react": "^17.0.2",
"react-dnd": "^11.1.3",
"react-dnd-html5-backend": "^11.1.3",
"react-dom": "^16.12.0",
"react-dom": "^17.0.2",
"react-fontawesome": "^1.7.1",
"react-image-crop": "^8.6.4",
"react-reconciler": "^0.25.1",
......@@ -100,7 +100,7 @@
"rgbaster": "^2.1.1",
"sortablejs": "^1.12.0",
"typescript": "^3.9.7",
"umi": "3.2.28",
"umi": "^3.2.28",
"video-react": "^0.14.1",
"yorkie": "^2.0.0"
},
......
<?xml version="1.0" encoding="UTF-8"?>
<svg width="40px" height="40px" viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>图标占位/活动</title>
<defs>
<rect id="path-1" x="0" y="0" width="40" height="40" rx="4"></rect>
</defs>
<g id="图标占位/活动" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="icon">
<mask id="mask-2" fill="white">
<use xlink:href="#path-1"></use>
</mask>
<use id="矩形" fill="#F25767" xlink:href="#path-1"></use>
<rect id="矩形" mask="url(#mask-2)" x="8" y="8" width="24" height="24"></rect>
<path d="M23.4047009,19.2867655 L23.3826623,19.4259721 C23.3772213,19.4585887 23.3715972,19.49113 23.3657912,19.5235947 C23.3355082,19.6929633 23.3001994,19.8605598 23.2601057,20.0258501 L23.2473269,20.0778047 C23.243061,20.094912 23.2387438,20.1119942 23.2343754,20.129051 C23.2183747,20.1915207 23.2017447,20.2534492 23.184443,20.3150287 C23.1774226,20.3400199 23.1701821,20.3653297 23.1628284,20.3905794 C23.1154485,20.5532271 23.063527,20.7129411 23.0071159,20.8699646 C23.0007005,20.8878231 22.9941797,20.9057756 22.9876003,20.9236924 C22.8940908,21.1783206 22.7888062,21.4256127 22.6724876,21.6647992 C22.6597157,21.6910619 22.6468326,21.7171828 22.6338181,21.7432052 C22.6114768,21.7878797 22.5886371,21.8324749 22.5654113,21.8767706 C22.5422864,21.9208673 22.5190153,21.9642362 22.4953745,22.0073081 C22.4778233,22.0392875 22.4599424,22.071325 22.441857,22.1031939 C22.42443,22.1339021 22.4068267,22.1644306 22.3890356,22.1948008 C22.2700814,22.3978369 22.142961,22.5934763 22.0080481,22.7813971 C21.9716976,22.8320351 21.9345667,22.882396 21.896875,22.932177 C21.810883,23.0457368 21.7222373,23.1559674 21.6308232,23.2630427 C21.6193413,23.2764914 21.6078649,23.2898336 21.5963455,23.3031262 C21.5580075,23.3473659 21.519152,23.3911004 21.4798285,23.4342726 C21.4555632,23.4609147 21.430946,23.4875274 21.4061505,23.5139202 C21.3747989,23.5472881 21.3434132,23.5800474 21.3117514,23.6124555 C21.2883758,23.6363815 21.2648921,23.6600739 21.2412603,23.6835735 C20.2212523,24.6981648 18.9240451,25.3535625 17.4983539,25.4782848 C17.3515045,25.7982007 17.3408143,26.0635946 17.4472136,26.2763932 C17.4999816,26.3819292 17.5725641,26.4788495 17.6870063,26.598672 L18.0202201,26.9242244 C18.817406,27.7214103 18.6837478,28.5233589 17.3535534,29.8535534 C17.1582912,30.0488155 16.8417088,30.0488155 16.6464466,29.8535534 C16.4511845,29.6582912 16.4511845,29.3417088 16.6464466,29.1464466 L16.9013664,28.8869261 L17.1075797,28.6656073 C17.5647022,28.1559614 17.5930155,27.9583184 17.401121,27.7266386 L17.3131133,27.6313312 L17.0831664,27.4095551 C16.8390335,27.1716821 16.6790663,26.9761665 16.5527864,26.7236068 C16.3554788,26.3289915 16.3217098,25.9109656 16.4395152,25.4713791 C13.1130662,25.1458317 10.5,21.9250203 10.5,18 C10.5,13.8578644 13.4101491,10.5 17,10.5 C19.4984272,10.5 21.6676247,12.1264613 22.7556877,14.5118014 C22.764971,14.5334531 22.7747717,14.5551712 22.7844824,14.5769511 C22.9032339,14.8423397 23.0080668,15.1168095 23.0985795,15.3992893 C23.1037449,15.4161476 23.1091397,15.4331589 23.1144825,15.4501989 C23.1385658,15.5263529 23.1613709,15.6030344 23.1831194,15.6802658 C23.1892298,15.7025482 23.1954457,15.7249642 23.2015723,15.7474257 C23.2174429,15.8050911 23.2325347,15.8629113 23.247034,15.9210211 C23.2613922,15.9790049 23.2753152,16.0374283 23.2886361,16.096132 C23.3062437,16.1733664 23.3227292,16.2511413 23.3381544,16.3293813 C23.3415362,16.3468412 23.3448955,16.3641577 23.3482027,16.3814967 C23.3616628,16.4517992 23.3742482,16.5226923 23.38596,16.5939421 C23.3918137,16.6297563 23.3975041,16.6657979 23.4029701,16.7019282 C23.413686,16.7726003 23.4235162,16.8436168 23.432476,16.9149584 C23.4375429,16.9554128 23.4423701,16.9961845 23.4469119,17.037059 C23.4556201,17.1153486 23.4632713,17.1940258 23.4698594,17.2730614 C23.4727402,17.3076879 23.4753983,17.3420551 23.4778548,17.3764883 C23.4925122,17.5818013 23.5,17.7898917 23.5,18 C23.5,18.1925677 23.4937102,18.3834404 23.4813549,18.5723594 C23.4796356,18.5986217 23.4778398,18.624301 23.4759322,18.6499435 C23.4707747,18.719304 23.464768,18.78871 23.457947,18.8578307 C23.4542386,18.8954039 23.4503043,18.932761 23.4461329,18.9700323 C23.4393774,19.0304087 23.4319663,19.09081 23.4239355,19.1509754 C23.4212832,19.1708411 23.418599,19.1904281 23.4158492,19.2099898 L23.4047009,19.2867655 L23.4047009,19.2867655 Z M24.5,13.5 C27.2614237,13.5 29.5,16.1862915 29.5,19.5 C29.5,22.4072781 27.7768764,24.8316077 25.4893142,25.3825665 C25.3688793,25.7048633 25.3464654,25.9680768 25.4085904,26.173341 C25.4292811,26.2417042 25.4561208,26.3025437 25.4978922,26.3764089 L25.6512559,26.62492 C26.0106899,27.2187142 25.9548117,27.772588 25.3577686,28.7589184 C25.2147719,28.9951525 24.9073446,29.0707364 24.6711105,28.9277397 C24.4348764,28.7847431 24.3592925,28.4773158 24.5022891,28.2410816 L24.6584513,27.9740291 C24.902047,27.5372963 24.9179307,27.3737069 24.8240216,27.1927558 L24.6955381,26.9830816 C24.5830803,26.8020621 24.5085097,26.6514933 24.4514673,26.4630227 C24.378669,26.2224933 24.358064,25.9684865 24.3872022,25.7010275 L24.418,25.497 L24.2518005,25.4927365 C23.3473038,25.4396775 22.5059532,25.0982038 21.7902615,24.5433307 C23.4509087,22.9799767 24.5,20.6210341 24.5,18 C24.5,16.4092906 24.1135889,14.9151172 23.4387103,13.6365908 C23.7805378,13.5467475 24.1357195,13.5 24.5,13.5 Z" id="形状结合" fill="#FFFFFF" mask="url(#mask-2)"></path>
</g>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>icon/特价促销</title>
<defs>
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
<stop stop-color="#FF3457" offset="0%"></stop>
<stop stop-color="#FF738C" offset="100%"></stop>
</linearGradient>
</defs>
<g id="icon/特价促销" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="图标">
<circle id="椭圆形" fill="url(#linearGradient-1)" cx="8" cy="8" r="8"></circle>
<g id="线稿" transform="translate(2.000000, 2.000000)">
<polygon id="矩形" points="0 0 12 0 12 12 0 12"></polygon>
<path d="M7.16187137,1.48155295 L6.78038571,5.05261401 L8.1203957,5.12836168 C8.34131457,5.14084972 8.51101898,5.34414215 8.49944111,5.58242805 C8.49576169,5.65815486 8.47366869,5.73150334 8.43538217,5.79510297 L5.42055075,10.8031889 C5.30007641,11.0033148 5.05200269,11.0602075 4.86646259,10.9302623 C4.73889395,10.8409182 4.66924665,10.68135 4.68668356,10.5183726 L5.09649538,6.68798677 L3.87943687,6.61863779 C3.65852287,6.60604993 3.48889743,6.40268082 3.50056785,6.16440018 C3.50427465,6.0887166 3.52637394,6.01541629 3.5646474,5.95185712 L6.42802566,1.19676221 C6.54852503,0.996653842 6.79660587,0.939797204 6.98212971,1.06976935 C7.10964988,1.15910596 7.17927701,1.31861996 7.16187137,1.48155295 Z" id="路径" fill="#FFFFFF" fill-rule="nonzero"></path>
</g>
</g>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>icon/多件促销</title>
<defs>
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
<stop stop-color="#FD8525" offset="0%"></stop>
<stop stop-color="#FEB85F" offset="100%"></stop>
</linearGradient>
</defs>
<g id="icon/多件促销" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="图标" fill="url(#linearGradient-1)">
<circle id="椭圆形" cx="8" cy="8" r="8"></circle>
</g>
<path d="M8,3 C9.65685425,3 11,4.34314575 11,6 L12.5,6 C12.7761424,6 13,6.22385763 13,6.5 L13,7.5 C13,7.77614237 12.7761424,8 12.5,8 L12,8 L11.5450248,12.5497519 C11.5194647,12.8053528 11.3043819,13 11.0475062,13 L4.95249378,13 C4.69561806,13 4.48053528,12.8053528 4.45497519,12.5497519 L4,8 L3.5,8 C3.22385763,8 3,7.77614237 3,7.5 L3,6.5 C3,6.22385763 3.22385763,6 3.5,6 L5,6 C5,4.34314575 6.34314575,3 8,3 Z M7,9 C6.72385763,9 6.5,9.22385763 6.5,9.5 L6.5,9.5 L6.5,10.5 L6.50805567,10.5898756 C6.55039163,10.8231248 6.75454011,11 7,11 C7.27614237,11 7.5,10.7761424 7.5,10.5 L7.5,10.5 L7.5,9.5 L7.49194433,9.41012437 C7.44960837,9.17687516 7.24545989,9 7,9 Z M9,9 C8.72385763,9 8.5,9.22385763 8.5,9.5 L8.5,9.5 L8.5,10.5 L8.50805567,10.5898756 C8.55039163,10.8231248 8.75454011,11 9,11 C9.27614237,11 9.5,10.7761424 9.5,10.5 L9.5,10.5 L9.5,9.5 L9.49194433,9.41012437 C9.44960837,9.17687516 9.24545989,9 9,9 Z M8,4 C6.8954305,4 6,4.8954305 6,6 L10,6 C10,4.8954305 9.1045695,4 8,4 Z" id="形状结合" fill="#FFFFFF"></path>
<g id="编组" transform="translate(6.500000, 9.000000)"></g>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>icon/组合促销</title>
<defs>
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
<stop stop-color="#8469FD" offset="0%"></stop>
<stop stop-color="#A4A3FF" offset="100%"></stop>
</linearGradient>
</defs>
<g id="icon/组合促销" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<circle id="椭圆形" fill="url(#linearGradient-1)" cx="8" cy="8" r="8"></circle>
<path d="M7.99997376,11.2838941 L4.79386339,12.9469085 C4.57073954,13.0626432 4.29213586,12.9828139 4.17158464,12.7686048 C4.12188435,12.6802917 4.1050647,12.5783395 4.12390648,12.4796042 L4.78060699,9.03834051 L2.1424213,6.62487631 C1.95882122,6.45691534 1.95180976,6.17786548 2.12676077,6.00160101 C2.19888875,5.92893152 2.29468876,5.88206925 2.39832207,5.86876198 L6.01029567,5.40495852 L7.58591762,2.25034118 C7.69557037,2.03080091 7.96984074,1.93816789 8.19851763,2.04343955 C8.29279545,2.08684045 8.36882278,2.15983016 8.41402989,2.25034118 L9.98965184,5.40495852 L13.6016254,5.86876198 C13.8529947,5.9010396 14.0295145,6.12283911 13.9958936,6.36416505 C13.9820325,6.46365776 13.93322,6.55563016 13.8575262,6.62487631 L11.2193405,9.03834051 L11.876041,12.4796042 C11.921743,12.7190931 11.7565679,12.9488057 11.5071121,12.9926817 C11.4811689,12.9972448 11.4550125,12.9996293 11.4289247,12.999878 C11.3515948,13.0006153 11.2748679,12.9825867 11.2060841,12.9469085 L7.99997376,11.2838941 Z" id="🎨-Icon-Сolor" fill="#FFFFFF"></path>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>icon/秒杀</title>
<defs>
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
<stop stop-color="#FF3457" offset="0%"></stop>
<stop stop-color="#FF738C" offset="100%"></stop>
</linearGradient>
<path d="M5.55565,11.50005 C5.49865,11.50005 5.44115,11.49005 5.38465,11.46955 C5.16865,11.39105 5.03365,11.17505 5.05865,10.94655 L5.44265,7.40005 L2.50015,7.40005 C2.31565,7.40005 2.14615,7.29855 2.05915,7.13555 C1.97215,6.97255 1.98215,6.77555 2.08465,6.62205 L6.02865,0.72205 C6.15665,0.53055 6.39865,0.45105 6.61515,0.53055 C6.83165,0.60905 6.96615,0.82505 6.94115,1.05355 L6.55715,4.60005 L9.50015,4.60005 C9.68465,4.60005 9.85415,4.70155 9.94115,4.86455 C10.02765,5.02755 10.01815,5.22455 9.91565,5.37805 L5.97115,11.27805 C5.87665,11.42005 5.71865,11.50005 5.55565,11.50005" id="path-2"></path>
</defs>
<g id="icon/秒杀" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="图标" fill="url(#linearGradient-1)">
<circle id="椭圆形" cx="8" cy="8" r="8"></circle>
</g>
<g id="图标" transform="translate(2.000000, 2.000000)">
<rect id="矩形" x="0" y="0" width="12" height="12"></rect>
<mask id="mask-3" fill="white">
<use xlink:href="#path-2"></use>
</mask>
<use id="🎨-Icon-Сolor" fill="#FFFFFF" xlink:href="#path-2"></use>
</g>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>icon/拼团</title>
<defs>
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
<stop stop-color="#FD8525" offset="0%"></stop>
<stop stop-color="#FEB85F" offset="100%"></stop>
</linearGradient>
</defs>
<g id="icon/拼团" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="图标">
<circle id="椭圆形" fill="url(#linearGradient-1)" cx="8" cy="8" r="8"></circle>
<g transform="translate(2.000000, 2.000000)">
<polygon id="矩形" points="0 0 12 0 12 12 0 12"></polygon>
<path d="M5,2 C6.1045695,2 7,2.8954305 7,4 C7,4.6907363 6.64983692,5.29968763 6.11733951,5.65902526 C7.7410029,6.12949164 8.93885181,7.60241828 8.99772946,9.36394106 L9,9.5 C9,9.77640155 8.77593227,10.0004775 8.49953072,10.0004775 L1.50046928,10.0004775 C1.24381069,10.0004775 1.03227668,9.80726806 1.00336702,9.55836529 L1,9.5 C1,7.67861206 2.21736471,6.14155488 3.88282755,5.65809504 C3.35016308,5.29968763 3,4.6907363 3,4 C3,2.8954305 3.8954305,2 5,2 Z M7.5,2 C8.46649831,2 9.25,2.78350169 9.25,3.75 C9.25,4.3544968 8.94350333,4.88740748 8.4774349,5.20180712 C9.89433982,5.6121576 10.9405209,6.89479272 10.9975487,8.43028186 L11,8.5625 C11,8.78575325 10.8329392,8.96998737 10.6170099,8.99701005 L10.5620075,9.00042083 L9.72402799,9.00028618 C9.60775454,7.88816432 9.10773693,6.8902225 8.35875721,6.14124279 C8.06619935,5.84868493 7.73565609,5.59411246 7.37516005,5.38555801 C7.61345822,4.979668 7.75,4.50577952 7.75,4 C7.75,3.28807044 7.47946893,2.6393268 7.03559984,2.15096211 L6.97014999,2.08164651 C7.13729006,2.02861241 7.31530364,2 7.5,2 Z" id="形状" fill="#FFFFFF"></path>
</g>
</g>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>icon/满额换购</title>
<defs>
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
<stop stop-color="#2179FD" offset="0%"></stop>
<stop stop-color="#3BADEC" offset="100%"></stop>
</linearGradient>
</defs>
<g id="icon/满额换购" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<circle id="椭圆形" fill="url(#linearGradient-1)" cx="8" cy="8" r="8"></circle>
<g id="编组" transform="translate(3.000000, 3.171573)" fill="#FFFFFF">
<path d="M9.70710678,7.53553391 L6.87867966,10.363961 L6.79145884,10.4416674 C6.39894119,10.7524929 5.82709579,10.7265907 5.46446609,10.363961 C5.10398213,10.0034771 5.0762526,9.43624601 5.38127749,9.04395481 L5.46446609,8.94974747 L6.585,7.82842712 L1,7.82842712 C0.44771525,7.82842712 0,7.38071187 0,6.82842712 C0,6.31559129 0.38604019,5.89291996 0.883378875,5.83515486 L1,5.82842712 L9.02462975,5.82872859 C9.04509957,5.82922977 9.06555694,5.83035586 9.08597078,5.83210685 L9.08,5.832 L9.14392965,5.83870811 L9.14392965,5.83870811 C9.16411407,5.84170021 9.18410113,5.84521405 9.20398692,5.84933782 L9.231441,5.8553551 L9.231441,5.8553551 L9.25877513,5.86223287 C9.27673458,5.86710654 9.29474284,5.87245528 9.31261846,5.87832126 C9.33593075,5.88593188 9.35876255,5.89439227 9.38118435,5.90364435 C9.39220295,5.90818161 9.4032072,5.9129454 9.41414034,5.91791628 C9.43738348,5.92853685 9.46009053,5.93995913 9.4822828,5.95219998 C9.4955854,5.95943724 9.50912518,5.96731026 9.52251336,5.97552755 C9.54682575,5.99056115 9.57037,6.00644359 9.59317379,6.02327164 L9.6514232,6.06965622 L9.6514232,6.06965622 L9.61675008,6.04121309 C9.68018175,6.09097884 9.73744829,6.14824537 9.78721404,6.21167704 L9.80366542,6.23312051 L9.80366542,6.23312051 C9.82150991,6.25729643 9.8382813,6.28215217 9.85393257,6.30776694 C9.86139308,6.31981402 9.86850117,6.33203268 9.87532883,6.34436503 C9.88620608,6.36413318 9.89662336,6.38453573 9.90634622,6.40532798 L9.92877451,6.4570911 L9.92877451,6.4570911 C9.93668426,6.47684792 9.94387751,6.49662945 9.95045332,6.51669071 L9.96415486,6.56243416 L9.96415486,6.56243416 C9.97016637,6.58399065 9.9753602,6.60568105 9.97983485,6.62763303 C9.98329783,6.64505186 9.98637192,6.66247811 9.9889822,6.67996026 C9.9920328,6.69990246 9.99446658,6.72054108 9.99626233,6.74136211 C9.9978436,6.76016164 9.99890526,6.77816076 9.99948292,6.79617251 C9.99981828,6.80621634 10,6.81730051 10,6.82842712 L9.99638403,6.91365135 L9.99638403,6.91365135 L9.98898066,6.97738834 L9.98898066,6.97738834 C9.98637192,6.99437613 9.98329783,7.01180239 9.97975993,7.02915289 C9.9753602,7.0511732 9.97016637,7.0728636 9.96427903,7.09426674 L9.95026191,7.14056965 L9.95026191,7.14056965 C9.94387751,7.1602248 9.93668426,7.18000633 9.92889604,7.19948565 L9.90632664,7.25164867 L9.90632664,7.25164867 C9.89662336,7.27231852 9.88620608,7.29272107 9.87512423,7.31270408 C9.86850117,7.32482157 9.86139308,7.33704023 9.85400455,7.34913588 C9.8382813,7.37470208 9.82150991,7.39955782 9.80368649,7.42358643 L9.773,7.461 L9.768,7.466 L9.767,7.468 L9.773,7.461 L9.78,7.453 L9.767,7.468 L9.763,7.472 L9.75779461,7.48097475 L9.75779461,7.48097475 L9.70710678,7.53553391 Z M0.292893219,3.12132034 L3.12132034,0.292893219 L3.20854116,0.215186855 C3.60105881,-0.0956386021 4.17290421,-0.0697364807 4.53553391,0.292893219 C4.89601787,0.65337718 4.9237474,1.22060824 4.61872251,1.61289944 L4.53553391,1.70710678 L3.414,2.828 L9,2.82842712 C9.55228475,2.82842712 10,3.27614237 10,3.82842712 C10,4.34126296 9.61395981,4.76393429 9.11662113,4.82169939 L9,4.82842712 L1,4.82842712 C0.949379716,4.82842712 0.899637905,4.82466594 0.851038784,4.81740778 C0.83626037,4.81511998 0.821607146,4.81258973 0.807005356,4.80973182 C0.779008717,4.80434874 0.751319073,4.79767803 0.724104404,4.78988305 C0.716262607,4.78756693 0.707927,4.7850697 0.699618714,4.78246147 C0.673251598,4.77421985 0.647804142,4.76503306 0.622859366,4.75486809 C0.607705462,4.74870152 0.592676686,4.7421553 0.577783475,4.7352223 C0.559865704,4.72683073 0.542136404,4.7179062 0.524718555,4.70847966 C0.508600465,4.69985335 0.492422491,4.69051971 0.4764607,4.68069615 C0.459227937,4.66998327 0.442368213,4.65888347 0.425874415,4.64729798 L0.357552198,4.59482397 L0.357552198,4.59482397 L0.377441931,4.61104979 C0.317927654,4.56364474 0.263942355,4.50959363 0.216609189,4.45001961 L0.186463402,4.41020674 L0.186463402,4.41020674 C0.172267065,4.39028046 0.158426988,4.36937758 0.145370459,4.34794493 C0.138911202,4.33750572 0.132717312,4.32689543 0.126735197,4.31619858 C0.115033742,4.2951384 0.103995121,4.27363077 0.0937298872,4.25168899 C0.0849725826,4.23302219 0.0768052939,4.21399922 0.0692553107,4.19478975 C0.0628806649,4.17866357 0.0568101517,4.16197984 0.0511777005,4.14509573 C0.0451409909,4.12676606 0.0397254918,4.10878197 0.0348267799,4.09068716 C0.0293235224,4.07073728 0.0243890427,4.04997104 0.0201130486,4.02896543 C0.016812336,4.01232446 0.013852717,3.99563564 0.0113186144,3.97889485 C0.00816835491,3.95847527 0.00572722774,3.93806244 0.00391025009,3.91747037 C0.00191464755,3.89464281 0.000658894511,3.87155088 0.000199149206,3.84844605 L0.000179732159,3.80940905 L0.001,3.774 L0.001,3.809 L0.003,3.746 L0.0109109995,3.68019319 L0.0109109995,3.68019319 C0.01364052,3.66230093 0.0168901096,3.64394858 0.0206541794,3.62568113 L0.0343478124,3.56763146 L0.0343478124,3.56763146 C0.0392765631,3.5495663 0.0448946183,3.53082951 0.0510732771,3.51223817 C0.0568101517,3.49487441 0.0628806649,3.47819068 0.0693757535,3.4617208 L0.0937571768,3.4050261 L0.0937571768,3.4050261 C0.103995121,3.38322348 0.115033742,3.36171585 0.126810667,3.34067745 C0.132717312,3.32995882 0.138911202,3.31934853 0.145316865,3.30883092 C0.160444524,3.28416483 0.176562998,3.26012649 0.193664647,3.23685551 L0.22,3.202 L0.221,3.201 L0.292893219,3.12132034 L0.292893219,3.12132034 Z" id="形状结合"></path>
</g>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>icon/买商品换购</title>
<defs>
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
<stop stop-color="#2179FD" offset="0%"></stop>
<stop stop-color="#3BADEC" offset="100%"></stop>
</linearGradient>
</defs>
<g id="icon/买商品换购" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<circle id="椭圆形" fill="url(#linearGradient-1)" cx="8" cy="8" r="8"></circle>
<rect id="矩形" x="2" y="2" width="12" height="12"></rect>
<path d="M8,3 C9.1045695,3 10,3.8954305 10,5 L11.2954116,5 C11.691459,5 12.0192463,5.3079401 12.043951,5.70321629 L12.450201,12.2032163 C12.4760389,12.6166232 12.1618522,12.9727015 11.7484453,12.9985394 L11.7016616,13 L4.29833842,13 C3.88412485,13 3.54833842,12.6642136 3.54833842,12.25 L3.54979898,12.2032163 L3.95604898,5.70321629 C3.98075374,5.3079401 4.30854095,5 4.70458842,5 L6,5 L6,5 C6,3.8954305 6.8954305,3 8,3 Z M8,4 C7.44771525,4 7,4.44771525 7,5 L9,5 L9,5 C9,4.44771525 8.55228475,4 8,4 Z" id="形状结合" fill="#FFFFFF"></path>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>icon/预售</title>
<defs>
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
<stop stop-color="#FF3457" offset="0%"></stop>
<stop stop-color="#FF738C" offset="100%"></stop>
</linearGradient>
</defs>
<g id="icon/预售" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="图标" fill="url(#linearGradient-1)">
<circle id="椭圆形" cx="8" cy="8" r="8"></circle>
</g>
<g id="图标" transform="translate(2.000000, 2.000000)">
<polygon id="矩形" points="0 0 12 0 12 12 0 12"></polygon>
<path d="M5.34876958,1.07374461 L5.52681674,1.23723101 L5.52681674,1.23723101 L5.86559116,1.55620485 C7.22904041,2.86304319 7.99110434,3.89214005 8.15178296,4.64349542 C8.27944815,4.39740307 8.50717166,4.13124144 8.8349535,3.84501053 L8.96256283,3.73673437 C9.01191131,3.69599514 9.08382271,3.70437747 9.12318145,3.75545684 C9.13860209,3.77546959 9.1473353,3.80011973 9.14807009,3.82570687 L9.15307574,3.96976741 L9.16762519,4.234429 C9.19984583,4.69096919 9.26257299,4.98980944 9.35580666,5.13094976 L9.44348378,5.25650883 L9.58136852,5.44830425 L9.65566514,5.56224564 C9.82665329,5.84111172 9.97600469,6.2227094 9.99783241,6.95298263 L10,7.15634107 L9.99897938,7.28374898 C9.98994242,7.67820549 9.94272957,7.98243334 9.86490439,8.21634418 C9.55662284,9.40622936 8.74850329,10.3853303 7.68754257,10.8969075 C7.70950833,10.6393154 7.71469391,10.3683504 7.71469391,10.0991213 C7.71469391,9.75342398 7.63943868,9.37889995 7.51122607,9.00759435 L7.47866472,8.91643038 C7.43858855,8.8078238 7.39412031,8.69971916 7.34582135,8.59292322 L7.30418467,8.50474498 C7.23850206,8.36619935 7.16651271,8.23027053 7.08947538,8.09875891 L6.94858787,7.87133354 L6.87657987,7.76500637 L6.76946898,7.61656069 L6.66641109,7.48432 L6.56073518,7.358689 L6.50165176,7.29259574 L6.3702505,7.15605279 L6.2991751,7.0879786 L6.21108092,7.00919624 L6.14417532,6.9534798 C6.09631302,6.91489485 6.04829938,6.87892824 6.00028573,6.84579643 C5.96362448,6.9406643 5.92528328,7.03299095 5.88562857,7.12302004 L5.78550659,7.34024877 C5.72684311,7.46220509 5.66635056,7.57964565 5.60487487,7.69361288 L5.48184308,7.91548308 L5.39758964,8.06178546 L5.04745233,8.65266785 C4.71339018,9.22312898 4.44915453,9.74669024 4.44915453,10.3526271 C4.44915453,10.5784455 4.48338524,10.7959885 4.54676879,11 L4.443194,10.95676 C3.03900476,10.3420063 2.04451546,8.92095678 2.0014554,7.25434187 L2,7.14155323 C2,7.03000262 2.00135983,6.92370488 2.00394683,6.82241298 L2.01525665,6.53330775 C2.03734563,6.12143507 2.08159821,5.80592811 2.13592516,5.56427565 L2.17350295,5.41386837 L2.21326975,5.28386169 L2.23372527,5.22604537 L2.27528306,5.1238604 L2.31703985,5.03837047 L2.35819964,4.96809336 L2.39796644,4.91154683 L2.43554423,4.86724868 L2.47013703,4.83371668 L2.50094884,4.8094686 L2.53833592,4.78726149 C2.55734016,4.78051481 2.57824335,4.78927863 2.58735453,4.8078129 L2.68045541,4.99720183 L2.83581383,5.29691636 L2.95012861,5.51216529 L2.982674,5.5829063 L3.02873898,5.70590383 L3.10411952,5.95743508 L3.14293878,5.9579345 L3.14870692,5.82177444 C3.19054187,5.31569689 3.45480145,4.75952969 3.77279863,4.19011802 L3.95056708,3.8784378 L4.27002835,3.32890368 L4.40209033,3.09575898 L4.52821751,2.86374397 C4.72265711,2.49611185 4.83554992,2.03410746 4.86689592,1.47773078 L4.87429704,1.28877595 C4.87803778,1.12546426 5.00897432,0.996212817 5.16675198,1 C5.21711493,1.00132071 5.26595526,1.01629937 5.30850007,1.04308923 L5.34876958,1.07374461 Z" id="路径" fill="#FFFFFF"></path>
</g>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>icon/试用</title>
<defs>
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
<stop stop-color="#27C7A4" offset="0%"></stop>
<stop stop-color="#5DEBCC" offset="100%"></stop>
</linearGradient>
</defs>
<g id="icon/试用" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<circle id="椭圆形" fill="url(#linearGradient-1)" cx="8" cy="8" r="8"></circle>
<g id="图标" transform="translate(2.000000, 2.000000)">
<rect id="矩形" x="0" y="0" width="12" height="12"></rect>
<path d="M6.43592865,1.68004869 C6.50327529,1.72815343 6.56219536,1.7870735 6.6103001,1.85442014 L8.03964542,3.85550359 C8.28040216,4.19256303 8.74881473,4.27063179 9.08587417,4.02987505 L9.11846681,4.00522655 L9.78147871,3.47481703 C10.1049252,3.21605987 10.5768944,3.2685009 10.8356516,3.59194735 C10.9420394,3.72493214 11,3.89016501 11,4.06046864 L11,9.75 C11,10.1642136 10.6642136,10.5 10.25,10.5 L1.75,10.5 C1.33578644,10.5 1,10.1642136 1,9.75 L1,4.06046864 C1,3.64625507 1.33578644,3.31046864 1.75,3.31046864 C1.92030362,3.31046864 2.0855365,3.3684292 2.21852129,3.47481703 L2.88153319,4.00522655 C3.20497964,4.26398371 3.67694892,4.21154268 3.93570608,3.88809623 L3.96035458,3.85550359 L5.3896999,1.85442014 C5.63045664,1.5173607 6.09886921,1.43929194 6.43592865,1.68004869 Z M6,6 C5.44771525,6 5,6.44771525 5,7 C5,7.55228475 5.44771525,8 6,8 C6.55228475,8 7,7.55228475 7,7 C7,6.44771525 6.55228475,6 6,6 Z" id="形状结合" fill="#FFFFFF"></path>
</g>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>icon/套餐</title>
<defs>
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
<stop stop-color="#E0B26C" offset="0%"></stop>
<stop stop-color="#F6CF85" offset="100%"></stop>
</linearGradient>
</defs>
<g id="icon/套餐" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<circle id="椭圆形" fill="url(#linearGradient-1)" cx="8" cy="8" r="8"></circle>
<g id="图标" transform="translate(2.000000, 2.000000)">
<rect id="矩形" x="0" y="0" width="12" height="12"></rect>
</g>
<g id="图标" transform="translate(2.000000, 2.000000)">
<rect id="矩形" x="0" y="0" width="12" height="12"></rect>
<path d="M4,1.30901699 C4.07762255,1.30901699 4.15417908,1.32708954 4.2236068,1.3618034 L6,2.25 L7.7763932,1.3618034 C8.02338245,1.23830877 8.32371897,1.33842095 8.4472136,1.5854102 C8.48192745,1.65483791 8.5,1.73139445 8.5,1.80901699 L8.5,3 L10.25,3 C10.6642136,3 11,3.33578644 11,3.75 L11,5.25 C11,5.66421356 10.6642136,6 10.25,6 L10,5.99990747 L10,10.25 C10,10.6642136 9.66421356,11 9.25,11 L2.75,11 C2.33578644,11 2,10.6642136 2,10.25 L2,5.99990747 L1.75,6 C1.33578644,6 1,5.66421356 1,5.25 L1,3.75 C1,3.33578644 1.33578644,3 1.75,3 L3.5,3 L3.5,1.80901699 C3.5,1.53287462 3.72385763,1.30901699 4,1.30901699 Z M6,6.5 C5.72385763,6.5 5.5,6.72385763 5.5,7 L5.5,7 L5.5,9 L5.50805567,9.08987563 C5.55039163,9.32312484 5.75454011,9.5 6,9.5 C6.27614237,9.5 6.5,9.27614237 6.5,9 L6.5,9 L6.5,7 L6.49194433,6.91012437 C6.44960837,6.67687516 6.24545989,6.5 6,6.5 Z" id="形状结合" fill="#FFFFFF"></path>
</g>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>icon/砍价</title>
<defs>
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
<stop stop-color="#FF3457" offset="0%"></stop>
<stop stop-color="#FF738C" offset="100%"></stop>
</linearGradient>
</defs>
<g id="icon/砍价" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="图标">
<circle id="椭圆形" fill="url(#linearGradient-1)" cx="8" cy="8" r="8"></circle>
<rect id="矩形" x="2" y="2" width="12" height="12"></rect>
</g>
<path d="M6,3.5 C6,3.22385763 6.22385763,3 6.5,3 L9.5,3 C9.77614237,3 10,3.22385763 10,3.5 L10,8 L11.7928932,8 C11.9255015,8 12.0526784,8.05267842 12.1464466,8.14644661 C12.3417088,8.34170876 12.3417088,8.65829124 12.1464466,8.85355339 L12.1464466,8.85355339 L8.35355339,12.6464466 C8.15829124,12.8417088 7.84170876,12.8417088 7.64644661,12.6464466 L7.64644661,12.6464466 L3.85355339,8.85355339 C3.7597852,8.7597852 3.70710678,8.63260824 3.70710678,8.5 C3.70710678,8.22385763 3.93096441,8 4.20710678,8 L4.20710678,8 L6,8 L6,3.5 Z" id="形状结合" fill="#FFFFFF"></path>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>icon/直降促销</title>
<defs>
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
<stop stop-color="#FF3457" offset="0%"></stop>
<stop stop-color="#FF738C" offset="100%"></stop>
</linearGradient>
</defs>
<g id="icon/直降促销" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="图标" fill="url(#linearGradient-1)">
<circle id="椭圆形" cx="8" cy="8" r="8"></circle>
</g>
<g id="线稿" transform="translate(8.000000, 8.000000) rotate(-45.000000) translate(-8.000000, -8.000000) translate(2.000000, 2.000000)">
<rect id="矩形" x="0" y="0" width="12" height="12"></rect>
</g>
<path d="M2.18289322,5.48289322 C2.54552292,5.12026352 3.11736831,5.0943614 3.50988597,5.40518685 L3.59710678,5.48289322 L5.71842712,7.60421356 L7.13264069,6.19 L7.13264069,6.19 C7.52316498,5.79947571 8.15632996,5.79947571 8.54685425,6.19 L11.0952671,8.73982705 L12.1495397,7.68563517 C12.3448019,7.49037303 12.6613844,7.49037303 12.8566465,7.68563517 C12.9503919,7.77938059 13.0030685,7.9065196 13.0030931,8.03909564 L13.0037371,11.5032671 C13.0039477,11.748727 12.8271289,11.9529083 12.5938896,11.9952876 L12.5038299,12.0031742 L9.03965839,12.0025304 C8.76351602,12.002479 8.5397,11.7785798 8.53975132,11.5024374 C8.53977596,11.3698614 8.5924525,11.2427224 8.68619792,11.148977 L9.68105353,10.1540406 L7.83904036,8.31202745 L6.42553391,9.72553391 C6.06290421,10.0881636 5.49105881,10.1140657 5.09854116,9.80324027 L5.01132034,9.72553391 L2.18289322,6.89710678 C1.79236893,6.50658249 1.79236893,5.87341751 2.18289322,5.48289322 Z" id="路径" fill="#FFFFFF"></path>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>icon/满量减</title>
<defs>
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
<stop stop-color="#8469FD" offset="0%"></stop>
<stop stop-color="#A4A3FF" offset="100%"></stop>
</linearGradient>
</defs>
<g id="icon/满量减" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<circle id="椭圆形" fill="url(#linearGradient-1)" cx="8" cy="8" r="8"></circle>
<rect id="矩形" x="2" y="2" width="12" height="12"></rect>
<path d="M8,3 C9.1045695,3 10,3.8954305 10,5 L11.2954116,5 C11.691459,5 12.0192463,5.3079401 12.043951,5.70321629 L12.450201,12.2032163 C12.4760389,12.6166232 12.1618522,12.9727015 11.7484453,12.9985394 L11.7016616,13 L4.29833842,13 C3.88412485,13 3.54833842,12.6642136 3.54833842,12.25 L3.54979898,12.2032163 L3.95604898,5.70321629 C3.98075374,5.3079401 4.30854095,5 4.70458842,5 L6,5 C6,3.8954305 6.8954305,3 8,3 Z M9.5,8 L6.5,8 L6.41012437,8.00805567 C6.17687516,8.05039163 6,8.25454011 6,8.5 C6,8.77614237 6.22385763,9 6.5,9 L6.5,9 L9.5,9 L9.58987563,8.99194433 C9.82312484,8.94960837 10,8.74545989 10,8.5 C10,8.22385763 9.77614237,8 9.5,8 L9.5,8 Z M8,4 C7.44771525,4 7,4.44771525 7,5 L9,5 C9,4.44771525 8.55228475,4 8,4 Z" id="形状结合" fill="#FFFFFF"></path>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>icon/折扣促销</title>
<defs>
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
<stop stop-color="#FD8525" offset="0%"></stop>
<stop stop-color="#FEB85F" offset="100%"></stop>
</linearGradient>
</defs>
<g id="icon/折扣促销" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="图标" fill="url(#linearGradient-1)">
<circle id="椭圆形" cx="8" cy="8" r="8"></circle>
</g>
<g id="图标" transform="translate(2.000000, 2.000000)">
<polygon id="矩形" points="0 0 12 0 12 12 0 12"></polygon>
<path d="M6.3232233,1.68413601 C6.46387559,1.54348372 6.65464102,1.46446609 6.85355339,1.46446609 L9.93198052,1.46446609 C10.2081229,1.46446609 10.4319805,1.68832372 10.4319805,1.96446609 L10.4319805,5.04289322 C10.4319805,5.24180559 10.3529629,5.43257102 10.2123106,5.5732233 L5.30545635,10.4800776 C5.11019421,10.6753397 4.79361172,10.6753397 4.59834957,10.4800776 L1.41636906,7.29809704 C1.22110691,7.10283489 1.22110691,6.7862524 1.41636906,6.59099026 L6.3232233,1.68413601 Z M7.4267767,3.40900974 C7.13388348,3.70190296 7.13388348,4.1767767 7.4267767,4.46966991 C7.71966991,4.76256313 8.19454365,4.76256313 8.48743687,4.46966991 C8.78033009,4.1767767 8.78033009,3.70190296 8.48743687,3.40900974 C8.19454365,3.11611652 7.71966991,3.11611652 7.4267767,3.40900974 Z" id="形状" fill="#FFFFFF"></path>
</g>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>icon/满量折</title>
<defs>
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
<stop stop-color="#E0B26C" offset="0%"></stop>
<stop stop-color="#F6CF85" offset="100%"></stop>
</linearGradient>
</defs>
<g id="icon/满量折" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<circle id="椭圆形" fill="url(#linearGradient-1)" cx="8" cy="8" r="8"></circle>
<rect id="矩形" x="2" y="2" width="12" height="12"></rect>
<path d="M8,3 C9.1045695,3 10,3.8954305 10,5 L11.2954116,5 C11.691459,5 12.0192463,5.3079401 12.043951,5.70321629 L12.450201,12.2032163 C12.4760389,12.6166232 12.1618522,12.9727015 11.7484453,12.9985394 L11.7016616,13 L4.29833842,13 C3.88412485,13 3.54833842,12.6642136 3.54833842,12.25 L3.54979898,12.2032163 L3.95604898,5.70321629 C3.98075374,5.3079401 4.30854095,5 4.70458842,5 L6,5 C6,3.8954305 6.8954305,3 8,3 Z M9.76776695,9.69454365 C9.47487373,9.40165043 9,9.40165043 8.70710678,9.69454365 C8.41421356,9.98743687 8.41421356,10.4623106 8.70710678,10.7552038 C9,11.048097 9.47487373,11.048097 9.76776695,10.7552038 C10.0606602,10.4623106 10.0606602,9.98743687 9.76776695,9.69454365 Z M9.76776695,7.21966991 C9.57250481,7.02440777 9.25592232,7.02440777 9.06066017,7.21966991 L9.06066017,7.21966991 L6.23223305,10.048097 L6.1743776,10.1173449 C6.03938154,10.3122131 6.0586667,10.5816375 6.23223305,10.7552038 C6.42749519,10.950466 6.74407768,10.950466 6.93933983,10.7552038 L6.93933983,10.7552038 L9.76776695,7.9267767 L9.8256224,7.85752881 C9.96061846,7.66266067 9.9413333,7.39323627 9.76776695,7.21966991 Z M7.29289322,7.21966991 C7,6.9267767 6.52512627,6.9267767 6.23223305,7.21966991 C5.93933983,7.51256313 5.93933983,7.98743687 6.23223305,8.28033009 C6.52512627,8.5732233 7,8.5732233 7.29289322,8.28033009 C7.58578644,7.98743687 7.58578644,7.51256313 7.29289322,7.21966991 Z M8,4 C7.44771525,4 7,4.44771525 7,5 L9,5 C9,4.44771525 8.55228475,4 8,4 Z" id="形状结合" fill="#FFFFFF"></path>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>icon/满额减</title>
<defs>
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
<stop stop-color="#8469FD" offset="0%"></stop>
<stop stop-color="#A4A3FF" offset="100%"></stop>
</linearGradient>
</defs>
<g id="icon/满额减" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<circle id="椭圆形" fill="url(#linearGradient-1)" cx="8" cy="8" r="8"></circle>
<g id="图标" transform="translate(2.000000, 2.000000)">
<rect id="矩形" x="0" y="0" width="12" height="12"></rect>
<path d="M6,1 C7.38071187,1 8.5,1.67157288 8.5,2.5 C8.5,2.7937507 8.35926857,3.13064613 8.11605229,3.4431549 C9.81948922,4.1851489 11,5.74601553 11,7.25 L10.9970093,7.4429745 C10.9345703,9.42436149 9.875,11 6,11 C2,11 1,9.32106781 1,7.25 C1,5.74601553 2.18051078,4.1851489 3.8844864,3.44313898 C3.64073143,3.13064613 3.5,2.7937507 3.5,2.5 C3.5,1.67157288 4.61928813,1 6,1 Z M8,6 L4,6 L3.91012437,6.00805567 C3.67687516,6.05039163 3.5,6.25454011 3.5,6.5 C3.5,6.77614237 3.72385763,7 4,7 L4,7 L8,7 L8.08987563,6.99194433 C8.32312484,6.94960837 8.5,6.74545989 8.5,6.5 C8.5,6.22385763 8.27614237,6 8,6 L8,6 Z" id="形状结合" fill="#FFFFFF"></path>
</g>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>icon/满额折</title>
<defs>
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
<stop stop-color="#E0B26C" offset="0%"></stop>
<stop stop-color="#F6CF85" offset="100%"></stop>
</linearGradient>
</defs>
<g id="icon/满额折" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<circle id="椭圆形" fill="url(#linearGradient-1)" cx="8" cy="8" r="8"></circle>
<g id="线稿" transform="translate(2.000000, 2.000000)">
<rect id="矩形" x="0" y="0" width="12" height="12"></rect>
<path d="M6,1 C7.38071187,1 8.5,1.67157288 8.5,2.5 C8.5,2.7937507 8.35926857,3.13064613 8.11605229,3.4431549 C9.81948922,4.1851489 11,5.74601553 11,7.25 L10.9970093,7.4429745 C10.9345703,9.42436149 9.875,11 6,11 C2,11 1,9.32106781 1,7.25 C1,5.74601553 2.18051078,4.1851489 3.8844864,3.44313898 C3.64073143,3.13064613 3.5,2.7937507 3.5,2.5 C3.5,1.67157288 4.61928813,1 6,1 Z M7.76776695,7.69454365 C7.47487373,7.40165043 7,7.40165043 6.70710678,7.69454365 C6.41421356,7.98743687 6.41421356,8.4623106 6.70710678,8.75520382 C7,9.04809704 7.47487373,9.04809704 7.76776695,8.75520382 C8.06066017,8.4623106 8.06066017,7.98743687 7.76776695,7.69454365 Z M7.76776695,5.21966991 C7.57250481,5.02440777 7.25592232,5.02440777 7.06066017,5.21966991 L7.06066017,5.21966991 L4.23223305,8.04809704 L4.1743776,8.11734493 C4.03938154,8.31221307 4.0586667,8.58163747 4.23223305,8.75520382 C4.42749519,8.95046597 4.74407768,8.95046597 4.93933983,8.75520382 L4.93933983,8.75520382 L7.76776695,5.9267767 L7.8256224,5.85752881 C7.96061846,5.66266067 7.9413333,5.39323627 7.76776695,5.21966991 Z M5.29289322,5.21966991 C5,4.9267767 4.52512627,4.9267767 4.23223305,5.21966991 C3.93933983,5.51256313 3.93933983,5.98743687 4.23223305,6.28033009 C4.52512627,6.5732233 5,6.5732233 5.29289322,6.28033009 C5.58578644,5.98743687 5.58578644,5.51256313 5.29289322,5.21966991 Z" id="形状结合" fill="#FFFFFF"></path>
</g>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>icon/赠商品</title>
<defs>
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
<stop stop-color="#E0B26C" offset="0%"></stop>
<stop stop-color="#F6CF85" offset="100%"></stop>
</linearGradient>
</defs>
<g id="icon/赠商品" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<rect id="矩形" x="2" y="2" width="12" height="12"></rect>
<circle id="椭圆形" fill="url(#linearGradient-1)" cx="8" cy="8" r="8"></circle>
<path d="M3.91181982,9.15369477 C2.69606006,7.93793501 2.69606006,5.96679896 3.91181982,4.7510392 C5.02779142,3.6350676 6.77954787,3.8591266 8,4.79190286 C9.2190931,3.8591266 10.9722086,3.6350676 12.0881802,4.7510392 C13.3039399,5.96679896 13.3039399,7.93793501 12.0881802,9.15369477 L8.56568542,12.6761895 C8.25326599,12.988609 7.74673401,12.988609 7.43431458,12.6761895 L3.91181982,9.15369477 L3.91181982,9.15369477 Z" id="路径" fill="#FFFFFF"></path>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>icon/赠优惠券</title>
<defs>
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
<stop stop-color="#FD8525" offset="0%"></stop>
<stop stop-color="#FEB85F" offset="100%"></stop>
</linearGradient>
</defs>
<g id="icon/赠优惠券" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<circle id="椭圆形" fill="url(#linearGradient-1)" cx="8" cy="8" r="8"></circle>
<g id="图标" transform="translate(2.000000, 2.000000)">
<polygon id="矩形" points="0 0 12 0 12 12 0 12"></polygon>
<path d="M10,2 C10.5522847,2 11,2.44771525 11,3 L11,4.5 C10.1715729,4.5 9.5,5.17157288 9.5,6 C9.5,6.82842712 10.1715729,7.5 11,7.5 L11,9 C11,9.55228475 10.5522847,10 10,10 L2,10 C1.44771525,10 1,9.55228475 1,9 L1,7.5 C1.82842712,7.5 2.5,6.82842712 2.5,6 C2.5,5.17157288 1.82842712,4.5 1,4.5 L1,3 C1,2.44771525 1.44771525,2 2,2 L10,2 Z M5,4.5 C4.72385763,4.5 4.5,4.72385763 4.5,5 L4.5,5 L4.5,7 L4.50805567,7.08987563 C4.55039163,7.32312484 4.75454011,7.5 5,7.5 C5.27614237,7.5 5.5,7.27614237 5.5,7 L5.5,7 L5.5,5 L5.49194433,4.91012437 C5.44960837,4.67687516 5.24545989,4.5 5,4.5 Z M7,4.5 C6.72385763,4.5 6.5,4.72385763 6.5,5 L6.5,5 L6.5,7 L6.50805567,7.08987563 C6.55039163,7.32312484 6.75454011,7.5 7,7.5 C7.27614237,7.5 7.5,7.27614237 7.5,7 L7.5,7 L7.5,5 L7.49194433,4.91012437 C7.44960837,4.67687516 7.24545989,4.5 7,4.5 Z" id="形状结合" fill="#FFFFFF"></path>
</g>
</g>
</svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="design-iconfont">
<path d="M12,2 C17.5228475,2 22,6.4771525 22,12 C22,17.5228475 17.5228475,22 12,22 C6.4771525,22 2,17.5228475 2,12 C2,6.4771525 6.4771525,2 12,2 Z M12,7 C11.4477153,7 11,7.44771525 11,8 L11,8 L11,11 L8,11 C7.44771525,11 7,11.4477153 7,12 C7,12.5522847 7.44771525,13 8,13 L8,13 L11,13 L11,16 C11,16.5522847 11.4477153,17 12,17 C12.5522847,17 13,16.5522847 13,16 L13,16 L13,13 L16,13 C16.5522847,13 17,12.5522847 17,12 C17,11.4477153 16.5522847,11 16,11 L16,11 L13,11 L13,8 C13,7.44771525 12.5522847,7 12,7 Z" fill="#C8CACD" fill-rule="evenodd"/>
</svg>
import React, { useState, useRef, useMemo, useEffect } from 'react';
import { history } from 'umi';
import { Drawer, Button, Radio, message, Space, Typography } from 'antd';
import { PlayCircleOutlined, PoweroffOutlined } from '@ant-design/icons';
import { StandardTable } from 'god';
import { PublicApi } from '@/services/api';
import { formatTimeString } from '@/utils'
import { FORM_FILTER_PATH } from '@/formSchema/const';
import { useStateFilterSearchLinkageEffect } from '@/formSchema/effects/useFilterSearch';
import Search from '@/components/NiceForm/components/Search';
import DateRangePickerUnix from '@/components/NiceForm/components/DateRangePickerUnix'
import Submit from '@/components/NiceForm/components/Submit'
import StatusTag from '@/components/StatusTag'
import * as tableSchemas from './schema';
const options = [
{ label: '平台', value: 1 },
{ label: '商家', value: 2 },
];
interface ActivityDrawerProps {
visible: boolean,
onClose: () => void,
onConfirm?: (record) => void,
selectId?: string,
activityType?: 1 | 2, // 类型: 1.平台 2.商家
}
const ActivityDrawer: React.FC<ActivityDrawerProps> = (props: ActivityDrawerProps) => {
const { visible, onClose, onConfirm, selectId, activityType = 2 } = props;
const { query: { shopId, environment } }: any = history.location
const [type, setType] = useState(activityType);
const [selectedRowKeys, setSelectedRowKeys] = useState<any>(selectId ? [selectId] : []);
const [selectedRows, setSelectedRows] = useState<any>([]);
const ref = useRef<any>({});
const _schema = useMemo(() => {
return tableSchemas[`ActivitySchema${type}`]
}, [type])
useEffect(() => {
setSelectedRowKeys(selectId ? [selectId] : []);
}, [selectId])
const columns = [
{
title: '活动信息',
dataIndex: 'name',
key: 'name',
render: (text: any, record: any) => (
<Space direction='horizontal' style={{ width: 300 }}>
<img src={record.templatePicUrl} style={{ width: 40, height: 40, borderRadius: 4 }} />
<Space direction='vertical' style={{ width: 300 }}>
{text}
<Typography.Text type='secondary'>ID:{record.id}</Typography.Text>
</Space>
</Space>
)
},
{
title: '类型',
dataIndex: 'templateName',
key: 'templateName'
},
{
title: '有效期',
dataIndex: 'startTime',
key: 'startTime',
render: (_: any, record: any) => <>
<div><PlayCircleOutlined />&nbsp;{formatTimeString(record.startTime, 'YYYY-MM-DD HH:mm')}</div>
<div><PoweroffOutlined />&nbsp;{formatTimeString(record.endTime, 'YYYY-MM-DD HH:mm')}</div>
</>
},
{
title: '所属',
dataIndex: 'memberName',
key: 'memberName',
render: (text: any, record: any) => (
<Space direction='vertical'>
<StatusTag title={record.type === 1 ? '平台' : '商家'} type={record.type === 1 ? 'success' : 'primary'} />
{record.type === 2 && <Typography.Text type='secondary'>{text}</Typography.Text>}
</Space>
)
},
]
const _onConfirm = () => {
if (selectedRows.length > 0) {
onConfirm?.(selectedRows[0]);
} else {
message.warning('请选择一条记录')
}
}
const _onRadioChange = (e: any) => {
setType(e.target.value);
ref?.current?.reload();
}
const fetchTableData = async (params: any) => {
const _params = { ...params, environment, type, shopId }
const { data } = await PublicApi.getTemplateWebActivityPageListAdorn(_params);
return data;
}
const rowSelection: any = {
selectedRowKeys,
onChange: (selectedRowKeys, selectedRows) => {
setSelectedRows(selectedRows);
setSelectedRowKeys(selectedRowKeys)
},
type: 'radio'
}
const drawerStyle = { background: '#FAFBFC' };
return (
<Drawer
headerStyle={drawerStyle}
bodyStyle={drawerStyle}
footerStyle={drawerStyle}
width={1200}
title={'选择活动'}
visible={visible}
onClose={onClose}
footer={
<div style={{ textAlign: 'right', }}>
<Button onClick={onClose} style={{ marginRight: 8 }}>取消</Button>
<Button onClick={_onConfirm} type="primary">确定</Button>
</div>
}
>
<StandardTable
keepAlive={false}
fetchTableData={params => fetchTableData(params)}
columns={columns}
currentRef={ref}
rowSelection={rowSelection}
rowKey={'id'}
formilyLayouts={{
justify: 'space-between'
}}
formilyProps={{
ctx: {
inline: false,
schema: _schema,
effects: ($, actions) => {
useStateFilterSearchLinkageEffect(
$,
actions,
'name',
FORM_FILTER_PATH,
);
},
components: { ModalSearch: Search, DateRangePickerUnix, Submit },
},
layouts: {
order: 1,
span: 16
}
}}
formilyChilds={{
children: (
<div style={{ textAlign: 'right' }}>
<Radio.Group
options={options}
onChange={_onRadioChange}
value={type}
optionType="button"
/>
</div>
),
layouts: {
order: 2,
span: 8
}
}}
/>
</Drawer>
)
}
export default ActivityDrawer;
import { ISchema } from '@formily/antd';
import { FORM_FILTER_PATH } from '@/formSchema/const';
export const ActivitySchema1: ISchema = {
type: 'object',
properties: {
name: {
type: 'string',
'x-component': 'ModalSearch',
'x-component-props': {
placeholder: '搜索',
allowClear: true,
align: 'flex-start',
},
},
[FORM_FILTER_PATH]: {
type: 'object',
'x-component': 'flex-layout',
'x-component-props': {
rowStyle: {
flexWrap: 'nowrap',
justifyContent: 'flex-start',
},
colStyle: {
marginRight: 20,
},
},
properties: {
'[startTime,endTime]': {
type: 'array',
'x-component': 'DateRangePickerUnix',
'x-component-props': {
placeholder: ['开始时间','结束时间'],
allowClear: true,
},
},
sumbit: {
'x-component': 'Submit',
'x-mega-props': {
span: 1,
},
'x-component-props': {
children: '查询',
},
},
},
},
},
};
export const ActivitySchema2: ISchema = {
type: 'object',
properties: {
name: {
type: 'string',
'x-component': 'ModalSearch',
'x-component-props': {
placeholder: '搜索',
allowClear: true,
align: 'flex-start',
},
},
[FORM_FILTER_PATH]: {
type: 'object',
'x-component': 'flex-layout',
'x-component-props': {
rowStyle: {
flexWrap: 'nowrap',
justifyContent: 'flex-start',
},
colStyle: {
marginRight: 20,
},
},
properties: {
memberName: {
type: 'string',
'x-component-props': {
placeholder: '商家名称',
allowClear: true,
},
},
'[startTime,endTime]': {
type: 'array',
'x-component': 'DateRangePickerUnix',
'x-component-props': {
placeholder: ['开始时间','结束时间'],
allowClear: true,
},
},
sumbit: {
'x-component': 'Submit',
'x-mega-props': {
span: 1,
},
'x-component-props': {
children: '查询',
},
},
},
},
},
};
import { PublicApi } from '@/services/api';
// 高级筛选schema中用于输入搜索品牌的Effect
export const searchBrandOptionEffect = (
shopId: any,
context: any,
fieldName: string,
) => {
context.getFieldState(fieldName, state => {
PublicApi.getSearchCommodityTemplateGetBrandList({
current: '1',
pageSize: '100',
name: state.props['x-component-props'].searchValue,
shopId,
}).then(res => {
context.setFieldState(fieldName, state => {
state.props['x-component-props'].dataoption = res.data?.data?.map(item => {
return { label: item.name, value: item.id };
});
});
});
});
};
// 高级筛选schema中用于输入搜索商品品类的Effect
export const searchCustomerCategoryOptionEffect = (
shopId: any,
context: any,
fieldName: string,
) => {
context.getFieldState(fieldName, state => {
PublicApi.getSearchCommodityTemplateGetFirstCategoryListByMemberId({
shopId,
}).then(res => {
// PublicApi.getProductPlatformGetCategoryTree().then(res => {
context.setFieldState(fieldName, state => {
state.props['x-component-props'].dataoption = res.data?.map(item => {
return { title: item.name, id: item.id };
});
});
});
});
};
.commodityName {
flex: 1;
color: #252D37;
font-size: 14px;
overflow: hidden; // 超出的文本隐藏
text-overflow: ellipsis;
display: -webkit-box; // 将对象作为弹性伸缩盒子模型显示。
-webkit-box-orient: vertical; //从上到下垂直排列子元素(设置伸缩盒子的子元素排列方式)
-webkit-line-clamp: 2; // 结合上面两个属性,表示显示的行数。
margin-left: 10px;
}
.priceInfo {
font-size: 14px;
color: #D32F2F;
.unit {
color: #909399;
font-size: 12px;
}
}
.table {
:global {
// .ant-table-thead {
// tr {
// th {
// background-color: transparent;
// }
// }
// }
.ant-table-tbody {
tr {
td.ant-table-row-expand-icon-cell {
.ant-table-row-expand-icon{
display: none;
}
}
}
.ant-table-expanded-row {
.ant-table-cell {
background-color: #fff;
}
}
}
}
}
.defaultTag {
display: inline-block;
padding: 0 8px;
font-size: 12px;
font-weight: 400;
color: #5C626A;
background: #fff;
border-radius: 4px;
border: 1px solid #EDEEEF;
}
import React, { useState, useRef, useEffect } from 'react';
import { history } from 'umi';
import { Drawer, Button, message, Space, Table, Tooltip } from 'antd';
import { FormEffectHooks } from '@formily/antd'
import { StandardTable } from 'god';
import { PublicApi } from '@/services/api';
import { formatTimeString } from '@/utils'
import { FORM_FILTER_PATH } from '@/formSchema/const';
import { useStateFilterSearchLinkageEffect } from '@/formSchema/effects/useFilterSearch';
import Search from '@/components/NiceForm/components/Search';
import DateRangePickerUnix from '@/components/NiceForm/components/DateRangePickerUnix'
import Submit from '@/components/NiceForm/components/Submit'
import StatusTag from '@/components/StatusTag'
import CustomInputSearch from '@/components/NiceForm/components/CustomInputSearch'
import CustomCategorySearch from '@/components/NiceForm/components/CustomCategorySearch'
import ActivityImage from '@/assets/couponIcons/ActivityImage.svg';
import styles from './index.less';
import CommoditySchema from './schema';
import { searchBrandOptionEffect, searchCustomerCategoryOptionEffect } from './effect'
interface CommodityDrawerProps {
visible: boolean,
onClose: () => void,
onConfirm?: (record) => void,
selectId?: string | number[],
filterParam?: any,
selectType?: 'radio' | 'checkbox'
}
const _returnCategoryList = (list: any, obj: any) => {
obj.name && list.unshift(obj.name);
if (obj.category) {
_returnCategoryList(list, obj.category);
}
}
const CommodityDrawer: React.FC<CommodityDrawerProps> = (props: CommodityDrawerProps) => {
const { visible, onClose, onConfirm, selectId, filterParam, selectType = 'radio' } = props;
const { query: { shopId } }: any = history.location
const [selectedRowKeys, setSelectedRowKeys] = useState<any>(selectId ? [selectId] : []);
const [selectedRows, setSelectedRows] = useState<any>([]);
const [expandedRowKeys, setExpandedRowKeys] = useState<any>([]);
const ref = useRef<any>({});
useEffect(() => {
setSelectedRowKeys(selectId ? [selectId] : []);
}, [selectId])
const expandedRowRender = (record: any) => {
return (
<>
{record?.activityList?.map((item, index) => {
return (
<div key={index} style={{ marginBottom: 8 }}>
<Space direction='horizontal'>
<img src={ActivityImage} style={{ width: 24, height: 24, borderRadius: 4 }} />
<span>{item?.name}</span>
<div className={styles['defaultTag']}>{item?.type}</div>
<StatusTag title={item?.belongType === 1 ? '平台活动' : '商家活动'} type={item?.belongType === 1 ? 'primary' : 'success'} />
</Space>
</div>
)
})}
</>
);
}
const columns = [
{
title: '商品信息',
dataIndex: 'name',
key: 'name',
render: (text: any, record: any) => (
<Space direction='horizontal' style={{ width: 300 }}>
<img src={record.mainPic} style={{ width: 64, height: 64, borderRadius: 4 }} />
<Tooltip title={record.name}>
<div className={styles.commodityName}>{record.name}</div>
</Tooltip>
</Space>
)
},
{
title: '品类',
dataIndex: 'customerCategory',
render: (_, _record) => {
let _list = [];
_returnCategoryList(_list, _record?.customerCategory);
return (
<Space direction='horizontal'>
{_list?.map((item) => <StatusTag title={item} type="default" />)}
</Space>
)
}
},
{
title: '品牌',
dataIndex: 'brand',
render: (_, _record) => <span>{_record?.brand?.name}</span>
},
{
title: '价格',
dataIndex: 'unitName',
render: (_text, _record) => {
return (
<div className={styles.priceInfo}>
<span>{_record.min}</span>
<span className={styles.unit}>({_record.unitName})</span>
</div>
);
}
},
{
title: '商家名称',
dataIndex: 'memberName',
},
]
const _onConfirm = () => {
if (selectedRows.length > 0) {
if (selectType === 'radio') {
onConfirm?.(selectedRows[0]);
} else {
onConfirm?.(selectedRows);
}
} else {
message.warning('请选择一条记录')
}
}
const fetchTableData = async (params: any) => {
const _params = {
...params,
shopId,
...filterParam
}
if (selectId) {
_params.idNotInList = Array.isArray(selectId) ? selectId : [selectId]
}
const { data } = await PublicApi.getMarketingAdornGoodsListAdorn(_params);
setExpandedRowKeys(data?.data?.map((item) => item.id) || []);
return data;
}
const rowSelection: any = {
selectedRowKeys,
onChange: (selectedRowKeys, selectedRows) => {
setSelectedRows(selectedRows);
setSelectedRowKeys(selectedRowKeys)
},
type: selectType
}
const drawerStyle = { background: '#FAFBFC' };
return (
<Drawer
headerStyle={drawerStyle}
bodyStyle={drawerStyle}
footerStyle={drawerStyle}
width={1200}
title={'选择商品'}
visible={visible}
onClose={onClose}
destroyOnClose
footer={
<div style={{ textAlign: 'right', }}>
<Button onClick={onClose} style={{ marginRight: 8 }}>取消</Button>
<Button onClick={_onConfirm} type="primary">确定</Button>
</div>
}
>
<StandardTable
keepAlive={false}
fetchTableData={params => fetchTableData(params)}
columns={columns}
currentRef={ref}
rowSelection={rowSelection}
rowKey={'id'}
tableProps={{ expandable: { expandedRowRender, expandedRowKeys, indentSize: 0, defaultExpandAllRows: true },className: styles['table'] }}
formilyLayouts={{
justify: 'space-between'
}}
formilyProps={{
ctx: {
inline: false,
schema: CommoditySchema,
effects: ($, actions) => {
useStateFilterSearchLinkageEffect(
$,
actions,
'name',
FORM_FILTER_PATH,
);
FormEffectHooks.onFieldChange$('brandId').subscribe(state => {
searchBrandOptionEffect(shopId, actions, 'brandId')
})
FormEffectHooks.onFieldChange$('categoryId').subscribe(state => {
searchCustomerCategoryOptionEffect(shopId, actions, 'categoryId')
})
},
components: { ModalSearch: Search, DateRangePickerUnix, Submit, CustomInputSearch, CustomCategorySearch },
},
}}
/>
</Drawer>
)
}
export default CommodityDrawer;
import { ISchema } from '@formily/antd';
import { FORM_FILTER_PATH } from '@/formSchema/const';
const CommoditySchema: ISchema = {
type: 'object',
properties: {
name: {
type: 'string',
'x-component': 'ModalSearch',
'x-component-props': {
placeholder: '搜索',
allowClear: true,
align: 'flex-start',
},
},
[FORM_FILTER_PATH]: {
type: 'object',
'x-component': 'flex-layout',
'x-component-props': {
rowStyle: {
flexWrap: 'nowrap',
justifyContent: 'flex-start',
},
colStyle: {
marginRight: 20,
},
},
properties: {
id: {
type: 'string',
'x-component-props': {
placeholder: '商品ID',
allowClear: true,
},
},
memberName: {
type: 'string',
'x-component-props': {
placeholder: '商家名称',
allowClear: true,
},
},
brandId: {
type: 'string',
'x-component': 'CustomInputSearch',
'x-component-props': {
placeholder: '品牌',
showSearch: true,
showArrow: true,
defaultActiveFirstOption: false,
filterOption: false,
notFoundContent: null,
style: { width: '174px' },
searchValue: null,
dataoption: [],
},
},
categoryId: {
type: 'string',
'x-component': 'CustomCategorySearch',
'x-component-props': {
placeholder: '品类',
showSearch: true,
notFoundContent: null,
style: { width: '174px' },
dataoption: [],
fieldNames: { label: 'title', value: 'id', children: 'children' },
},
},
'[publishStartTime,publishEndTime]': {
type: 'array',
'x-component': 'DateRangePickerUnix',
'x-component-props': {
placeholder: ['开始时间','结束时间'],
allowClear: true,
},
},
sumbit: {
'x-component': 'Submit',
'x-mega-props': {
span: 1,
},
'x-component-props': {
children: '查询',
},
},
},
},
},
};
export default CommoditySchema
import React, { useState, useRef, useMemo, useEffect } from 'react';
import { history } from 'umi';
import { Drawer, Button, Radio, message, Space, Typography } from 'antd';
import { PlayCircleOutlined, PoweroffOutlined } from '@ant-design/icons';
import { StandardTable } from 'god';
import { PublicApi } from '@/services/api';
import { formatTimeString } from '@/utils'
import { priceFormat } from '@/utils/numberFomat'
import { FORM_FILTER_PATH } from '@/formSchema/const';
import { useStateFilterSearchLinkageEffect } from '@/formSchema/effects/useFilterSearch';
import Search from '@/components/NiceForm/components/Search';
import Submit from '@/components/NiceForm/components/Submit'
import StatusTag from '@/components/StatusTag'
import CouponPlatformIcon from '@/pages/pageCustomized/icons/coupon_platform.png';
import CouponShopIcon from '@/pages/pageCustomized/icons/coupon_shop.png';
import * as tableSchemas from './schema';
const options = [
{ label: '平台', value: 1 },
{ label: '商家', value: 2 },
];
interface CouponsDrawerProps {
visible: boolean,
onClose: () => void,
onConfirm?: (record) => void,
selectId?: number,
// 1平台,2商家
belongType?: 1 | 2
}
const CouponsDrawer: React.FC<CouponsDrawerProps> = (props: CouponsDrawerProps) => {
const { visible, onClose, onConfirm, selectId, belongType } = props;
const { query: { shopId } }: any = history.location
const [type, setType] = useState(belongType || 1);
const [selectedRowKeys, setSelectedRowKeys] = useState<any>(selectId ? [selectId] : []);
const [selectedRows, setSelectedRows] = useState<any>([]);
const ref = useRef<any>({});
const _schema = useMemo(() => {
return tableSchemas[`CouponSchema${type}`]
}, [type])
useEffect(() => {
setSelectedRowKeys(selectId ? [selectId] : []);
}, [selectId])
// useEffect(() => {
// ref?.current?.reload();
// }, [type, ref?.current])
const columns = [
{
title: '优惠券信息',
dataIndex: 'name',
key: 'name',
render: (text: any, record: any) => (
<Space direction='horizontal' style={{ width: 300 }}>
<img src={record.type === 1 ? CouponPlatformIcon : CouponShopIcon} style={{ width: 40, height: 40, borderRadius: 4 }} />
<Space direction='vertical' style={{ width: 300 }}>
{text}
<Typography.Text type='secondary'>ID:{record.id}</Typography.Text>
</Space>
</Space>
)
},
{
title: '类型',
dataIndex: 'typeName',
key: 'typeName'
},
{
title: '领劵方式',
dataIndex: 'getWayName',
key: 'getWayName'
},
{
title: '面额',
dataIndex: 'denomination',
key: 'denomination',
render: (text: any) => (
<span style={{ color: '#D32F2F' }}>¥ {priceFormat(text)}</span>
)
},
{
title: '使用条件',
dataIndex: 'useConditionMoney',
key: 'useConditionMoney',
render: (text: any) => (
`满 ${text} 元使用`
)
},
{
title: '有效期',
dataIndex: 'releaseTimeEnd',
key: 'releaseTimeEnd',
render: (_: any, record: any) => <>
<div><PlayCircleOutlined />&nbsp;{formatTimeString(record.releaseTimeStart, 'YYYY-MM-DD HH:mm')}</div>
<div><PoweroffOutlined />&nbsp;{formatTimeString(record.releaseTimeEnd, 'YYYY-MM-DD HH:mm')}</div>
</>
},
{
title: '所属',
dataIndex: 'belongName',
key: 'belongName',
render: (text: any, record: any) => (
<Space direction='vertical'>
<StatusTag title={record.belongType === 1 ? '平台' : '商家'} type={record.belongType === 1 ? 'success' : 'primary'} />
{record.belongType === 2 && <Typography.Text type='secondary'>{text}</Typography.Text>}
</Space>
)
},
]
const _onConfirm = () => {
if (selectedRows.length > 0) {
onConfirm?.({ ...selectedRows[0] });
} else {
message.warning('请选择一条记录')
}
}
const _onRadioChange = (e: any) => {
setType(e.target.value);
ref?.current?.reload();
}
const fetchTableData = async (params: any) => {
const _params = { ...params, shopId };
let _fetch: any;
switch (type) {
case 1:
_fetch = PublicApi.getMarketingCouponPlatformActivityPageSelectPage
break;
case 2:
_fetch = PublicApi.getMarketingCouponPlatformActivityPageSelectMerchantPage
break;
}
const { data } = await _fetch(_params);
return data;
}
const rowSelection: any = {
selectedRowKeys,
onChange: (selectedRowKeys, selectedRows) => {
setSelectedRows(selectedRows);
setSelectedRowKeys(selectedRowKeys)
},
type: 'radio'
}
const drawerStyle = { background: '#FAFBFC' };
return (
<Drawer
width={1200}
title={'选择优惠券'}
visible={visible}
onClose={onClose}
headerStyle={drawerStyle}
bodyStyle={drawerStyle}
footerStyle={drawerStyle}
footer={
<div style={{ textAlign: 'right', }}>
<Button onClick={onClose} style={{ marginRight: 8 }}>取消</Button>
<Button onClick={_onConfirm} type="primary">确定</Button>
</div>
}
>
<StandardTable
keepAlive={false}
fetchTableData={params => fetchTableData(params)}
columns={columns}
currentRef={ref}
rowSelection={rowSelection}
rowKey={'id'}
formilyLayouts={{
justify: 'space-between'
}}
formilyProps={{
ctx: {
inline: false,
schema: _schema,
effects: ($, actions) => {
useStateFilterSearchLinkageEffect(
$,
actions,
'id',
FORM_FILTER_PATH,
);
},
components: { ModalSearch: Search, Submit },
},
layouts: {
order: 1,
span: 16
}
}}
formilyChilds={{
children: (
<div style={{ textAlign: 'right' }}>
<Radio.Group
options={options}
onChange={_onRadioChange}
value={type}
optionType="button"
/>
</div>
),
layouts: {
order: 2,
span: 8
}
}}
/>
</Drawer>
)
}
export default CouponsDrawer;
import { ISchema } from '@formily/antd';
import { FORM_FILTER_PATH } from '@/formSchema/const';
export const CouponSchema1: ISchema = {
type: 'object',
properties: {
id: {
type: 'string',
'x-component': 'ModalSearch',
'x-component-props': {
placeholder: '搜索',
allowClear: true,
align: 'flex-start',
},
},
[FORM_FILTER_PATH]: {
type: 'object',
'x-component': 'flex-layout',
'x-component-props': {
rowStyle: {
flexWrap: 'nowrap',
justifyContent: 'flex-start',
},
colStyle: {
marginRight: 20,
},
},
properties: {
name: {
type: 'string',
'x-component-props': {
placeholder: '优惠劵名称',
allowClear: true,
},
},
sumbit: {
'x-component': 'Submit',
'x-mega-props': {
span: 1,
},
'x-component-props': {
children: '查询',
},
},
},
},
},
};
export const CouponSchema2: ISchema = {
type: 'object',
properties: {
id: {
type: 'string',
'x-component': 'ModalSearch',
'x-component-props': {
placeholder: '搜索',
allowClear: true,
align: 'flex-start',
},
},
[FORM_FILTER_PATH]: {
type: 'object',
'x-component': 'flex-layout',
'x-component-props': {
rowStyle: {
flexWrap: 'nowrap',
justifyContent: 'flex-start',
},
colStyle: {
marginRight: 20,
},
},
properties: {
name: {
type: 'string',
'x-component-props': {
placeholder: '优惠劵名称',
allowClear: true,
},
},
memberName: {
type: 'string',
'x-component-props': {
placeholder: '商家名称',
allowClear: true,
},
},
sumbit: {
'x-component': 'Submit',
'x-mega-props': {
span: 1,
},
'x-component-props': {
children: '查询',
},
},
},
},
},
};
.shopName {
display: flex;
flex-direction: column;
&-top {
flex: 1;
display: flex;
flex-direction: row;
color: #252D37;
font-size: 14px;
&-tag {
margin-left: 20px;
display: inline-block;
background: #FFF0F2;
border-radius: 2px;
font-size: 12px;
color: #EF3346;
padding: 2px 4px;
}
}
&-bottom {
color: #909399;
font-size: 12px;
}
}
.info {
display: flex;
flex-direction: column;
justify-content: center;
&-title {
flex: 1;
font-size: 14px;
color: #252D37;
}
&-bottom {
flex: 1;
display: flex;
flex-direction: row;
font-size: 12px;
align-items: center;
justify-content: center;
&-tag {
display: inline-block;
padding: 2px 4px;
border-radius: 2;
background-color: #EBF9F6;
color: #00A98F;
}
&-time {
flex: 1;
color: #909399;
text-align: right;
}
}
}
import React, { useState, useEffect, useMemo } from 'react';
import { Drawer, Input, Table, Button, Row, Col, message } from 'antd';
import { SearchOutlined } from '@ant-design/icons';
import moment from 'moment';
import { priceFormat } from '@/utils/numberFomat';
import { PublicApi } from '@/services/api';
import styles from './index.less';
interface MixDrawerProps {
visible: boolean,
// 1商城,3积分商品,4店铺,5资讯, 6品牌,
type: 1 | 3 | 4 | 5 | 6,
shopId?: number,
// 1.B端 2.C端 3.SRM
property: 1 | 2 | 3,
onConfirm: (record: any) => void,
onClose?: () => void,
selectId?: string | number[],
selectType?: 'radio' | 'checkbox',
filterParam?: any,
}
const Environment_MAPS = {
1: 'web',
2: 'H5',
3: '小程序',
4: 'APP'
}
const Property_MAPS = {
1: 'B端商城',
2: 'C端商城',
3: 'SRM商城',
}
const Title_MAPS = {
1: '选择商城',
3: '选择积分商品',
4: '选择店铺',
5: '选择资讯'
}
const MixDrawer: React.FC<MixDrawerProps> = (props: MixDrawerProps) => {
const { visible, type, property, onConfirm, onClose, selectId, filterParam, shopId, selectType = 'radio' } = props;
const [dataSource, setDataSource] = useState<any>([]);
const [totalCount, setTotalCount] = useState<number>(0);
const [selectedRowKeys, setSelectedRowKeys] = useState<any>([]);
const [selectedRows, setSelectedRows] = useState<any>([]);
const [keyWord, setKeyWord] = useState<string>('');
const [current, setCurrent] = useState<number>(1);
const [pageSize, setPageSize] = useState<number>(10);
useEffect(() => {
setSelectedRowKeys(selectId ? [selectId] : []);
}, [selectId])
const _search = (current: number, pageSize: number, keyWord?: string) => {
setCurrent(current);
setPageSize(pageSize);
let _params: any = {
current,
pageSize,
...filterParam
}
let _fetch;
switch (type) {
case 1:
_params.type = 1;
_params.environment = 4;
_params.property = property;
if (keyWord) {
_params.name = keyWord
}
_fetch = PublicApi.getManageShopListAdorn;
break;
case 3:
if (keyWord) {
_params.name = keyWord
}
_params.priceType = 3;
if (selectId) {
_params.idNotList = Array.isArray(selectId) ? selectId : [selectId]
}
_fetch = PublicApi.getProductCommodityGetPlatformCommodityList;
break;
case 4:
if (keyWord) {
_params.memberName = keyWord
}
_fetch = PublicApi.getTemplateWebMemberShopWebMemberShopListAdorn;
break;
// 资讯
case 5:
if (keyWord) {
_params.title = keyWord
}
if (property === 1) {
_params.shopId = shopId
_params.idNotInList = selectId
}
_fetch = PublicApi.getManageContentInformationListAdorn;
break;
// 品牌
case 6:
if (keyWord) {
_params.name = keyWord
}
_params.shopId = shopId
_params.idNotInList = selectId
_fetch = PublicApi.getSearchCommodityTemplateGetBrandList;
break;
}
_fetch && _fetch(_params).then((res) => {
message.destroy()
if (res.code === 1000) {
setDataSource(res.data?.data ?? res.data);
setTotalCount(res.data?.totalCount ?? res.data.length);
} else {
setDataSource([])
setTotalCount(0);
}
}).catch(err => console.log(err))
}
const _onInputChange = (e) => {
const _val = e.target.value;
setKeyWord(_val);
}
const _onPageChange = (page, pageSize) => {
_search(page, pageSize)
}
const _onConfirm = () => {
if (selectedRows.length > 0) {
if (selectType === 'radio') {
onConfirm(selectedRows[0]);
} else {
onConfirm(selectedRows);
}
} else {
message.warning('请选择一条记录')
}
}
const columns = useMemo(() => {
if (type === 1) {
return (
[
{
title: 'logoUrl',
dataIndex: 'logoUrl',
width: 64,
render: (text: string) => {
return (
<img src={text} style={{ width: 64, height: 64 }} />
)
},
},
{
title: 'name',
dataIndex: 'name',
render: (text: string, record: any) => {
return (
<div className={styles['shopName']}>
<div className={styles['shopName-top']}>
{text}
<div className={styles['shopName-top-tag']}>{Property_MAPS[record?.property]}</div>
</div>
<div className={styles['shopName-bottom']}>
{record?.describe}
</div>
</div>
)
},
},
{
title: 'environment',
dataIndex: 'environment',
render: (text: any) => {
return (
<span style={{ color: '#007BFC', background: '#E9F3FF', borderRadius: 2, display: 'inline-block', padding: '2px 4px' }}>{Environment_MAPS[text]}</span>
)
},
},
]
)
}
if (type === 3) {
return (
[
{
title: 'mainPic',
dataIndex: 'mainPic',
render: (text: string) => {
return (
<img src={text} style={{ width: 40, height: 40 }} />
)
},
},
{
title: 'name',
dataIndex: 'name',
},
{
title: 'min',
dataIndex: 'min',
render: (_: any, record: any) => {
return (
<span style={{ color: '#EA8000' }}>{priceFormat(record?.min)} 积分</span>
)
},
},
]
)
}
if (type === 4) {
return (
[
{
title: 'logo',
dataIndex: 'logo',
render: (text: string) => {
return (
<img src={text} style={{ width: 40, height: 40 }} />
)
},
},
{
title: 'memberName',
dataIndex: 'memberName',
}
]
)
}
if (type === 5) {
return (
[
{
title: 'imageUrl',
dataIndex: 'imageUrl',
width: 72,
render: (text: string) => {
return (
<img src={text} style={{ width: 72, height: 48 }} />
)
},
},
{
title: 'title',
dataIndex: 'title',
render: (text: string, record: any) => {
return (
<div className={styles['info']}>
<div className={styles['info-title']}>{text}</div>
<div className={styles['info-bottom']}>
<div className={styles['info-bottom-tag']}>{record?.columnName}</div>
<div className={styles['info-bottom-time']}>{moment(record?.createTime).format('YYYY-MM-DD')}</div>
</div>
</div>
)
},
}
]
)
}
if (type === 6) {
return (
[
{
title: 'logoUrl',
dataIndex: 'logoUrl',
render: (text: string) => {
return (
<img src={text} style={{ width: 40, height: 40 }} />
)
},
},
{
title: 'name',
dataIndex: 'name',
}
]
)
}
}, [type]);
const rowSelection: any = {
selectedRowKeys,
onChange: (selectedRowKeys, selectedRows) => {
setSelectedRows(selectedRows);
setSelectedRowKeys(selectedRowKeys)
},
type: selectType
}
useEffect(() => {
setDataSource([]);
setKeyWord('');
}, [type])
useEffect(() => {
if (visible) {
_search(current, pageSize);
}
}, [visible])
const _showTotal = (total) => {
return `共 ${total} 条`
}
const drawerStyle = { background: '#FAFBFC' };
return (
<Drawer
headerStyle={drawerStyle}
bodyStyle={drawerStyle}
footerStyle={drawerStyle}
width={800}
title={Title_MAPS[type]}
visible={visible}
onClose={onClose}
footer={
<div style={{ textAlign: 'right', }}>
<Button onClick={onClose} style={{ marginRight: 8 }}>取消</Button>
<Button onClick={_onConfirm} type="primary">确定</Button>
</div>
}
>
<div>
<Row style={{ marginBottom: 16 }}>
<Col span={8}>
<Input
onChange={_onInputChange}
placeholder="搜索"
suffix={<SearchOutlined onClick={() => { _search(1, pageSize, keyWord) }} />}
allowClear={true}
onPressEnter={() => { _search(1, pageSize, keyWord) }}
/>
</Col>
</Row>
<Table
rowKey={'id'}
columns={columns}
showHeader={false}
rowSelection={rowSelection}
dataSource={dataSource}
pagination={{ total: totalCount, pageSize: pageSize, current: current, onChange: _onPageChange, showTotal: _showTotal, showSizeChanger: true, showQuickJumper: true, size: 'small' }}
/>
</div>
</Drawer>
)
}
export default MixDrawer;
.marketingSwitch {
width: 136px;
height: 100px;
border: 1px solid #FAFBFB;
border-radius: 4px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.marketingSwitch_img{
width: 20px;
height: 20px;
}
.marketingSwitch_text{
font-size: 12px;
color: #5C626A;
margin: 9px 0;
}
}
import React, { useCallback } from 'react';
import { Switch } from 'antd';
import { cloneDeep } from 'lodash';
import { updatePageConfig, STATE_PROPS, SelectedInfoType, PageConfigType } from '@lingxi-disign/core';
import { useSelector } from '@lingxi-disign/react';
import * as MarketingConfigs from '../../../mobileTemplate/shopTemplateEdit/page_config';
import styles from './index.less';
interface MarketingSwitchProps {
type: number,
title: string,
icon: any
}
type SettingPanelType = {
selectedInfo: SelectedInfoType,
pageConfig: PageConfigType
}
const MarketingSwitch: React.FC<MarketingSwitchProps> = (props: any) => {
const { type, title, icon } = props;
const { pageConfig } = useSelector<SettingPanelType, STATE_PROPS>(['pageConfig']);
const _checked = Object.keys(pageConfig).indexOf(`11-${type}`) >= 0;
const _onChange = useCallback((checked: boolean) => {
if (checked) {
let _pageConfig: any = { ...pageConfig }
const _marketingConfig = MarketingConfigs[`marketingConfig_${type}`];
_pageConfig = cloneDeep({ ..._pageConfig, ..._marketingConfig });
const _insertIndex = _pageConfig['0'].childNodes.indexOf('10');
_pageConfig['0'].childNodes?.splice(_insertIndex, 0, `11-${type}`);
updatePageConfig(_pageConfig);
} else {
const _type = `11-${type}`;
let _pageConfig: any = cloneDeep({ ...pageConfig })
const _deleteType = _type.split('-');
for (let key in _pageConfig) {
const _deteleKey = key.split('-')
if (_deleteType[0] === _deteleKey[0] && _deleteType[1] === _deteleKey[1]) {
delete _pageConfig[key]
}
}
_pageConfig['0'].childNodes.splice(_pageConfig['0'].childNodes.indexOf(_type), 1);
updatePageConfig(_pageConfig);
}
}, [pageConfig])
return (
<div className={styles.marketingSwitch}>
<img src={icon} className={styles.marketingSwitch_img} />
<div className={styles.marketingSwitch_text}>{title}</div>
<Switch size='small' onChange={_onChange} checked={_checked} />
</div>
);
}
export default MarketingSwitch;
import icon1 from '@/assets/couponIcons/marketing-1.svg';
import icon2 from '@/assets/couponIcons/marketing-2.svg';
import icon3 from '@/assets/couponIcons/marketing-3.svg';
import icon4 from '@/assets/couponIcons/marketing-4.svg';
import icon5 from '@/assets/couponIcons/marketing-5.svg';
import icon6 from '@/assets/couponIcons/marketing-6.svg';
import icon7 from '@/assets/couponIcons/marketing-7.svg';
import icon8 from '@/assets/couponIcons/marketing-8.svg';
import icon9 from '@/assets/couponIcons/marketing-9.svg';
import icon10 from '@/assets/couponIcons/marketing-10.svg';
import icon11 from '@/assets/couponIcons/marketing-11.svg';
import icon12 from '@/assets/couponIcons/marketing-12.svg';
import icon13 from '@/assets/couponIcons/marketing-13.svg';
import icon14 from '@/assets/couponIcons/marketing-14.svg';
import icon15 from '@/assets/couponIcons/marketing-15.svg';
import icon16 from '@/assets/couponIcons/marketing-16.svg';
import icon17 from '@/assets/couponIcons/marketing-17.svg';
import icon18 from '@/assets/couponIcons/marketing-18.svg';
import icon19 from '@/assets/couponIcons/marketing-19.svg';
const ICON_CONFIGS = [
{type : 1, title: '特价促销',explain: '爆款限时特价',icon: icon1},
{type : 2, title: '直降促销',explain: '大牌商品最高直降$元',icon: icon2},
{type : 3, title: '满量减',explain: '大牌商品最高减$元',icon: icon3},
{type : 4, title: '折扣促销',explain: '大牌商品低至$折',icon: icon4},
{type : 5, title: '满量折',explain: '大牌商品低至$折',icon: icon5},
{type : 6, title: '满额减',explain: '大牌商品最高减$元',icon: icon6},
{type : 7, title: '满额折',explain: '大牌商品低至$折',icon: icon7},
{type : 8, title: '赠商品',explain: '满$元即有机会获赠商品',icon: icon8},
{type : 9, title: '赠优惠券',explain: '价值$元优惠券免费领取',icon: icon9},
{type : 10, title: '多件促销',explain: '任选$件商品,$折起!',icon: icon10},
{type : 11, title: '组合促销',explain: '任选$件商品,仅需$元!',icon: icon11},
{type : 12, title: '秒杀',explain: '今日大牌秒杀',icon: icon12},
{type : 13, title: '拼团',explain: '大牌拼团直降$元',icon: icon13},
{type : 14, title: '满额换购',explain: '满$元即可换购以下商品',icon: icon14},
{type : 15, title: '买商品换购',explain: '购买指定商品即可换购以下商品',icon: icon15},
{type : 16, title: '预售',explain: '大牌新品火爆预售',icon: icon16},
{type : 17, title: '试用',explain: '新品抢先试用',icon: icon17},
{type : 18, title: '套餐',explain: '超级搭配套餐',icon: icon18},
{type : 19, title: '砍价',explain: '砍一砍,免费拿',icon: icon19},
]
export default ICON_CONFIGS;
.edit_container {
width: 320px;
background-color: #FFF;
:global {
.ant-tabs-card.ant-tabs-top > .ant-tabs-nav .ant-tabs-tab:not(:last-of-type), .ant-tabs-card.ant-tabs-bottom > .ant-tabs-nav .ant-tabs-tab:not(:last-of-type), .ant-tabs-card.ant-tabs-top > div > .ant-tabs-nav .ant-tabs-tab:not(:last-of-type), .ant-tabs-card.ant-tabs-bottom > div > .ant-tabs-nav .ant-tabs-tab:not(:last-of-type){
margin: 0;
}
.ant-tabs-nav-list{
width: 100%;
.ant-tabs-tab{
border: 0;
margin: 0;
flex: 1;
height: 48px;
background-color: #FAFBFC;
display: flex;
align-items: center;
justify-content: center;
color: #8E959D;
font-size: 16px;
}
.ant-tabs-tab-active{
background-color: #fff;
color: #1F2C3D;
}
}
.ant-tabs-card .ant-tabs-content {
margin-top: -16px;
}
.ant-tabs-card .ant-tabs-content>.ant-tabs-tabpane {
// padding: 16px;
background: #fff;
}
.ant-tabs-card>.ant-tabs-nav::before {
display: none;
}
}
}
import React from 'react';
import { Tabs, Row, Col } from 'antd';
import { PropsType, ChildNodesType } from '@lingxi-disign/core';
import { ModuleTree } from '@lingxi-disign/react';
import MarketingSwitch from '../marketingSwitch';
import ICONS_CONFIG from './iconsConfig';
import styles from './index.less';
const { TabPane } = Tabs;
export interface VirtualDOMType {
key?: string;
componentName: string;
props?: PropsType;
childNodes?: ChildNodesType;
condition?: string;
isStateDomain?: boolean;
propFields?: string[];
methods?: {
[key: string]: string;
};
loop?: string | any[];
fileName?: string;
[custom: string]: any;
}
interface MobileClientEditLeftProps {
}
const MobileClientEditLeft: React.FC<MobileClientEditLeftProps> = (props: MobileClientEditLeftProps) => {
return (
<div className={styles.edit_container}>
<Tabs type="card">
<TabPane tab="已添加" key="1">
<ModuleTree />
</TabPane>
<TabPane tab="全部模块" key="2">
<Row gutter={16}>
{ICONS_CONFIG.map((item, index) => <Col key={index} span={12} style={{ marginBottom: 16 }}><MarketingSwitch {...item} /></Col>)}
</Row>
</TabPane>
</Tabs>
</div>
);
};
export default MobileClientEditLeft;
......@@ -5,6 +5,7 @@ import { PublicApi } from '@/services/api'
import { LAYOUT_TYPE } from '@/constants'
import { STATE_PROPS, PageConfigType, PROPS_SETTING_TYPES } from '@lingxi-disign/core'
import { useSelector } from '@lingxi-disign/react'
import { paramsShop, paramsChannel } from './returnSaveParams'
import { history } from 'umi'
import styles from './index.less'
......@@ -38,94 +39,11 @@ const ToolBar: React.FC<ToolBarPropsType> = (props) => {
}
const handleSave = useCallback(() => {
const param: any = {
templateId: Number(templateId),
}
if(layoutType === LAYOUT_TYPE.shop) {
param.appStoreBO = {}
Object.keys(pageConfig).forEach(key => {
const pageConfigItem = pageConfig[key]
if(pageConfigItem.componentType) {
switch(pageConfigItem.componentType) {
case PROPS_SETTING_TYPES.mobileShopHeaderNav:
param.appStoreBO.backdropBO = {
status: false,
backdrop: pageConfigItem.props.backdrop || ''
}
break
case PROPS_SETTING_TYPES.mobileBanner:
param.appStoreBO.advertBO = {
status: false,
advertDetailsBOList: pageConfigItem.props.dataList || []
}
break
case PROPS_SETTING_TYPES.mobileQuickNav:
param.appStoreBO.functionBO = {
status: false,
functionDetailsBO: pageConfigItem.props.dataList || []
}
break
case PROPS_SETTING_TYPES.mobileShopCommodity:
param.appStoreBO.productBO = {
status: false,
title: pageConfigItem.props.title,
productIdList: pageConfigItem.props.productIdList,
}
break
default:
break
}
}
})
if (layoutType === LAYOUT_TYPE.shop) {
saveAppEnterprise(paramsShop(templateId, pageConfig))
} else if(layoutType=== LAYOUT_TYPE.channel) {
param.appChannelBO = {}
console.log(pageConfig, "pageConfig")
Object.keys(pageConfig).forEach(key => {
const pageConfigItem = pageConfig[key]
if(pageConfigItem.componentType) {
switch(pageConfigItem.componentType) {
case PROPS_SETTING_TYPES.mobileHeaderNav:
param.appChannelBO.topBO = {
status: false,
style: pageConfigItem.props.styleTheme,
topDetailsBOList: pageConfigItem.props.dataList || []
}
break
case "mobileChannelBanner":
case PROPS_SETTING_TYPES.mobileBanner:
param.appChannelBO.advertBO = {
status: false,
advertDetailsBOList: pageConfigItem.props.dataList || []
}
break
case PROPS_SETTING_TYPES.mobileChannelGoodsCard:
param.appChannelBO.productBO = {
status: false,
productDetailsBOList: pageConfigItem.props.dataList || []
}
break
case PROPS_SETTING_TYPES.moibileChannelInformation:
param.appChannelBO.informationBO = {
status: false,
title: pageConfigItem.props.title,
informationIdList: pageConfigItem.props.informationIdList || []
}
break
case PROPS_SETTING_TYPES.mobileBottomNavigation:
param.appChannelBO.bottomBO = {
status: false,
bottomDetailsBOList: pageConfigItem.props.dataList || []
}
break
default:
break
}
}
})
saveAppEnterprise(paramsChannel(templateId, pageConfig))
}
console.log(JSON.stringify(param), "param")
saveAppEnterprise(param)
}, [pageConfig])
const saveAppEnterprise = (param) => {
......
import {
PageConfigType,
getComponentConfig,
PROPS_SETTING_TYPES,
ROOT,
ChildNodesType
} from '@lingxi-disign/core';
import { get, isEmpty } from 'lodash'
const contactList = (list: any[], data: any) => {
let result: any[] = [];
if (list && Array.isArray(list)) {
result = [...list, data];
} else {
result = [data];
}
return result;
};
/**
* 处理店铺装修数据
* @param templateId
* @param pageConfig
*/
export const paramsShop = (
templateId: number,
pageConfig: PageConfigType,
) => {
let _params: any = {
templateId,
adornContent: {},
categoryAdornContent: {},
};
const _root: any = pageConfig[ROOT].childNodes || [];
_root.forEach(childKey => {
let propsData: any = undefined;
let childNodes: ChildNodesType | undefined = undefined
let tempProps: any = undefined
switch (childKey) {
case '1':
propsData = get(pageConfig, ['1', 'props']) || {}
if (propsData.backdrop) {
_params.adornContent.header = {
style: 0,
status: true,
details: {
backdrop: propsData.backdrop || ''
}
}
}
break
case '2':
propsData = get(pageConfig, ['2', 'props']) || {}
childNodes = get(pageConfig, ['2', 'childNodes']) || {}
_params.adornContent.navList = {
style: 0,
status: true,
details: []
}
if (childNodes && Array.isArray(childNodes) && childNodes.length > 0) {
for (let key in childNodes) {
tempProps = pageConfig[childNodes[key]]?.props || {}
!isEmpty(tempProps) && _params.adornContent.navList.details.push({
id: tempProps.id,
name: tempProps.name,
type: tempProps.type,
url: tempProps.url,
icon: tempProps.icon,
});
}
}
break
case '4':
propsData = get(pageConfig, ['4', 'props']) || {}
childNodes = get(pageConfig, ['4', 'childNodes']) || {}
_params.adornContent.advert = {
style: propsData.styleTheme || 0,
status: true,
details: []
}
if (childNodes && Array.isArray(childNodes) && childNodes.length > 0) {
for (let key in childNodes) {
tempProps = pageConfig[childNodes[key]]?.props || {}
!isEmpty(tempProps) && _params.adornContent.advert.details.push({
id: tempProps.id,
name: tempProps.name,
type: tempProps.type,
img: tempProps.img,
});
}
}
break
case '6':
propsData = get(pageConfig, ['6', 'props']) || {}
childNodes = get(pageConfig, ['6', 'childNodes']) || {}
_params.adornContent.commodity = {
style: 0,
status: true,
details: []
}
if (childNodes && Array.isArray(childNodes) && childNodes.length > 0) {
for (let key in childNodes) {
tempProps = pageConfig[childNodes[key]]?.props || {}
!isEmpty(tempProps) && _params.adornContent.commodity.details.push({
title: tempProps.title,
categoryId: tempProps.categoryId,
idList: tempProps.idList,
manageWay: tempProps.manageWay,
num: tempProps.num,
})
}
}
break
}
})
return _params;
};
/**
* 处理渠道装修数据
* @param templateId
* @param pageConfig
*/
export const paramsChannel = (
templateId: number,
pageConfig: PageConfigType,
) => {
let _params: any = {
templateId,
adornContent: {},
};
const _root: any = pageConfig[ROOT].childNodes || [];
_root.forEach(childKey => {
let propsData: any = undefined;
let childNodes: ChildNodesType | undefined = undefined
let tempProps: any = undefined
switch (childKey) {
case '1':
break
}
})
return _params;
};
import {
ComponentSchemaType,
PROPS_SETTING_TYPES,
PROPS_TYPES,
} from '@lingxi-disign/core';
const Banner: ComponentSchemaType = {
propsConfig: {
children: {
label: '内容',
type: PROPS_TYPES.string,
},
},
};
const BannerItems: ComponentSchemaType = {
fatherNodesRule: ['Banner.children'],
propsConfig: {
children: {
label: '内容',
type: PROPS_TYPES.string,
},
componentType: {
type: PROPS_SETTING_TYPES.bannerItems,
},
},
};
export default {
Banner,
'Banner.Items': BannerItems,
};
import {
ComponentSchemaType,
PROPS_SETTING_TYPES,
PROPS_TYPES,
} from '@lingxi-disign/core';
const MobileNavCard: ComponentSchemaType = {
propsConfig: {
children: {
label: '内容',
type: PROPS_TYPES.string,
},
styleType: {
label: "样式",
type: PROPS_TYPES.number,
},
},
};
const MobileNavCardNavItem: ComponentSchemaType = {
fatherNodesRule: ['MobileNavCard.children'],
propsConfig: {
children: {
label: '内容',
type: PROPS_TYPES.string,
},
componentType: {
label: '内容',
type: PROPS_SETTING_TYPES.mobileNavCardNavItem,
},
},
};
export default {
MobileNavCard,
'MobileNavCard.NavItem': MobileNavCardNavItem,
};
import {
ComponentSchemaType,
PROPS_SETTING_TYPES,
PROPS_TYPES,
} from '@lingxi-disign/core';
const MobileShopCommodity: ComponentSchemaType = {
propsConfig: {
children: {
label: '内容',
type: PROPS_TYPES.string,
},
},
};
const CommodityItem: ComponentSchemaType = {
fatherNodesRule: ['MobileShopCommodity.children'],
propsConfig: {
children: {
label: '内容',
type: PROPS_TYPES.string,
},
componentType: {
label: '内容',
type: PROPS_SETTING_TYPES.mobileShopCommodity,
},
},
};
export default {
MobileShopCommodity,
'MobileShopCommodity.Item': CommodityItem,
};
import { ComponentSchemaType, PROPS_SETTING_TYPES } from '@lingxi-disign/core';;
const MobileShopHeader: ComponentSchemaType = {
propsConfig: {
componentType: {
label: '编辑',
type: PROPS_SETTING_TYPES.mobileShopHeaderNav
},
},
};
export default MobileShopHeader;
......@@ -43,6 +43,10 @@ import MobileChannelGoodsCard from './MobileChannelGoodsCard'
import MobileChannelInformation from './MobileChannelInformation'
import MobileChannelCategory from './MobileChannelCategory'
import View from './View';
import MobileShopHeader from './MobileShopHeader'
import MobileNavCard from './MobileNavCard'
import Banner from './Banner'
import MobileShopCommodity from './MobileShopCommodity'
export default {
View,
......@@ -81,4 +85,8 @@ export default {
...FloorLine,
...ShopFloorLine,
...ShowCase,
MobileShopHeader,
...MobileNavCard,
...Banner,
...MobileShopCommodity,
}
......@@ -13,9 +13,13 @@ type SettingPanelType = {
pageConfig: PageConfigType,
}
interface MobileSettingPanelProps {
shopId: number
}
const { TabPane } = Tabs
const MobileSettingPanel: React.FC = ()=> {
const MobileSettingPanel: React.FC<MobileSettingPanelProps> = (props)=> {
const { selectedInfo, pageConfig } = useSelector<SettingPanelType, STATE_PROPS>(['selectedInfo', 'pageConfig'])
const { propsConfig } = selectedInfo || {}
const [ newSelectInfo, setNewSelectInfo ] = useState<SelectedInfoType>()
......@@ -27,7 +31,6 @@ const MobileSettingPanel: React.FC = ()=> {
const newProps = get(pageConfig, [selectedKey, 'props'], oldProps)
const updateSelectInfo = { ...selectedInfo }
updateSelectInfo.props = newProps
console.log(JSON.stringify(newProps))
setNewSelectInfo(updateSelectInfo)
}
}
......@@ -41,9 +44,13 @@ const MobileSettingPanel: React.FC = ()=> {
defaultActiveKey="1"
className={styles.settingTabs}
>
<TabPane tab="编辑" key="props">
<PropsSettings selectedInfo={newSelectInfo} />
</TabPane>
{
(propsConfig && propsConfig.componentType) && (
<TabPane tab="编辑" key="props">
<PropsSettings selectedInfo={newSelectInfo} {...props} />
</TabPane>
)
}
{
(propsConfig && propsConfig.styleType) && (
<TabPane tab="样式" key="style">
......
import React from 'react'
import { numFormat, priceFormat } from '@/utils/numberFomat'
import ImageBox from '@/components/ImageBox'
const showMainPic = (mainPic: string) => <ImageBox width={32} height={32} imgUrl={mainPic} />
export const promptCommodityColumn = [
{
title: 'ID',
dataIndex: 'id',
key: 'id',
width: 80,
},
{
title: "商品图片",
dataIndex: "mainPic",
render: (mainPic: string) => showMainPic(mainPic)
},
{
title: "商品名称",
dataIndex: "name",
width: 300,
ellipsis: true,
},
{
title: "品类",
// render: (_, record) => record.customerCategory.name
},
{
title: "品牌",
// render: (_, record) => record.brand.name
},
{
title: "价格",
dataIndex: "min",
render: (_, record) => ${priceFormat(record.min)}`
},
]
export const integralCommodityColumn = [
{
title: "商品图片",
dataIndex: "mainPic",
render: (mainPic: string) => showMainPic(mainPic)
},
{
title: "商品名称",
dataIndex: "name",
width: 300,
ellipsis: true,
},
{
title: "需要积分",
dataIndex: "min",
render: (_, record) => `${numFormat(record.min)}`
},
]
export const shopColumn = [
{
title: "店铺图片",
dataIndex: "logo",
render: (logo: string) => showMainPic(logo)
},
{
title: "店铺名称",
dataIndex: "memberName",
width: 300,
ellipsis: true,
},
]
export const informationColumn = [
{
title: "资讯图片",
dataIndex: "imageUrl",
render: (imageUrl: string) => showMainPic(imageUrl)
},
{
title: "资讯标题",
dataIndex: "title",
width: 360,
ellipsis: true,
},
]
const tableColumn = {
1: promptCommodityColumn,
2: integralCommodityColumn,
3: shopColumn,
4: informationColumn
}
export default tableColumn
import { ISchema } from '@formily/antd'
import { FORM_FILTER_PATH } from '@/formSchema/const'
import { PublicApi } from '@/services/api'
export const formProduct: ISchema = {
type: 'object',
properties: {
name: {
type: 'string',
'x-component': 'ModalSearch',
'x-component-props': {
placeholder: '搜索',
align: 'flex-left',
},
},
[FORM_FILTER_PATH]: {
type: 'object',
'x-component': 'flex-layout',
'x-component-props': {
rowStyle: {
flexWrap: 'nowrap',
style: {
marginRight: 0
}
},
colStyle: {
marginTop: 20,
},
},
properties: {
customerCategoryId: {
type: 'string',
"x-component": 'SearchSelect',
"x-component-props": {
placeholder: '请选择品类',
className: 'fixed-ant-selected-down', // 该类强制将显示的下拉框出现在select下, 只有这里出现问题, ??
fetchSearch: PublicApi.getProductSelectGetSelectCategory,
style: {
width: 160
}
}
},
brandId: {
type: 'string',
"x-component": 'SearchSelect',
"x-component-props": {
placeholder: '请选择品牌',
fetchSearch: PublicApi.getProductSelectGetSelectPlatformBrand,
style: {
width: 160
}
}
},
submit: {
"x-component": 'Submit',
"x-mega-props": {
span: 1
},
"x-component-props": {
children: '查询'
}
}
}
}
}
}
export const basicSchema: ISchema = {
type: 'object',
properties: {
name: {
type: 'string',
'x-component': 'Search',
'x-component-props': {
placeholder: '搜索',
align: 'flex-left',
},
},
}
}
@import "../../../../../../global//styles/utils.less";
@import "../../common.less";
.selectBtn {
display: block;
width: 100%;
background-color: #FAFBFC;
border: 1px dashed #D8DDE6;
}
.banner {
&-box {
margin-bottom: 16px;
:global {
.ant-upload {
width: 100%;
}
}
&-label {
font-size: 12px;
color: #91959B;
margin-bottom: 8px;
}
&-icon {
height: 96px;
background-color: #FAFBFC;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
position: relative;
overflow: hidden;
&>img {
width: 100%;
}
&-add {
width: 24px;
height: 24px;
}
&:hover {
.banner-box-icon-cover {
display: block;
}
}
&-cover {
position: absolute;
height: 100%;
width: 100%;
background-color: rgba(0, 0, 0, .1);
display: none;
z-index: 1;
&-delete {
position: absolute;
right: 10px;
top: 10px;
font-size: 20px;
color: #fff;
}
&-bottom {
cursor: pointer;
position: absolute;
height: 24px;
line-height: 24px;
text-align: center;
background-color: rgba(0, 0, 0, 0.24);
font-size: 12px;
color: #fff;
width: 100%;
bottom: 0;
left: 0;
}
}
}
}
&-record {
&-shop {
height: 56px;
border: 1px solid #EDEEEF;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
padding: 0 8px;
img {
width: 40px;
height: 40px;
margin-right: 8px;
}
span {
flex: 1;
color: #303133;
font-size: 12px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
&-integral {
height: 56px;
border: 1px solid #EDEEEF;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
padding: 0 8px;
img {
width: 40px;
height: 40px;
margin-right: 8px;
}
&-right {
flex: 1;
display: flex;
flex-direction: column;
width: calc(100% - 80px);
&-top {
flex: 1;
color: #303133;
font-size: 12px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
&-bottom {
flex: 1;
color: #EA8000;
font-size: 12px;
}
}
}
&-activity {
height: 56px;
border: 1px solid #EDEEEF;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
padding: 0 8px;
position: relative;
img {
width: 40px;
height: 40px;
border-radius: 4px;
margin-right: 8px;
}
&-right {
flex: 1;
display: flex;
flex-direction: column;
font-size: 12px;
width: calc(100% - 80px);
&-top {
flex: 1;
color: #303133;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
&-bottom {
flex: 1;
color: #91959B;
}
}
&-tag {
position: absolute;
right: 0;
top: -3px;
}
}
&-commodity {
&-box {
margin-bottom: 16px;
&-label {
font-size: 12px;
color: #91959B;
margin-bottom: 8px;
}
}
&-detail {
height: 80px;
border: 1px solid #F7F8FA;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
padding: 6px 8px;
margin-bottom: 16px;
position: relative;
overflow: hidden;
img {
height: 60px;
width: 60px;
margin-right: 10px;
}
&-right {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
height: 100%;
&-title {
color: #303133;
font-size: 12px;
word-break: break-all;
overflow: hidden; // 超出的文本隐藏
text-overflow: ellipsis;
display: -webkit-box; // 将对象作为弹性伸缩盒子模型显示。
-webkit-box-orient: vertical; //从上到下垂直排列子元素(设置伸缩盒子的子元素排列方式)
-webkit-line-clamp: 2; // 结合上面两个属性,表示显示的行数。
}
&-price {
color: #D32F2F;
font-size: 14px;
}
}
}
&-activityList {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
margin-bottom: 8px;
img {
width: 24px;
height: 24px;
}
.uploadPreview {
border: 1px solid #EBECF0;
&-name {
flex: 1;
font-size: 12px;
color: #303133;
margin: 0 8px;
word-break: break-all;
overflow: hidden; // 超出的文本隐藏
text-overflow: ellipsis;
}
}
}
}
}
@import "../../common.less";
.banner {
&-box {
margin-bottom: 16px;
:global {
.ant-upload {
width: 100%;
}
}
&-label {
font-size: 12px;
color: #91959B;
margin-bottom: 8px;
}
&-icon {
height: 96px;
background-color: #FAFBFC;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
position: relative;
overflow: hidden;
&>img {
width: 100%;
}
&-add {
width: 24px;
height: 24px;
}
&:hover {
.banner-box-icon-cover {
display: block;
}
}
&-cover {
position: absolute;
height: 100%;
width: 100%;
background-color: rgba(0, 0, 0, .1);
display: none;
z-index: 1;
&-delete {
position: absolute;
right: 10px;
top: 10px;
font-size: 20px;
color: #fff;
}
&-bottom {
position: absolute;
height: 24px;
line-height: 24px;
text-align: center;
background-color: rgba(0, 0, 0, 0.24);
font-size: 12px;
color: #fff;
width: 100%;
bottom: 0;
left: 0;
}
}
}
}
&-record {
&-shop {
height: 56px;
border: 1px solid #EDEEEF;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
padding: 0 8px;
img {
width: 40px;
height: 40px;
margin-right: 8px;
}
span {
flex: 1;
color: #303133;
font-size: 12px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
&-integral {
height: 56px;
border: 1px solid #EDEEEF;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
padding: 0 8px;
img {
width: 40px;
height: 40px;
margin-right: 8px;
}
&-right {
flex: 1;
display: flex;
flex-direction: column;
&-top {
flex: 1;
color: #303133;
font-size: 12px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
&-bottom {
flex: 1;
color: #EA8000;
font-size: 12px;
}
}
}
&-activity {
height: 56px;
border: 1px solid #EDEEEF;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
padding: 0 8px;
position: relative;
img {
width: 40px;
height: 40px;
border-radius: 4px;
margin-right: 8px;
}
&-right {
flex: 1;
display: flex;
flex-direction: column;
font-size: 12px;
&-top {
flex: 1;
color: #303133;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
&-bottom {
flex: 1;
color: #91959B;
}
}
&-tag{
position: absolute;
right: 0;
top: -3px;
}
}
}
}
@import "../../../../../../global//styles/utils.less";
@import "../../common.less";
.selectBtn {
display: block;
width: 100%;
background-color: #FAFBFC;
border: 1px dashed #D8DDE6;
}
.banner {
&-box {
margin-bottom: 16px;
:global {
.ant-upload {
width: 100%;
}
}
&-label {
font-size: 12px;
color: #91959B;
margin-bottom: 8px;
}
&-icon {
height: 96px;
background-color: #FAFBFC;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
position: relative;
overflow: hidden;
&>img {
width: 100%;
}
&-add {
width: 24px;
height: 24px;
}
&:hover {
.banner-box-icon-cover {
display: block;
}
}
&-cover {
position: absolute;
height: 100%;
width: 100%;
background-color: rgba(0, 0, 0, .1);
display: none;
z-index: 1;
&-delete {
position: absolute;
right: 10px;
top: 10px;
font-size: 20px;
color: #fff;
}
&-bottom {
cursor: pointer;
position: absolute;
height: 24px;
line-height: 24px;
text-align: center;
background-color: rgba(0, 0, 0, 0.24);
font-size: 12px;
color: #fff;
width: 100%;
bottom: 0;
left: 0;
}
}
.uploadPreview {
border: 1px solid #EBECF0;
}
}
}
import React, { useState } from 'react'
import { PlusOutlined } from '@ant-design/icons'
import ImageBox from '@/components/ImageBox'
import { DeleteOutlined } from '@ant-design/icons'
import { changeProps } from '@lingxi-disign/core'
import UploadImage from '@/components/UploadImage'
import arrowRightIcon from '@/assets/icons/arrow_right.png'
import arrowLeftIcon from '@/assets/icons/arrow_left.png'
import uploadImgIcon from '@/assets/icons/upload_img_icon.svg'
import styles from './index.less'
interface BannerPropsType {
......@@ -12,64 +10,48 @@ interface BannerPropsType {
}
const HeadBackground: React.FC<BannerPropsType> = (props) => {
const { backdrop } = props
const [expandState, setExpandState] = useState<boolean>(true)
const handleBackdropChange = (url: string) => {
const _onChangeImg = (url: any) => {
changeProps({
props:Object.assign({ ...props }, { backdrop: url })
})
props: Object.assign({ ...props }, { backdrop: url })
});
}
return (
<div className={styles.setting}>
{/* <div className={styles.hideModule}>
<Checkbox checked={!visible} onChange={handleHideChange}>隐藏整个模块</Checkbox>
</div> */}
<div className={styles.setting_line}>
<div className={styles.setting_line_main}>
<div className={styles.setting_line_name} >
<div style={{ flex: 1 }} onClick={() => setExpandState(!expandState)}>
{
expandState ? <img className={styles.icon} src={arrowLeftIcon} /> : <img className={styles.icon} src={arrowRightIcon} />
}
<span>背景图</span>
<div className={styles['banner']}>
<div className={styles['banner-box']}>
<div className={styles['banner-box-label']}>背景图</div>
{backdrop ? (
<div className={styles['banner-box-icon']}>
<img src={backdrop} />
<div className={styles['banner-box-icon-cover']}>
<UploadImage
onChange={(url) => { _onChangeImg(url) }}
listType="text"
>
<div className={styles['banner-box-icon-cover-bottom']}>
添加图像
</div>
</UploadImage>
<DeleteOutlined className={styles['banner-box-icon-cover-delete']} onClick={() => { _onChangeImg('') }} />
</div>
</div>
{
expandState && (
<div className={styles.setting_line_addItem}>
<div className={styles.setting_line_addItem_line}>
<div className={styles.setting_line_addItem_line_label}>名称:</div>
<div className={styles.setting_line_addItem_line_brief}>
背景图
</div>
</div>
<div className={styles.setting_line_addItem_line}>
<div className={styles.setting_line_addItem_line_label}>图片:</div>
<div className={styles.setting_line_addItem_line_brief}>
<div className={styles.uploadIconWrap}>
<ImageBox className={styles.uploadPreview} width={90} height={90} imgUrl={backdrop} />
<UploadImage
fileMaxSize={200}
onChange={(url) => handleBackdropChange(url)}
listType="text"
>
<div className={styles.uploadIconBtn}>
<PlusOutlined className={styles.uploadIconBtnIcon} />
<span>点击上传</span>
</div>
</UploadImage>
</div>
<label className={styles.uploadIconTip}>图片建议尺寸:1920*750</label>
<label className={styles.uploadIconTip}>大小:不超过200k</label>
</div>
) : (
<UploadImage
onChange={(url) => { _onChangeImg(url) }}
listType="text"
>
<div className={styles['banner-box-icon']}>
<img src={uploadImgIcon} className={styles['banner-box-icon-add']} />
<div className={styles['banner-box-icon-cover']}>
<div className={styles['banner-box-icon-cover-bottom']}>
添加图像
</div>
</div>
)
}
</div>
</div>
</UploadImage>
)}
</div>
</div>
)
......
import React from 'react'
import { numFormat, priceFormat } from '@/utils/numberFomat'
import ImageBox from '@/components/ImageBox'
const showMainPic = (mainPic: string) => <ImageBox width={32} height={32} imgUrl={mainPic} />
export const promptCommodityColumn = [
{
title: 'ID',
dataIndex: 'id',
key: 'id',
width: 80,
},
{
title: "商品图片",
dataIndex: "mainPic",
render: (mainPic: string) => showMainPic(mainPic)
},
{
title: "商品名称",
dataIndex: "name",
width: 280,
ellipsis: true,
// eslint-disable-next-line react/display-name
render: (name: any) => <div dangerouslySetInnerHTML={{ __html: name }}></div>
},
{
title: "品类",
render: (_, record) => record.customerCategory ? record.customerCategory.name : "",
ellipsis: true,
},
{
title: "品牌",
render: (_, record) => record.brand ? record.brand.name : "",
ellipsis: true,
},
{
title: "价格",
dataIndex: "min",
render: (_, record) => ${priceFormat(record.min)}`
},
]
export default promptCommodityColumn
import { ISchema } from '@formily/antd'
import { FORM_FILTER_PATH } from '@/formSchema/const'
import { PublicApi } from '@/services/api'
export const formProduct: ISchema = {
type: 'object',
properties: {
name: {
type: 'string',
'x-component': 'ModalSearch',
'x-component-props': {
placeholder: '搜索',
align: 'flex-left',
},
},
[FORM_FILTER_PATH]: {
type: 'object',
'x-component': 'flex-layout',
'x-component-props': {
rowStyle: {
flexWrap: 'nowrap',
style: {
marginRight: 0
}
},
colStyle: {
marginTop: 20,
},
},
properties: {
customerCategoryId: {
type: 'string',
"x-component": 'SearchSelect',
"x-component-props": {
placeholder: '请选择品类',
className: 'fixed-ant-selected-down', // 该类强制将显示的下拉框出现在select下, 只有这里出现问题, ??
queryParams: {
storeId: 2,
},
fetchSearch: PublicApi.getProductSelectGetSelectCategory,
style: {
width: 160
}
}
},
brandId: {
type: 'string',
"x-component": 'SearchSelect',
"x-component-props": {
placeholder: '请选择品牌',
queryParams: {
storeId: 2,
},
fetchSearch: PublicApi.getSearchMobileShopStoreGetBrand,
style: {
width: 160
}
}
},
submit: {
"x-component": 'Submit',
"x-mega-props": {
span: 1
},
"x-component-props": {
children: '查询'
}
}
}
}
}
}
export const basicSchema: ISchema = {
type: 'object',
properties: {
name: {
type: 'string',
'x-component': 'Search',
'x-component-props': {
placeholder: '搜索',
align: 'flex-left',
},
},
}
}
@import "../../../../../../global/styles/utils.less";
@import "../../common.less";
.selectBtn {
display: block;
width: 100%;
background-color: #FAFBFC;
border: 1px dashed #D8DDE6;
.RecommendCommodity {
&-box {
margin-bottom: 16px;
&-label {
font-size: 12px;
color: #91959B;
margin-bottom: 8px;
}
}
}
.uploadPreview {
border: 1px solid #EBECF0;
.banner {
&-record {
&-commodity {
&-box {
margin-bottom: 16px;
&-label {
font-size: 12px;
color: #91959B;
margin-bottom: 8px;
}
}
&-detail {
height: 80px;
border: 1px solid #F7F8FA;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
padding: 6px 8px;
margin-bottom: 16px;
position: relative;
overflow: hidden;
&:hover {
.banner-record-commodity-detail-mask {
display: block;
}
}
&-mask {
position: absolute;
width: 100%;
height: 100%;
display: none;
background-color: rgba(0, 0, 0, 0.24);
transition: 0.5s all;
z-index: 6;
&-delete {
position: absolute;
right: 10px;
top: 10px;
font-size: 20px;
color: #fff;
cursor: pointer;
}
}
img {
height: 60px;
width: 60px;
margin-right: 10px;
}
&-right {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
height: 100%;
&-title {
color: #303133;
font-size: 12px;
word-break: break-all;
overflow: hidden; // 超出的文本隐藏
text-overflow: ellipsis;
display: -webkit-box; // 将对象作为弹性伸缩盒子模型显示。
-webkit-box-orient: vertical; //从上到下垂直排列子元素(设置伸缩盒子的子元素排列方式)
-webkit-line-clamp: 2; // 结合上面两个属性,表示显示的行数。
}
&-price {
color: #D32F2F;
font-size: 14px;
}
}
}
&-activityList {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
margin-bottom: 8px;
img {
width: 24px;
height: 24px;
}
&-name {
flex: 1;
font-size: 12px;
color: #303133;
margin: 0 8px;
word-break: break-all;
overflow: hidden; // 超出的文本隐藏
text-overflow: ellipsis;
}
}
}
}
}
......@@ -8,39 +8,44 @@ import RecommendCommodity from './components/recommendCommodity'
import BottomNavigation from './components/bottomNavigation'
import MobileChannelGoods from './components/channelGoods'
import MobileChannelInformation from './components/channelInformation'
import CardNavItem from './components/cardNavItem'
import styles from './index.less'
interface PropsSettingsPropsType {
selectedInfo: SelectedInfoType | undefined,
shopId: number,
}
const PropsSettings: React.FC<PropsSettingsPropsType> = (props) => {
const { selectedInfo } = props
const { selectedInfo, } = props
const renderSettingItem = () => {
const { props: initProps, propsConfig } = selectedInfo || {};
const _props = { ...initProps, ...props, selectedKey: selectedInfo?.selectedKey }
const componentType = propsConfig?.componentType
if (componentType) {
switch (componentType.type) {
case PROPS_SETTING_TYPES.mobileShopHeaderNav:
return <HeadBackground {...initProps} />
return <HeadBackground {..._props} />
case PROPS_SETTING_TYPES.mobileShopCommodity:
return <RecommendCommodity {...initProps} />
return <RecommendCommodity {..._props} />
case PROPS_SETTING_TYPES.mobileHeaderNav:
return <HeaderNav {...initProps} />
case PROPS_SETTING_TYPES.mobileBanner:
return <Banner {...initProps} />
return <HeaderNav {..._props} />
case PROPS_SETTING_TYPES.bannerItems:
return <Banner {..._props} />
case "mobileChannelBanner":
return <Banner {...initProps} type="channel" />
return <Banner {..._props} type="channel" />
case PROPS_SETTING_TYPES.mobileQuickNav:
return <QuickNav {...initProps} />
return <QuickNav {..._props} />
case PROPS_SETTING_TYPES.mobileChannelGoodsCard:
return <MobileChannelGoods {...initProps} />
return <MobileChannelGoods {..._props} />
case PROPS_SETTING_TYPES.moibileChannelInformation:
return <MobileChannelInformation {...initProps} />
return <MobileChannelInformation {..._props} />
case PROPS_SETTING_TYPES.mobileBottomNavigation:
return <BottomNavigation {...initProps} />
return <BottomNavigation {..._props} />
case PROPS_SETTING_TYPES.mobileNavCardNavItem:
return <CardNavItem {..._props} />
default:
return null
}
......
......@@ -11,8 +11,9 @@
display: flex;
align-items: center;
justify-content: center;
width: 184px;
height: 138px;
flex: 1;
// width: 184px;
// height: 138px;
border: 1px solid #E4E6EB;
margin: 0 12px;
margin-bottom: 24px;
......
import React, { useState } from 'react'
import cx from 'classnames'
import { SelectedInfoType, changeProps, PROPS_SETTING_TYPES } from '@lingxi-disign/core'
import GoodsCardTitleStyle from './components/GoodsCardTitleStyle'
import styles from './index.less'
import React, { useState } from 'react';
import cx from 'classnames';
import { SelectedInfoType, changeProps } from '@lingxi-disign/core';
import styles from './index.less';
interface StyleSettingsPropsType {
selectedInfo: SelectedInfoType | undefined,
}
const StyleSettings: React.FC<StyleSettingsPropsType> = ({ selectedInfo }) => {
const { props: selectProps } = selectedInfo || {}
const [ selectKey, setSelectKey ] = useState<number>(selectProps.styleTheme)
const { props: selectProps } = selectedInfo || {};
const [ selectKey, setSelectKey ] = useState<number>(selectProps.styleTheme);
/**
* 更换样式模板
......@@ -18,40 +17,36 @@ const StyleSettings: React.FC<StyleSettingsPropsType> = ({ selectedInfo }) => {
*/
const handleChangeStyleTheme = (key: number) => {
if(selectKey !== key) {
setSelectKey(key)
setSelectKey(key);
changeProps({
props: Object.assign({ ...selectProps }, { styleTheme: key })
})
});
}
}
const renderSettingItem = () => {
const { props: initProps, propsConfig } = selectedInfo || {};
const componentType = propsConfig?.componentType
if (componentType) {
switch (componentType.type) {
case PROPS_SETTING_TYPES.mobileHeaderNav:
return (selectProps && selectProps.stylesThemeList) && selectProps.stylesThemeList.map(item => (
<div className={cx(styles.styleItem, selectKey === item.key ? styles.active : {})} key={item.key} onClick={() => handleChangeStyleTheme(item.key)}>
<img className={styles.themeImg} src={item.img} title={item.key} />
</div>
))
case PROPS_SETTING_TYPES.mobileChannelGoodsCard:
return <GoodsCardTitleStyle {...initProps} />
default:
return null
}
}
}
};
return (
<div className={styles.styleSettings}>
<div className={styles.styleList}>
{renderSettingItem()}
{
(selectProps && selectProps.stylesthemelist) && selectProps.stylesthemelist.map(item => (
<div
className={cx(styles.styleItem, selectKey === item.key ? styles.active : {})}
key={item.key}
// style={{ width: item.width || 184, height: item.height || 138 }}
onClick={() => handleChangeStyleTheme(item.key)}
>
<img
className={styles.themeImg}
src={item.img}
title={item.key}
style={{ width: item.width || 152, height: item.height || 105 }}
/>
</div>
))
}
</div>
</div>
)
}
);
};
export default StyleSettings
export default StyleSettings;
import { PROPS_SETTING_TYPES } from '@lingxi-disign/core'
import { PROPS_SETTING_TYPES, PageConfigType } from '@lingxi-disign/core'
import categoryNavTemplateDefault from './img/category_template_default.png'
export const defaultConfig: PageConfigType = {
'0': {
componentName: 'MallLayout',
props: {
style: {
"width": "100%",
"minHeight": "100%",
"background": "#F7F8FA",
"overflowX": "hidden",
"paddingBottom": "50px",
}
},
childNodes: ['1', '2', '4', '6']
},
'1': {
componentName: 'MobileShopHeader',
props: {
shopInfo: '${shopInfo}',
backdrop: '${backdrop}',
},
title: '背景图'
},
'2': {
title: '分类导航',
componentName: 'MobileNavCard',
props: {
style: {
margin: '8px',
},
stylesthemelist: [
{
key: 0,
width: 320,
height: 148,
img: categoryNavTemplateDefault,
},
]
},
childNodes: ['3'],
childComponentName: 'MobileNavCard.NavItem',
addBtnText: '添加导航',
},
'3': {
loop: '${navList}',
title: '${item.name}',
componentName: 'MobileNavCard.NavItem',
props: {
id: '${item.id}',
name: '${item.name}',
type: '${item.type}',
url: '${item.url}',
icon: '${item.icon}',
empty: false,
},
},
'4': {
title: '广告图',
componentName: 'Banner',
props: {
style: {
margin: '8px',
},
},
childNodes: ['5'],
childComponentName: 'Banner.Items',
addBtnText: '添加广告',
},
'5': {
loop: '${advert}',
title: '${item.name}',
componentName: 'Banner.Items',
props: {
id: '${item.id}',
type: '${item.type}',
img: '${item.img}',
name: '${item.name}',
isnull: false,
},
},
'6': {
componentName: 'MobileShopCommodity',
title: '推荐商品',
props: {},
childNodes: ['7'],
childComponentName: 'MobileShopCommodity.Item',
addBtnText: '添加商品区',
},
'7': {
loop: '${commodityList}',
componentName: 'MobileShopCommodity.Item',
title: '${item.title}',
props: {
title: '${item.title}',
categoryId: '${item.categoryId}',
idList: '${item.idList}',
manageWay: '${item.manageWay}',
dataList: '${item.dataList}',
num: '${item.num}',
},
}
}
export const mallLayoutConfig = {
key: "0",
......
......@@ -6,13 +6,16 @@
* @Description app店铺主页装修
*/
import React, { useEffect, useState } from 'react'
import { BrickProvider } from '@lingxi-disign/react';
import { BrickProvider, resolveMappingPageConfig } from '@lingxi-disign/react';
import { Helmet } from 'umi'
import ToolBar from '../../editor/components/toolBar'
import MobileDesignPanel from '../../editor/components/MobileDesignPanel'
import MobileClientEditLeft from '../../editor/components/mobileClientEditLeft'
import AllComponents from '../../editor/components/ComponentsPreview'
import { message } from 'antd'
import config from '../../editor/configs'
import {
defaultConfig,
mallLayoutConfig,
divWrap,
mobileShopHeaderNav,
......@@ -23,7 +26,7 @@ import {
import Loading from '../../editor/components/Loading'
import { PublicApi } from '@/services/api'
import { LAYOUT_TYPE } from '@/constants'
import { GetTemplateAdornAppStoreFindResponse, GetTemplateWebMemberShopWebFindByMemberIdAndRoleIdResponse } from '@/services/TemplateApi'
import { GetTemplateAdornAppStoreFindResponse } from '@/services/TemplateV2Api'
// import { GlobalConfig } from '@/global/config'
import MobileSettingPanel from '../../editor/mobileSettingPanel'
import { getAuth } from '@/utils/auth'
......@@ -90,19 +93,19 @@ const mobileShopTempleteEdit: React.FC<ShopPreviewPropsType> = (props) => {
/**
* 获取app店铺装修信息
*/
const getAppShopConfig = (): Promise<GetTemplateAdornAppStoreFindResponse | null> => {
const getAppShopConfig = (): Promise<any> => {
return new Promise((resolve, reject) => {
const param: any = {
templateId: id
}
PublicApi.getTemplateAdornAppStoreFind(param, { headers }).then(res => {
if(res.code === 1000) {
resolve(res.data)
if(res.code === 1000 && res.data) {
resolve(res.data.adornContent)
} else {
reject(res)
resolve({})
}
}).catch((eror) => {
reject(eror)
resolve({})
})
})
}
......@@ -158,50 +161,77 @@ const mobileShopTempleteEdit: React.FC<ShopPreviewPropsType> = (props) => {
})
}
const _getListByIds = (ids: number[], list: any[]) => {
const result: any = []
list && list.forEach((item) => {
if (ids.includes(item.id)) {
result.push(item)
}
})
return result
}
const _getCommodityList = async (list: any[]) => {
let listRes: any = []
if (list && Array.isArray(list) && list.length > 0) {
let commodityIds: any = []
const commodityResList: any[] = []
list.forEach((detailsItem) => {
if (commodityIds.length === 0) {
commodityIds = [...detailsItem.idList]
} else {
commodityIds = [...commodityIds, ...detailsItem.idList]
}
})
if (commodityIds && commodityIds.length > 0) {
const param: any = {
idInList: commodityIds,
shopId: shopId,
current: 1,
pageSize: 80
}
const res = await PublicApi.getMarketingAdornGoodsListAdorn(param)
let allCommodityList: any[] = []
if (res.code === 1000) {
allCommodityList = res.data.data
list.forEach((detailsItem) => {
commodityResList.push({
...detailsItem,
dataList: _getListByIds(detailsItem.idList, allCommodityList)
})
})
listRes = commodityResList
}
}
}
return listRes
}
const getComponentsConfig = async () => {
try {
const appConfig = await getAppShopConfig()
//店铺信息
const shopInfo = await fetchShopInfo(shopId)
mobileShopHeaderNav[mobileShopHeaderNav.key].props.shopInfo = shopInfo
if(appConfig?.backdropBO) {
mobileShopHeaderNav[mobileShopHeaderNav.key].props.backdrop = appConfig?.backdropBO.backdrop
const allState: any = {
shopInfo: shopInfo,
navList: appConfig?.navList ? appConfig?.navList.details : [],
advert: appConfig?.advert ? appConfig?.advert.details : [],
commodityList: []
}
mobileBanner[mobileBanner.key].props.storeId = shopInfo.id
if(appConfig?.advertBO) {
mobileBanner[mobileBanner.key].props.dataList = appConfig?.advertBO.advertDetailsBOList
if (appConfig?.commodity) {
allState.commodityList = await _getCommodityList(appConfig.commodity?.details)
}
if(appConfig?.functionBO) {
mobileQuickNav[mobileQuickNav.key].props.dataList = appConfig?.functionBO.functionDetailsBO
if (appConfig?.header) {
allState.backdrop = appConfig?.header.details.backdrop
}
if(appConfig?.productBO) {
const dataList = await fetchCategoryByCommodityId(appConfig.productBO.productIdList)
mobileShopCommodityList[mobileShopCommodityList.key].props = {
storeId: shopInfo.id,
title: appConfig.productBO.title,
productIdList: appConfig.productBO.productIdList || [],
dataList,
}
} else {
mobileShopCommodityList[mobileShopCommodityList.key].props.storeId = shopInfo.id
mobileShopCommodityList[mobileShopCommodityList.key].props.title = '热销商品'
mobileShopCommodityList[mobileShopCommodityList.key].props.productIdList = []
}
const config = {
...mallLayoutConfig,
...mobileShopHeaderNav,
...divWrap,
...mobileBanner,
...mobileQuickNav,
...mobileShopCommodityList,
}
setComponentConfigs(config)
const finalConfig = resolveMappingPageConfig(defaultConfig, allState)
setComponentConfigs(finalConfig)
setLoading(false)
} catch (error) {
console.log(error)
......@@ -213,16 +243,19 @@ const mobileShopTempleteEdit: React.FC<ShopPreviewPropsType> = (props) => {
<BrickProvider
config={config}
>
<Helmet>
<title>店铺装修-店铺主页</title>
</Helmet>
<div className={styles['wrapper']}>
<ToolBar type={1} title="店铺主页" showActions={true} layoutType={LAYOUT_TYPE.shop} templateId={id} />
<div className={styles['content']}>
<AllComponents />
<MobileClientEditLeft />
<div className={styles['app-wrapper']}>
<div className={styles['app-canvas-container']}>
<MobileDesignPanel onlyEidt theme={theme} pageConfig={componentConfigs} />
</div>
</div>
<MobileSettingPanel />
<MobileSettingPanel shopId={shopId} />
</div>
</div>
</BrickProvider>
......
This diff is collapsed.
import React, { useEffect, useState } from 'react'
import cx from 'classnames'
import { Button, message, Modal } from 'antd'
import { Button, message, Modal, Pagination } from 'antd'
import { StarFilled } from '@ant-design/icons'
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import credit_icon from '@/assets/imgs/credit_icon.png'
import ShopCredit from '@/components/ShopCredit'
import { PublicApi } from '@/services/api'
import { numFormat } from '@/utils/numberFomat'
......@@ -14,73 +13,34 @@ import styles from './index.less'
const Commodity: React.FC = () => {
const [list, setList] = useState([])
const [buyLoading, setBuyLoading] = useState<boolean>(false)
// const [current, setCurrent] = useState<number>(1)
// const [pageSize, setPageSize] = useState<number>(10)
// const [totalCount, setTotalCount] = useState<number>(0)
const [current, setCurrent] = useState<number>(1)
const [pageSize, setPageSize] = useState<number>(10)
const [totalCount, setTotalCount] = useState<number>(0)
useEffect(() => {
fetchCollectCommodityList()
getShopCommodityCollectList()
}, [])
/**
* 获取收藏的商品列表
*/
const fetchCollectCommodityList = async () => {
// const param: any = {
// current,
// pageSize
// }
const shopCommodityCollectList = await getShopCommodityCollectList()
const channelCommodityCollectList = await getChannelCommodityCollectList()
setList([...shopCommodityCollectList, ...channelCommodityCollectList])
// PublicApi.getSearchShopCommodityCollectGetCommodityCollectList(param).then(res => {
// if (res.code === 1000) {
// setList(res.data.data)
// setTotalCount(res.data.totalCount)
// }
// })
}
const getShopCommodityCollectList = (): Promise<any> => {
return new Promise((resolve) => {
PublicApi.getSearchShopCommodityCollectGetCommodityCollectList().then((res) => {
if (res.code === 1000) {
resolve(res.data)
} else {
resolve([])
}
}).catch(() => {
resolve([])
})
})
}
const getChannelCommodityCollectList = (): Promise<any> => {
return new Promise((resolve) => {
PublicApi.getSearchShopCommodityCollectChannelGetCommodityCollectList().then((res: any) => {
if (res.code === 1000) {
if (!res.data) return
const result = res.data.map((item) => {
return {
...item,
isChannel: true
}
})
resolve(result)
} else {
resolve([])
}
}).catch(() => {
resolve([])
})
const getShopCommodityCollectList = () => {
const params: any = {
current,
pageSize,
}
PublicApi.getSearchShopCommodityCollectGetCommodityCollectList(params).then((res) => {
if (res.code === 1000) {
setList(res.data.data)
setTotalCount(res.data.totalCount)
}
})
}
const linkToDetail = (detail) => {
if (detail.isPublish) {
const el = document.createElement('a')
if (detail.isChannel) {
if (detail.channelMemberId) {
switch (detail.commodity.priceType) {
case 1:
case 2:
......@@ -145,9 +105,9 @@ const Commodity: React.FC = () => {
}
}
// const handleChange = (page) => {
// setCurrent(page)
// }
const handleChange = (page) => {
setCurrent(page)
}
const handleCancelCollect = (detail) => {
Modal.confirm({
......@@ -161,7 +121,7 @@ const Commodity: React.FC = () => {
}
let postFn
if (detail.isChannel) {
if (detail.channelMemberId) {
postFn = PublicApi.postSearchShopCommodityCollectChannelDeleteCommodityCollectById
} else {
postFn = PublicApi.postSearchShopCommodityCollectDeleteCommodityCollectById
......@@ -169,7 +129,7 @@ const Commodity: React.FC = () => {
postFn && postFn (param).then(res => {
if (res.code === 1000) {
fetchCollectCommodityList()
getShopCommodityCollectList()
resolve(true)
} else {
reject()
......@@ -228,13 +188,9 @@ const Commodity: React.FC = () => {
))
}
</div>
{/* {
totalCount > pageSize && (
<div className={styles.pagination_wrap}>
<Pagination showSizeChanger={false} current={current} total={totalCount} pageSize={pageSize} onChange={handleChange} />
</div>
)
} */}
<div className={styles.pagination_wrap}>
<Pagination showSizeChanger={false} current={current} total={totalCount} pageSize={pageSize} onChange={handleChange} />
</div>
</PageHeaderWrapper>
)
}
......
......@@ -10,7 +10,7 @@
--category_content_title_text: #303133;
--category_content_title_text_hover: #00B37A;
--category_content_sub_title_text: #606266;
overflow-x: hidden;
}
// 渠道科技类模板
......@@ -24,6 +24,7 @@
--category_content_title_text: #303133;
--category_content_title_text_hover: #00B37A;
--category_content_sub_title_text: #606266;
overflow-x: hidden;
}
// 店铺科技类模板颜色配置
......@@ -37,4 +38,5 @@
--category_content_title_text: #303133;
--category_content_title_text_hover: #00B37A;
--category_content_sub_title_text: #606266;
overflow-x: hidden;
}
......@@ -7,7 +7,7 @@ const tokenList = [
{ name: 'Template', token: '7ec923520215c7e2f771867cb4d29cafbf823daf0fb2d3d9fa70b57a523c8bfb', categoryIds: [0], }, // 店铺模板服务
{ name: 'Pay', token: '34608cd33222b1650795459d73b8eb0b260eb92cf5e8d1e646f85a4875e36f05', categoryIds: [0], }, // 支付服务
{ name: 'Search', token: 'ca19f532efba91f7773cbfbd526b798c6ac83df670071e97d72c50dca1d53a48', categoryIds: [0], }, // 搜索服务
{ name: 'SearchV2', token: 'f3e6ec26764f54d06ba33f487ff42d7debeaef397e51dc395040447737eb2e66', categoryIds: [9367, 9370], }, // 搜索服务V2
{ name: 'SearchV2', token: 'f3e6ec26764f54d06ba33f487ff42d7debeaef397e51dc395040447737eb2e66', categoryIds: [0], }, // 搜索服务V2
{ name: 'Order', token: 'fcebd7d4c6b6930790e844725f348280c2227b8044ae8a16bf56ead2720ec1b6', categoryIds: [0], }, //订单服务
{ name: 'Settle', token: 'fffbeeaaa198c285955997c606bc279fc6950fea118580c786f2c73eecccaa6a', categoryIds: [0], }, //结算服务
{ name: 'AfterService', token: '39db719680bf1b3db21bc1deda933cde16d17559e9676bf848ec96c1320e68df', categoryIds: [0], }, // '售后服务'
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment