lists.html 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504
  1. {extend name="base"/}
  2. {block name="resources"}
  3. <link rel="stylesheet" href="STATIC_EXT/colorPicker/css/colorpicker.css" />
  4. <link rel="stylesheet" href="SHOP_CSS/goods_service.css" />
  5. {/block}
  6. {block name="main"}
  7. <!-- 搜索框 -->
  8. <div class="single-filter-box">
  9. <button class="layui-btn" onclick="addService()">添加商品服务</button>
  10. <div class="layui-form">
  11. <div class="layui-input-inline">
  12. <input type="text" name="search_keys" placeholder="请输入商品服务名称" autocomplete="off" class="layui-input">
  13. <button type="button" class="layui-btn layui-btn-primary" lay-filter="search" lay-submit>
  14. <i class="layui-icon">&#xe615;</i>
  15. </button>
  16. </div>
  17. </div>
  18. </div>
  19. <div id="table_app">
  20. <!-- 列表 -->
  21. <table id="attr_class_list" lay-filter="attr_class_list"></table>
  22. </div>
  23. <!-- 操作 -->
  24. <script type="text/html" id="operation">
  25. <div class="table-btn">
  26. <a class="layui-btn" lay-event="edit">编辑</a>
  27. <a class="layui-btn" lay-event="delete">删除</a>
  28. </div>
  29. </script>
  30. <script type="text/html" id="addService">
  31. <div class="layui-form" id="app">
  32. <div class="layui-form-item">
  33. <label class="layui-form-label mid"><span class="required">*</span>商品服务:</label>
  34. <div class="layui-input-block">
  35. <input name="service_name" type="text" placeholder="请输入商品服务名称" lay-verify="required" class="layui-input len-mid" maxlength="20">
  36. </div>
  37. </div>
  38. <div class="layui-form-item">
  39. <label class="layui-form-label mid">描述:</label>
  40. <div class="layui-input-block">
  41. <textarea name="desc" class="layui-textarea len-mid" maxlength="150"></textarea>
  42. </div>
  43. </div>
  44. <div class="layui-form-item">
  45. <label class="layui-form-label mid">图标:</label>
  46. <div class="layui-input-block img-upload">
  47. <div class="img-icon-box">
  48. <img-icon-upload :data="{data:myData}"></img-icon-upload>
  49. <div class="action-box">
  50. <div class="action" v-if="myData.iconType == 'icon' && myData.icon" title="风格" @click="iconStyle($event)"><i class="iconfont iconpifu"></i></div>
  51. <div class="action" v-if="myData.iconType == 'icon' && myData.icon" title="背景" @click="selectColor('icon-color-' +id)" :id="'icon-color-' +id"><i class="iconfont iconyanse"></i></div>
  52. </div>
  53. </div>
  54. </div>
  55. </div>
  56. <div class="form-row mid">
  57. <button class="layui-btn" lay-submit lay-filter="save">保存</button>
  58. <button class="layui-btn layui-btn-primary" onclick="closeAttrLayer()">返回</button>
  59. </div>
  60. </div>
  61. </script>
  62. <script type="text/html" id="editService">
  63. <div class="layui-form" id="app">
  64. <div class="layui-form-item">
  65. <label class="layui-form-label mid"><span class="required">*</span>商品服务:</label>
  66. <div class="layui-input-block">
  67. <input name="service_name" type="text" value="{{ d.service_name }}" placeholder="请输入商品服务名称" lay-verify="required" class="layui-input len-mid" maxlength="20">
  68. </div>
  69. </div>
  70. <div class="layui-form-item">
  71. <label class="layui-form-label mid">描述:</label>
  72. <div class="layui-input-block">
  73. <textarea name="desc" class="layui-textarea len-mid" maxlength="150">{{ d.desc }}</textarea>
  74. </div>
  75. </div>
  76. <div class="layui-form-item">
  77. <label class="layui-form-label mid">图标:</label>
  78. <div class="layui-input-block img-upload">
  79. <div class="img-icon-box">
  80. <img-icon-upload :data="{data:myData}"></img-icon-upload>
  81. <div class="action-box">
  82. <div class="action" v-if="myData.iconType == 'icon' && myData.icon" title="风格" @click="iconStyle($event)"><i class="iconfont iconpifu"></i></div>
  83. <div class="action" v-if="myData.iconType == 'icon' && myData.icon" title="背景" @click="selectColor('icon-color-' +id)" :id="'icon-color-' +id"><i class="iconfont iconyanse"></i></div>
  84. </div>
  85. </div>
  86. </div>
  87. </div>
  88. <input type="hidden" name="id" value="{{ d.id }}">
  89. <div class="form-row mid">
  90. <button class="layui-btn" lay-submit lay-filter="edit_save">保存</button>
  91. <button class="layui-btn layui-btn-primary" onclick="closeAttrLayer()">返回</button>
  92. </div>
  93. </div>
  94. </script>
  95. {/block}
  96. {block name="script"}
  97. <script src="STATIC_JS/vue.js"></script>
  98. {include file="diy/iconfont_component"/}
  99. <script src="STATIC_EXT/colorPicker/js/colorpicker.js"></script>
  100. <script src="STATIC_EXT/diyview/js/components.js"></script>
  101. <script>
  102. var laytpl, add_attr_index = -1,
  103. form, table,vue;
  104. layui.use(['form', 'laytpl'], function() {
  105. var repeat_flag = false; //防重复标识
  106. laytpl = layui.laytpl;
  107. form = layui.form;
  108. form.render();
  109. table = new Table({
  110. elem: '#attr_class_list',
  111. url: ns.url("shop/goodsservice/lists"),
  112. cols: [
  113. [ {
  114. field: 'service_name',
  115. title: '商品服务',
  116. unresize: 'false',
  117. width: '15%'
  118. },{
  119. title: '图标',
  120. unresize: 'false',
  121. width: '15%',
  122. align: 'center',
  123. templet: function (data) {
  124. return iconHtml(data);
  125. },
  126. }, {
  127. field:'desc',
  128. unresize: 'false',
  129. title: '描述',
  130. width: '55%',
  131. templet:'<div><span title="{{d.desc}}">{{d.desc}}</span></div>'
  132. }, {
  133. title: '操作',
  134. toolbar: '#operation',
  135. unresize: 'false',
  136. align : 'right'
  137. }]
  138. ],
  139. callback: function (){
  140. }
  141. });
  142. /**
  143. * 监听工具栏操作
  144. */
  145. table.tool(function(obj) {
  146. var data = obj.data;
  147. switch (obj.event) {
  148. case 'edit':
  149. editService(data);
  150. break;
  151. case 'delete':
  152. deleteService(data.id);
  153. break;
  154. }
  155. });
  156. /**
  157. * 删除
  158. */
  159. function deleteService(id) {
  160. layer.confirm('确认删除该服务吗?', function() {
  161. $.ajax({
  162. url: ns.url("shop/goodsservice/delete"),
  163. data: {
  164. id:id
  165. },
  166. dataType: 'JSON',
  167. type: 'POST',
  168. success: function(res) {
  169. layer.msg(res.message);
  170. if (res.code == 0) {
  171. table.reload();
  172. }
  173. }
  174. });
  175. });
  176. }
  177. /**
  178. * 搜索功能
  179. */
  180. form.on('submit(search)', function(data) {
  181. table.reload({
  182. page: {
  183. curr: 1
  184. },
  185. where: data.field
  186. });
  187. });
  188. form.on('submit(save)', function(data) {
  189. if (repeat_flag) return false;
  190. repeat_flag = true;
  191. data.field.icon = JSON.stringify(vue.myData)
  192. $.ajax({
  193. url: '{:addon_url("shop/goodsservice/add")}',
  194. data: data.field,
  195. dataType: 'JSON',
  196. type: 'POST',
  197. success: function(data) {
  198. layer.msg(data.message);
  199. if (data.code == 0) {
  200. table.reload();
  201. layer.close(add_attr_index);
  202. }
  203. repeat_flag = false;
  204. }
  205. });
  206. return false;
  207. });
  208. form.on('submit(edit_save)', function(data) {
  209. if (repeat_flag) return false;
  210. repeat_flag = true;
  211. data.field.icon = JSON.stringify(vue.myData)
  212. $.ajax({
  213. url: '{:addon_url("shop/goodsservice/edit")}',
  214. data: data.field,
  215. dataType: 'JSON',
  216. type: 'POST',
  217. success: function(data) {
  218. layer.msg(data.message);
  219. if (data.code == 0) {
  220. table.reload();
  221. layer.close(add_attr_index);
  222. }
  223. repeat_flag = false;
  224. }
  225. });
  226. return false;
  227. });
  228. /**
  229. * 表单验证
  230. */
  231. form.verify({
  232. num: function(value) {
  233. if (value == '') {
  234. return;
  235. }
  236. if (value % 1 != 0) {
  237. return '排序数值必须为整数';
  238. }
  239. if (value < 0) {
  240. return '排序数值必须为大于0';
  241. }
  242. }
  243. });
  244. });
  245. function iconHtml(data){
  246. var id = ns.gen_non_duplicate(10);
  247. let iconData = JSON.parse(data.icon);
  248. var html = '';
  249. if(iconData.iconType == 'img'){
  250. html += `
  251. <div class="td-box">
  252. <div class="icon-img-box">
  253. <img src="${ns.img(iconData.imageUrl)}" alt="">
  254. </div>
  255. </div>
  256. `;
  257. }else if(iconData.iconType == 'icon') {
  258. let iconBgStyle = '';
  259. let iconStyle = '';
  260. if(iconData.style) {
  261. var style = {
  262. 'border-radius': iconData.style.bgRadius + '%',
  263. 'background': ''
  264. };
  265. if (iconData.style.iconBgImg) style['background'] += 'url(' + ns.img(iconData.style.iconBgImg) + ') no-repeat bottom / contain'
  266. if (iconData.style.iconBgColor.length) {
  267. if (style.background) style.background += ',';
  268. if (iconData.style.iconBgColor.length == 1) {
  269. style.background += iconData.style.iconBgColor[0];
  270. } else {
  271. style['background'] += 'linear-gradient(' + iconData.style.iconBgColorDeg + 'deg, ' + iconData.style.iconBgColor.join(',') + ')';
  272. }
  273. }
  274. for (let i in style){
  275. iconBgStyle += i+':'+style[i]+';';
  276. }
  277. var style = {
  278. 'font-size': iconData.style.fontSize + '%'
  279. }
  280. if (iconData.style.iconColor.length == 1) {
  281. style.color = iconData.style.iconColor[0];
  282. } else {
  283. style['background'] = 'linear-gradient('+ iconData.style.iconColorDeg +'deg, '+ iconData.style.iconColor.join(',') +')';
  284. }
  285. for (let i in style){
  286. iconStyle += i+':'+style[i]+';';
  287. }
  288. }
  289. let iconClass = iconData.icon;
  290. if (iconData.style && iconData.style.iconColor.length > 1) iconClass += ' gradient';
  291. html += `
  292. <div class="td-box">
  293. <div class="icon-img-box">
  294. <div class="icon-wrap" style="${iconBgStyle}">
  295. <i class="js-icon ${iconClass}" style="${iconStyle}"></i>
  296. </div>
  297. </div>
  298. </div>
  299. `;
  300. }
  301. return html;
  302. }
  303. function addService() {
  304. var add_attr = $("#addService").html();
  305. laytpl(add_attr).render({}, function(html) {
  306. add_attr_index = layer.open({
  307. title: '添加商品服务',
  308. skin: 'layer-tips-class',
  309. type: 1,
  310. area: ['500px', '500px'],
  311. content: html,
  312. success: function(){
  313. init({
  314. "imageUrl": "",
  315. "icon" : "",
  316. "iconType": "icon",
  317. "style": '',
  318. });
  319. }
  320. });
  321. });
  322. }
  323. function editService(data) {
  324. var add_attr = $("#editService").html();
  325. laytpl(add_attr).render(data, function(html) {
  326. add_attr_index = layer.open({
  327. title: '编辑商品服务',
  328. skin: 'layer-tips-class',
  329. type: 1,
  330. area: ['500px', '500px'],
  331. content: html,
  332. success: function(){
  333. if(data.icon){
  334. if(isJSON(data.icon)){
  335. init(JSON.parse(data.icon));
  336. }else{
  337. init({
  338. "imageUrl": data.icon,
  339. "icon" : "",
  340. "iconType": "img",
  341. "style": '',
  342. });
  343. }
  344. }else{
  345. init({
  346. "imageUrl": "",
  347. "icon" : "",
  348. "iconType": "icon",
  349. "style": '',
  350. });
  351. }
  352. }
  353. });
  354. });
  355. }
  356. function isJSON(str) {
  357. if (typeof str == 'string') {
  358. try {
  359. var obj = JSON.parse(str);
  360. if (typeof obj == 'object' && obj) {
  361. return true;
  362. } else {
  363. return false;
  364. }
  365. } catch (e) {
  366. return false;
  367. }
  368. }
  369. }
  370. function closeAttrLayer() {
  371. layer.close(add_attr_index);
  372. }
  373. function init(data){
  374. vue = new Vue({
  375. el: "#app",
  376. data: {
  377. myData: {},
  378. id : '',
  379. colorPicker:{}
  380. },
  381. created: function (){
  382. this.id = ns.gen_non_duplicate(10);
  383. this.myData = data;
  384. loadImgMagnify();
  385. },
  386. methods: {
  387. // 选择图标风格
  388. iconStyle(event) {
  389. var self = this;
  390. selectIconStyle({
  391. elem: event.currentTarget,
  392. icon: self.myData.icon,
  393. callback: function (data) {
  394. if (data) {
  395. self.myData.style = data;
  396. } else {
  397. iconStyleSet({
  398. style: JSON.stringify(self.myData.style),
  399. query: {
  400. icon: self.myData.icon
  401. }
  402. }, function (style) {
  403. self.myData.style = style;
  404. })
  405. }
  406. }
  407. })
  408. },
  409. /**
  410. * 渲染颜色组件
  411. * @param id
  412. * @param color
  413. * @param callback
  414. */
  415. colorRender(id, color, callback) {
  416. var self = this;
  417. if (this.colorPicker[id]) return;
  418. setTimeout(function () {
  419. self.colorPicker[id] = Colorpicker.create({
  420. el: id,
  421. color: color,
  422. change: function (elem, hex) {
  423. callback(elem, hex)
  424. }
  425. });
  426. $('#' + id).click();
  427. }, 10)
  428. },
  429. selectColor(id) {
  430. let self = this;
  431. this.colorRender(id, '', function (elem, color) {
  432. if (self.myData.style['iconBgImg'] || self.myData.style['iconBgColor'].length) {
  433. self.myData.style['iconBgColor'] = [color];
  434. } else {
  435. self.myData.style['iconColor'] = [color];
  436. }
  437. self.$forceUpdate();
  438. })
  439. },
  440. previewImg(id){
  441. $('#'+id).find('div>img').click();
  442. },
  443. },
  444. mounted(){
  445. },
  446. computed: {
  447. }
  448. })
  449. }
  450. </script>
  451. {/block}