form.html 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. {extend name='admin@main'}
  2. {block name="content"}
  3. {include file='store@goods/form_style'}
  4. <form onsubmit="return false;" id="GoodsForm" data-auto="true" method="post" class='layui-form layui-card' autocomplete="off">
  5. <div class="layui-card-body think-box-shadow padding-left-40">
  6. <div class="layui-form-item layui-row layui-col-space15">
  7. <label class="layui-col-xs3 relative">
  8. <span class="color-green">服务分类</span>
  9. <select class="layui-select" required name="cate_id" lay-search>
  10. {foreach $cates as $cate}
  11. {if isset($vo.cate_id) and $vo.cate_id eq $cate.id}
  12. <option selected value="{$cate.id}">{$cate.title|default=''}</option>
  13. {else}
  14. <option value="{$cate.id}">{$cate.title|default=''}</option>
  15. {/if}
  16. {/foreach}
  17. </select>
  18. </label>
  19. <label class="layui-col-xs9 relative">
  20. <span class="color-green">服务名称</span>
  21. <input name="title" required class="layui-input" placeholder="请输入服务名称" value="{$vo.title|default=''}">
  22. </label>
  23. </div>
  24. <div class="layui-form-item">
  25. <span class="color-green label-required-prev">服务LOGO及服务介绍图片</span>
  26. <table class="layui-table">
  27. <thead>
  28. <tr>
  29. <th class="text-center">LOGO</th>
  30. <th class="text-left">展示图片</th>
  31. </tr>
  32. <tr>
  33. <td width="90px" class="text-center"><input name="logo" type="hidden" value="{$vo.logo|default=''}"></td>
  34. <td width="auto" class="text-left"><input name="image" type="hidden" value="{$vo.image|default=''}"></td>
  35. </tr>
  36. </thead>
  37. </table>
  38. <script>$('[name="logo"]').uploadOneImage(), $('[name="image"]').uploadMultipleImage()</script>
  39. </div>
  40. <div class="layui-form-item">
  41. <span class="color-green label-required-prev">服务类型<span class="color-red font-s12">(服务类型填写后不允许再次修改)</span></span>
  42. <div ng-repeat="x in specs track by $index" style="display:none" class="margin-bottom-10" ng-class="{true:'layui-show'}[isAddMode&&specs.length>0]">
  43. <div class="goods-spec-box padding-10 margin-0 relative" style="background:#ddd">
  44. <span class="text-center goods-spec-title">分组</span>
  45. <label class="label-required-null inline-block"><input ng-blur="x.name=trimSpace(x.name)" ng-model="x.name" required placeholder="请输入分组名称"></label>
  46. <div class="pull-right">
  47. <a class="layui-btn layui-btn-sm layui-btn-primary goods-spec-btn" ng-click="addSpecVal(x.list)">增加</a>
  48. <a class="layui-btn layui-btn-sm layui-btn-primary goods-spec-btn" ng-class="{false:'layui-bg-gray'}[$index>0]" ng-click="upSpecRow(specs,$index)">上移</a>
  49. <a class="layui-btn layui-btn-sm layui-btn-primary goods-spec-btn" ng-class="{false:'layui-bg-gray'}[$index<specs.length-1]" ng-click="dnSpecRow(specs,$index)">下移</a>
  50. <a class="layui-btn layui-btn-sm layui-btn-primary goods-spec-btn" ng-click="delSpecRow(specs,$index)" ng-if="specs.length>1">删除</a>
  51. </div>
  52. </div>
  53. <div class="goods-spec-box padding-10 margin-0 layui-bg-gray block relative" ng-if="x.list && x.list.length > 0">
  54. <label class="label-required-null inline-block margin-right-10 margin-bottom-5 relative nowrap" ng-repeat="xx in x.list">
  55. <input type="checkbox" lay-ignore ng-model="xx.check" ng-click="xx.check=checkListChecked(x.list,$event.target.checked)">
  56. <input type="text" ng-blur="xx.name=trimSpace(xx.name)" ng-model="xx.name" ng-keyup="xx.name=$event.target.value" required placeholder="请输入规格">
  57. <a ng-if="x.list.length>1" ng-click="x.list=delSpecVal(x.list,$index)" class="layui-icon layui-icon-close font-s12 goods-spec-close"></a>
  58. </label>
  59. </div>
  60. </div>
  61. <!--<a ng-if="isAddMode&&specs.length<3" class="layui-btn layui-btn-sm layui-btn-primary" ng-click="addSpecRow(specs)">增加分组</a>-->
  62. <table class="layui-table margin-top-10">
  63. <thead>
  64. <tr>
  65. <th ng-repeat="x in specsTreeNava track by $index" class="nowrap" ng-bind="x"></th>
  66. <th width="20%" class="text-center nowrap">市场价格 <a ng-click="batchSet('market',2)" data-tips-text="批量设置" class="layui-icon">&#xe63c;</a></th>
  67. <th width="20%" class="text-center nowrap">销售价格 <a ng-click="batchSet('selling',2)" data-tips-text="批量设置" class="layui-icon">&#xe63c;</a></th>
  68. </tr>
  69. </thead>
  70. <tbody>
  71. <tr ng-repeat="rows in specsTreeData track by $index">
  72. <td class="layui-bg-gray" ng-if="td.show" rowspan="{{td.span}}" ng-repeat="td in rows" ng-bind="td.name"></td>
  73. <td class="padding-0">
  74. <label class="padding-0 margin-0">
  75. <input ng-blur="rows[0].market=setValue(rows[0].key,'market',$event.target.value,'(parseFloat(_)||0).toFixed(2)')" class="layui-input border-0 padding-left-0 text-center" ng-model="rows[0].market">
  76. </label>
  77. </td>
  78. <td class="padding-0">
  79. <label class="padding-0 margin-0">
  80. <input ng-blur="rows[0].selling=setValue(rows[0].key,'selling',$event.target.value,'(parseFloat(_)||0).toFixed(2)')" class="layui-input border-0 padding-left-0 text-center" ng-model="rows[0].selling">
  81. </label>
  82. </td>
  83. </tr>
  84. </tbody>
  85. </table>
  86. <textarea class="layui-textarea layui-hide" name="specs">{{specs}}</textarea>
  87. <textarea class="layui-textarea layui-hide" name="lists">{{specsTreeData}}</textarea>
  88. </div>
  89. <div class="layui-form-item text-center">
  90. {notempty name='vo.id'}<input type="hidden" name="id" value="{$vo.id}">{/notempty}
  91. <button class="layui-btn layui-btn-danger" ng-click="hsitoryBack()" type="button">取消编辑</button>
  92. <button class="layui-btn" type="submit">保存服务</button>
  93. </div>
  94. </div>
  95. </form>
  96. {/block}
  97. {block name='script'}
  98. <textarea class="layui-hide" id="goods-specs">{$vo.specs|raw|default=''}</textarea>
  99. <textarea class="layui-hide" id="goods-value">{$defaultValues|raw|default=''}</textarea>
  100. <script>
  101. window.form.render();
  102. require(['ckeditor', 'angular'], function () {
  103. window.createEditor('[name="content"]', {height: 500});
  104. var app = angular.module("GoodsForm", []).run(callback);
  105. angular.bootstrap(document.getElementById(app.name), [app.name]);
  106. function callback($rootScope) {
  107. $rootScope.isAddMode = parseInt('{$isAddMode|default=0}');
  108. $rootScope.maps = JSON.parse(angular.element('#goods-value').val() || '[]') || {};
  109. $rootScope.specs = JSON.parse(angular.element('#goods-specs').val() || '[{"name":"服务类型","list":[{"name":"服务类型","check":true}]}]');
  110. // 批量设置数值
  111. $rootScope.batchSet = function (type, fixed) {
  112. layer.prompt({title: '请输入数值', formType: 0}, function (value, index) {
  113. $rootScope.$apply(function () {
  114. var val = (parseFloat(value) || 0).toFixed(fixed);
  115. for (var i in $rootScope.specsTreeData) for (var j in $rootScope.specsTreeData[i]) {
  116. $rootScope.specsTreeData[i][j][type] = val;
  117. }
  118. });
  119. layer.close(index);
  120. });
  121. };
  122. // 返回服务列表
  123. $rootScope.hsitoryBack = function () {
  124. $.msg.confirm('确定要取消编辑吗?', function (index) {
  125. history.back(), $.msg.close(index);
  126. });
  127. };
  128. // 设置默认值
  129. $rootScope.setValue = function (key, type, value, call) {
  130. $rootScope.maps[key] || ($rootScope.maps[key] = {});
  131. return $rootScope.maps[key][type] = eval(call.replace('_', "'" + value + "'"));
  132. };
  133. // 读取默认值
  134. $rootScope.getValue = function (key, callback) {
  135. if (typeof callback === 'function') {
  136. return callback($rootScope.maps[key] || {});
  137. }
  138. return {};
  139. };
  140. // 去除空白字符
  141. $rootScope.trimSpace = function (value) {
  142. return (value + '').replace(/\s*/ig, '');
  143. };
  144. // 生成交叉表格数据
  145. $rootScope.specsTreeData = [];
  146. $rootScope.specsTreeNava = [];
  147. // 当前服务规格发生变化时重新计算规格列表
  148. $rootScope.$watch('specs', function () {
  149. var data = $rootScope.specs, list = [], navs = [], table = [[]];
  150. // 过滤无效记录
  151. for (var i in data) {
  152. var tmp = [];
  153. for (var j in data[i].list) if (data[i].list[j].check && data[i].list[j].name.length > 0) {
  154. data[i].list[j].span = 1, data[i].list[j].show = true, data[i].list[j].group = data[i].name;
  155. tmp.push(data[i].list[j]);
  156. }
  157. list.push(tmp), navs.push(data[i].name);
  158. }
  159. $rootScope.specsTreeNava = navs;
  160. // 表格交叉
  161. for (var i in list) {
  162. var tmp = [];
  163. for (var j in table) for (var k in list[i]) tmp.push(table[j].concat(list[i][k]));
  164. table = tmp;
  165. }
  166. // 表格合并
  167. list = angular.fromJson(angular.toJson(table));
  168. for (var i in list) {
  169. var key = [], _key = '';
  170. for (var td in list[i]) key.push(list[i][td].group + '::' + list[i][td].name);
  171. for (var td in list[i]) if (_key.length === 0) {
  172. list[i][0].key = _key = key.join(';;');
  173. list[i][0].sku = $rootScope.getValue(_key, function (data) {
  174. return data.sku || '0';
  175. });
  176. list[i][0].virtual = $rootScope.getValue(_key, function (data) {
  177. return data.virtual || '0';
  178. });
  179. list[i][0].express = $rootScope.getValue(_key, function (data) {
  180. return data.express || '1';
  181. });
  182. list[i][0].market = $rootScope.getValue(_key, function (data) {
  183. return data.market || '0.00';
  184. });
  185. list[i][0].selling = $rootScope.getValue(_key, function (data) {
  186. return data.selling || '0.00';
  187. });
  188. list[i][0].status = $rootScope.getValue(_key, function (data) {
  189. return !!(typeof data.status !== 'undefined' ? data.status : true);
  190. });
  191. }
  192. }
  193. $rootScope.specsTreeData = list;
  194. }, true);
  195. // 判断规则是否能取消选择
  196. $rootScope.checkListChecked = function (list, check) {
  197. for (var i in list) if (list[i].check) return check;
  198. return true;
  199. };
  200. // 增加整行规格分组
  201. $rootScope.addSpecRow = function (data) {
  202. data.push({name: '规格分组', list: [{name: '规格属性', check: true}]})
  203. };
  204. // 下移整行规格分组
  205. $rootScope.dnSpecRow = function (data, $index) {
  206. var tmp = [], cur = data[$index];
  207. if ($index > data.length - 2) return false;
  208. for (var i in data) {
  209. (parseInt(i) !== parseInt($index)) && tmp.push(data[i]);
  210. (parseInt(i) === parseInt($index) + 1) && tmp.push(cur);
  211. }
  212. return $rootScope.specs = tmp;
  213. };
  214. // 上移整行规格分组
  215. $rootScope.upSpecRow = function (data, $index) {
  216. var tmp = [], cur = data[$index];
  217. if ($index < 1) return false;
  218. for (var i in data) {
  219. (parseInt(i) === parseInt($index) - 1) && tmp.push(cur);
  220. (parseInt(i) !== parseInt($index)) && tmp.push(data[i]);
  221. }
  222. return $rootScope.specs = tmp;
  223. };
  224. // 移除整行规格分组
  225. $rootScope.delSpecRow = function (data, $index) {
  226. var tmp = [];
  227. for (var i in data) if (parseInt(i) !== parseInt($index)) tmp.push(data[i]);
  228. return $rootScope.specs = tmp;
  229. };
  230. // 增加分组的属性
  231. $rootScope.addSpecVal = function (list) {
  232. list.push({name: '规格属性', check: true});
  233. };
  234. // 移除分组的属性
  235. $rootScope.delSpecVal = function (data, $index) {
  236. var temp = [];
  237. for (var i in data) if (parseInt(i) !== parseInt($index)) temp.push(data[i]);
  238. return temp;
  239. };
  240. }
  241. })
  242. </script>
  243. {/block}