product.js 53 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027
  1. //加载Vue 主要用作规格
  2. require.config({
  3. paths: {
  4. "vue": "../addons/unishop/js/vue",
  5. //"vue": "https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue",
  6. }
  7. });
  8. define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'upload', 'plupload', 'vue'], function ($, undefined, Backend, Table, Form, Upload, Plupload, Vue) {
  9. // 规格模板
  10. //使用基础 Vue 构造器,创建一个“子类”。参数是一个包含组件选项的对象
  11. var specComponent = Vue.extend({
  12. template: '<div>' +
  13. ' <div class="form-group">\n' +
  14. ' <label class="control-label col-xs-12 col-sm-2">' + __('use_spec') + '</label>\n' +
  15. ' <div class="col-xs-12 col-sm-8">\n' +
  16. ' <input type="radio" name="row[use_spec]" value="0" v-model="use_spec"/>否\n' +
  17. ' <input type="radio" name="row[use_spec]" value="1" v-model="use_spec"/>是\n' +
  18. ' </div>\n' +
  19. ' </div>\n' +
  20. '\n' +
  21. ' <div class="form-group" v-if="use_spec == 1">\n' +
  22. ' <label class="control-label col-xs-12 col-sm-2">' + __('Spec') + '</label>\n' +
  23. ' <div class="col-xs-12 col-sm-8">\n' +
  24. ' <input id="c-specList" type="hidden" name="row[specList]" v-model="specListJSON"/>\n' +
  25. ' <input id="c-specTableList" type="hidden" name="row[specTableList]" v-model="specTableListJSON"/>\n' +
  26. '\n' +
  27. ' <table class="table table-hover">\n' +
  28. ' <thead>\n' +
  29. ' <tr>\n' +
  30. ' <th class="col-sm-4">\n' +
  31. ' <a href="javascript:;" class="btn btn-success btn-add" title="添加" data-toggle="modal"\n' +
  32. ' data-target="#addSpec"><i class="fa fa-plus"></i> 添加属性</a>\n' +
  33. ' <!-- 输入规格名称 -->\n' +
  34. ' <div class="modal fade" id="addSpec" tabindex="-1" role="dialog">\n' +
  35. ' <div class="modal-dialog modal-sm" role="document">\n' +
  36. ' <div class="modal-content">\n' +
  37. ' <div class="modal-body">\n' +
  38. ' <label>输入规格名称</label>\n' +
  39. ' <input type="text" class="form-control" v-model="specName">\n' +
  40. ' </div>\n' +
  41. ' <div class="modal-footer">\n' +
  42. ' <button type="button" class="btn btn-default" data-dismiss="modal">\n' +
  43. __('Close') +
  44. ' </button>\n' +
  45. ' <button type="button" class="btn btn-primary" data-dismiss="modal"\n' +
  46. ' v-on:click="addSpecList">' + __('Add') + '\n' +
  47. ' </button>\n' +
  48. ' </div>\n' +
  49. ' </div>\n' +
  50. ' </div>\n' +
  51. ' </div>\n' +
  52. ' <!-- 输入规格值 -->\n' +
  53. ' <div class="modal fade" id="addSpecValue" tabindex="-1" role="dialog">\n' +
  54. ' <div class="modal-dialog modal-sm" role="document">\n' +
  55. ' <div class="modal-content">\n' +
  56. ' <div class="modal-body">\n' +
  57. ' <label>输入规格 {{specFatherName}} 的值</label>\n' +
  58. ' <input type="text" class="form-control" v-model="specValue">\n' +
  59. ' </div>\n' +
  60. ' <div class="modal-footer">\n' +
  61. ' <button type="button" class="btn btn-default" data-dismiss="modal">\n' +
  62. __('Close') +
  63. ' </button>\n' +
  64. ' <button type="button" class="btn btn-primary" data-dismiss="modal"\n' +
  65. ' v-on:click="addSpecChildList">' + __('Add') + '\n' +
  66. ' </button>\n' +
  67. ' </div>\n' +
  68. ' </div>\n' +
  69. ' </div>\n' +
  70. ' </div>\n' +
  71. ' </th>\n' +
  72. ' <th style=" height: 50px;\n' +
  73. ' display: block;\n' +
  74. ' line-height: 36px;\n' +
  75. ' text-align: center;">\n' +
  76. __('Specchildlist') + '\n' +
  77. ' </th>\n' +
  78. ' </tr>\n' +
  79. ' </thead>\n' +
  80. ' <tbody>\n' +
  81. ' <tr v-for="(item,index) in specList">\n' +
  82. ' <td>\n' +
  83. ' <div class="input-group">\n' +
  84. ' <input type="text" class="form-control" v-model="item.name">\n' +
  85. ' <span class="input-group-btn">\n' +
  86. ' <button class="btn btn-default" type="button" v-on:click="delSpec(index)">\n' +
  87. ' <span aria-hidden="true" class="tab-danger">&times;</span>\n' +
  88. ' </button>\n' +
  89. ' </span>\n' +
  90. ' </div>\n' +
  91. ' </td>\n' +
  92. ' <td>\n' +
  93. ' <div class="input-group" v-for="(childItem, childIndex) in item.child">\n' +
  94. ' <input type="text" class="form-control" disabled v-model="item.child[childIndex]">\n' +
  95. ' <span class="input-group-btn">\n' +
  96. ' <button class="btn btn-default" type="button"\n' +
  97. ' v-on:click="delSpecChild(index,childIndex)">\n' +
  98. ' <span aria-hidden="true" class="tab-danger">&times;</span>\n' +
  99. ' </button>\n' +
  100. ' </span>\n' +
  101. ' </div>\n' +
  102. ' <a href="javascript:;" v-on:click="herFatherSpec(index)" class="btn btn-success btn-add"\n' +
  103. ' title="添加" data-toggle="modal" data-target="#addSpecValue"><i class="fa fa-plus"></i>\n' +
  104. ' 添加属性值</a>\n' +
  105. ' </td>\n' +
  106. ' </tr>\n' +
  107. ' </tbody>\n' +
  108. ' </table>\n' +
  109. ' </div>\n' +
  110. ' </div>\n' +
  111. ' <div class="form-group" v-if="use_spec == 1">\n' +
  112. ' <div class="col-xs-12 col-sm-1"></div>\n' +
  113. ' <div class="col-xs-12 col-sm-10">\n' +
  114. ' <table class="table table-bordered table-hover">\n' +
  115. ' <thead>\n' +
  116. ' <tr>\n' +
  117. ' <th>图片</th>\n' +
  118. ' <th v-for="(item) in specList" v-if="item.child.length > 0">\n' +
  119. ' <span>\n' +
  120. ' {{item.name}}\n' +
  121. ' </span>\n' +
  122. ' </th>\n' +
  123. ' <th>' + __('Code') + '</th>\n' +
  124. ' <th>' + __('Market price') + '</th>\n' +
  125. ' <th>' + __('Sales price') + '</th>\n' +
  126. ' <th>' + __('Stock') + '</th>\n' +
  127. ' <th>' + __('Sales') + '</th>\n' +
  128. ' </tr>\n' +
  129. ' </thead>\n' +
  130. ' <tbody>\n' +
  131. ' <tr v-for="(tItem,index) in specTableList">\n' +
  132. ' <td>\n' +
  133. ' <input v-bind:id="\'c-logoSpec\' + index" type="hidden" v-model="tItem.image" >\n' +
  134. '\n' +
  135. ' <button type="button" v-bind:id="\'fachoose-logoSpec\'+index" class="btn btn-primary fachoose-spec"\n' +
  136. ' v-bind:data-input-id="\'c-logoSpec\'+index" v-bind:data-preview-id="\'p-logoSpec\'+index" data-mimetype="image/*"\n' +
  137. ' data-multiple="false">' + __('Choose') +
  138. ' </button>\n' +
  139. ' <button style="display: none;" type="button" v-bind:id="\'plupload-logoSpec\'+index"\n' +
  140. ' class="btn btn-danger plupload-spec" v-bind:data-input-id="\'c-logoSpec\'+index"\n' +
  141. ' data-mimetype="image/gif,image/jpeg,image/png,image/jpg,image/bmp"\n' +
  142. ' data-multiple="false" v-bind:data-preview-id="\'p-logoSpec\'+index">\n' +
  143. __('Upload') +
  144. ' </button>\n' +
  145. ' <ul class="row list-inline plupload-preview width100" v-bind:id="\'p-logoSpec\'+index">\n' +
  146. '\n' +
  147. ' </ul>\n' +
  148. ' </td>\n' +
  149. ' <td v-for="vItem in tItem.value">\n' +
  150. ' <input class="form-control" disabled v-bind:value="vItem" />\n' +
  151. ' </td>\n' +
  152. ' <td><input class="form-control" data-rule="required" min="0" type="number" v-model="tItem.code"></td>\n' +
  153. ' <td><input class="form-control" data-rule="required" min="0" type="number" v-model="tItem.market_price"></td>\n' +
  154. ' <td><input class="form-control" data-rule="required" min="0" type="number" v-model="tItem.sales_price"></td>\n' +
  155. ' <td><input class="form-control" data-rule="required" min="0" type="number" v-model="tItem.stock"></td>\n' +
  156. ' <td><input class="form-control" data-rule="required" min="0" type="number" v-model="tItem.sales"></td>\n' +
  157. ' </tr>\n' +
  158. ' </tbody>\n' +
  159. ' </table>\n' +
  160. ' </div>\n' +
  161. ' </div>\n' +
  162. '\n' +
  163. ' <div class="form-group">\n' +
  164. ' <label class="control-label col-xs-12 col-sm-2">' + __('Lower market price') + ':</label>\n' +
  165. ' <div class="col-xs-12 col-sm-8">\n' +
  166. ' <input id="c-market_price" data-rule="required" v-bind:readonly="use_spec == 1" class="form-control"\n' +
  167. ' name="row[market_price]" min="0" type="number" v-model="noSpecValue.market_price">\n' +
  168. ' </div>\n' +
  169. ' </div>\n' +
  170. ' <div class="form-group">\n' +
  171. ' <label class="control-label col-xs-12 col-sm-2">' + __('Lower sales price') + ':</label>\n' +
  172. ' <div class="col-xs-12 col-sm-8">\n' +
  173. ' <input id="c-sales_price" data-rule="required" v-bind:readonly="use_spec == 1" class="form-control"\n' +
  174. ' name="row[sales_price]" min="0" type="number" v-model="noSpecValue.sales_price">\n' +
  175. ' </div>\n' +
  176. ' </div>\n' +
  177. '\n' +
  178. ' <div class="form-group">\n' +
  179. ' <label class="control-label col-xs-12 col-sm-2">' + __('Total stock') + ':</label>\n' +
  180. ' <div class="col-xs-12 col-sm-8">\n' +
  181. ' <input id="c-stock" data-rule="required" v-bind:readonly="use_spec == 1" class="form-control"\n' +
  182. ' name="row[stock]" min="0" type="number" v-model="noSpecValue.stock">\n' +
  183. ' </div>\n' +
  184. ' </div>\n' +
  185. ' <div class="form-group">\n' +
  186. ' <label class="control-label col-xs-12 col-sm-2">' + __('Total sales') + ':</label>\n' +
  187. ' <div class="col-xs-12 col-sm-8">\n' +
  188. ' <input id="c-sales" data-rule="required" v-bind:readonly="use_spec == 1" class="form-control"\n' +
  189. ' name="row[sales]" min="0" type="number" v-model="noSpecValue.sales">\n' +
  190. ' </div>\n' +
  191. ' </div>\n' +
  192. '</div>\n',
  193. data() {
  194. return {
  195. specList: _specList ? _specList : '',
  196. //[ //规格列表
  197. // {
  198. // name: '尺寸',
  199. // child: ['XS']
  200. // }, {
  201. // name: '大小',
  202. // child: ['大', '小']
  203. // },
  204. //],
  205. specTableList: _specTableList ? _specTableList : '',
  206. //[
  207. // {
  208. // value: ['XS', '大'],
  209. // code: 0,
  210. // market_price: 0.00,
  211. // sales_price: 0.00,
  212. // stock: 0,
  213. // sales: 0,
  214. // image: ''
  215. // },
  216. // {
  217. // value: ['XS', '小'],
  218. // code: 0,
  219. // market_price: 0.00,
  220. // sales_price: 0.00,
  221. // stock: 0,
  222. // sales: 0,
  223. // image: ''
  224. // }
  225. //],
  226. use_spec: _use_spec ? _use_spec : 0, //是否使用
  227. specName: '', //要添加的规格健名
  228. specValue: '', //要添加的规格值
  229. specChildValue: '', //要添加的规格值
  230. specFatherIndex: 0,
  231. market_price: _market_price ? _market_price : 0.00,
  232. sales_price: _sales_price ? _sales_price : 0.00,
  233. stock: _stock ? _stock : 0,
  234. sales: _sales ? _sales : 0
  235. }
  236. },
  237. computed: {
  238. specListJSON() {
  239. return JSON.stringify(this.specList);
  240. },
  241. specTableListJSON() {
  242. let data = [];
  243. // 按字母排序
  244. for (let i in this.specTableList) {
  245. let newData = {};
  246. Object.keys(this.specTableList[i]).sort().map(key => {
  247. //newData[i][key]=this.specTableList[i].key;
  248. newData[key] = this.specTableList[i][key];
  249. });
  250. data[i] = newData;
  251. }
  252. return JSON.stringify(data);
  253. },
  254. specFatherName() {
  255. return this.specList[this.specFatherIndex] ? this.specList[this.specFatherIndex].name : '';
  256. },
  257. noSpecValue() {
  258. if (this.specTableList.length > 0) {
  259. let value = this.specTableList[0];
  260. let market_price = value.market_price;
  261. let sales_price = value.sales_price;
  262. let stock = 0;
  263. let sales = 0;
  264. for (let item of this.specTableList) {
  265. market_price = parseFloat(item.market_price) < parseFloat(market_price) ? parseFloat(item.market_price) : market_price;
  266. sales_price = parseFloat(item.sales_price) < parseFloat(sales_price) ? parseFloat(item.sales_price) : sales_price;
  267. stock = parseFloat(stock) + parseFloat(item.stock);
  268. sales = parseFloat(sales) + parseFloat(item.sales);
  269. }
  270. return {market_price, sales_price, stock, sales};
  271. } else {
  272. return {
  273. market_price: this.market_price,
  274. sales_price: this.sales_price,
  275. stock: this.stock,
  276. sales: this.sales,
  277. }
  278. }
  279. }
  280. },
  281. methods: {
  282. //渲染到表格
  283. render() {
  284. let arr = this.specList;
  285. if (arr.length == 0) {
  286. //空
  287. return;
  288. }
  289. let specTableList = this.specTableList;
  290. this.specTableList = [];
  291. let td = []; //tbody
  292. var xNum = [];
  293. // 自创笛卡尔乘积算法 @author: mingwei zheng
  294. // 主逻辑
  295. for (var i = 0; i < arr.length; i++) {
  296. var valueLenght = arr[i]['child'].length; //是一个数组
  297. var cols = cols ? cols : valueLenght;//行数
  298. xNum[i] = 1;
  299. for (var ii = i + 1; ii < arr.length; ii++) {
  300. if (arr[ii]) {
  301. let length = arr[ii]['child'].length ? arr[ii]['child'].length : 1;
  302. xNum[i] *= length;
  303. }
  304. if (i == 0) {
  305. let length = arr[ii]['child'].length ? arr[ii]['child'].length : 1;
  306. cols *= length;
  307. }
  308. }
  309. //console.log(xNum[i]);//每个值填多少个行
  310. for (var ii = 0; ii < cols;) {
  311. if (arr[i]['child'].length == 0) {
  312. ii++;
  313. }
  314. for (var v = 0; v < arr[i]['child'].length; v++) {
  315. for (var x = 0; x < xNum[i]; x++) {
  316. td[ii] = td[ii] ? td[ii] : {
  317. value: [],
  318. code: 0,
  319. market_price: 0.00,
  320. sales_price: 0.00,
  321. stock: 0,
  322. sales: 0,
  323. image: ''
  324. };
  325. td[ii].value.push(arr[i]['child'][v]);
  326. //保留原来大值(针对添加的情况)
  327. for (let tItem of specTableList) {
  328. if (
  329. tItem.value.toString() + ',' + arr[i]['child'][v] == td[ii].value.toString()
  330. ||
  331. tItem.value.toString() == td[ii].value.toString()
  332. ) {
  333. let tempValue = td[ii].value;
  334. td[ii] = tItem;
  335. td[ii].value = tempValue;
  336. break;
  337. }
  338. }
  339. ii++;
  340. }
  341. }
  342. }
  343. }
  344. this.specTableList = td;
  345. },
  346. //添加规格名
  347. addSpecList() {
  348. if (this.specName == '') {
  349. Toastr.error('不能为空');
  350. return
  351. }
  352. for (let item of this.specList) {
  353. if (item.name == this.specName) {
  354. Toastr.error('不能重复');
  355. this.specName = '';
  356. return
  357. }
  358. }
  359. if (this.specList === '') {
  360. this.specList = [];
  361. }
  362. this.specList.push({
  363. name: this.specName,
  364. child: []
  365. });
  366. this.specName = '';
  367. },
  368. //添加规格值
  369. addSpecChildList() {
  370. if (this.specValue == '') {
  371. Toastr.error('不能为空');
  372. return
  373. }
  374. for (let item of this.specList) {
  375. if (item.name == this.specFatherName) {
  376. for (let Citem of item.child) {
  377. if (Citem == this.specValue) {
  378. Toastr.error('不能重复的');
  379. this.specValue = '';
  380. return
  381. }
  382. }
  383. item.child.push(this.specValue)
  384. }
  385. }
  386. this.specValue = '';
  387. //更新到表格
  388. this.render();
  389. },
  390. //设置父亲规格名
  391. herFatherSpec(index) {
  392. this.specFatherIndex = index;
  393. },
  394. //删除规格属性
  395. delSpec(index) {
  396. let confir = confirm('是否删除属性:' + this.specList[index].name + '。若有属性值则一带删除。');
  397. if (confir) {
  398. for (var i = this.specList[index].child.length - 1; i >= 0; i--) {
  399. this.delSpecChild(index, i, true);
  400. }
  401. this.specList.splice(index, 1);
  402. this.render();
  403. }
  404. },
  405. //删除规格属性值
  406. delSpecChild(index, childIndex, noconfir = false) {
  407. if (!noconfir)
  408. var confir = confirm('是否删除属性值:' + this.specList[index].child[childIndex] + '。');
  409. if (confir || noconfir) {
  410. var value = this.specList[index].child.splice(childIndex, 1)[0];
  411. //更新到表格
  412. //console.log(value)
  413. this.renderDel(index, value)
  414. }
  415. return;
  416. },
  417. //删除渲染
  418. renderDel(index, value) {
  419. const that = this;
  420. if (that.specList[index].child.length == 0) {
  421. //删除最后一个的情况。只删除specTableList.value的
  422. for (let item of this.specTableList) {
  423. for (let i in item.value) {
  424. if (item.value[i] == value) {
  425. item.value.splice(i, 1);
  426. break;
  427. }
  428. }
  429. }
  430. this.render();
  431. } else {
  432. //还有属性值的情况。直接删除跟value相关的specTableList
  433. for (var i = this.specTableList.length - 1; i >= 0; i--) {
  434. for (let item of that.specTableList[i].value) {
  435. if (item == value) {
  436. this.specTableList.splice(i, 1);
  437. break;
  438. }
  439. }
  440. }
  441. }
  442. return;
  443. },
  444. }
  445. });
  446. var Controller = {
  447. index: function () {
  448. // 初始化表格参数配置
  449. Table.api.init({
  450. extend: {
  451. index_url: 'unishop/product/index' + location.search,
  452. add_url: 'unishop/product/add',
  453. edit_url: 'unishop/product/edit',
  454. del_url: 'unishop/product/del',
  455. multi_url: 'unishop/product/multi',
  456. evaluate_url: 'unishop/evaluate/index',
  457. copy_url: 'unishop/product/copy',
  458. table: 'product',
  459. }
  460. });
  461. $.fn.bootstrapTable.locales[Table.defaults.locale]['formatSearch'] = function () {
  462. return "请输入产品名称";
  463. };
  464. // 合并操作方法
  465. Table.api.events.operate = $.extend(Table.api.events.operate,
  466. {
  467. 'click .btn-evaluate': function (e, value, row, index) {
  468. e.stopPropagation();
  469. e.preventDefault();
  470. var table = $(this).closest('table');
  471. var options = table.bootstrapTable('getOptions');
  472. var ids = row[options.pk];
  473. row = $.extend({}, row ? row : {}, {ids: ids});
  474. var url = options.extend.evaluate_url + '?product_id=' + row.id;
  475. Fast.api.open(Table.api.replaceurl(url, row, table), __('Evaluate'), $(this).data() || {});
  476. }
  477. },
  478. {
  479. 'click .btn-copy': function (e, value, row, index) {
  480. e.stopPropagation();
  481. e.preventDefault();
  482. var table = $(this).closest('table');
  483. var options = table.bootstrapTable('getOptions');
  484. var ids = row[options.pk];
  485. row = $.extend({}, row ? row : {}, {ids: ids});
  486. var url = options.extend.copy_url;
  487. Fast.api.open(Table.api.replaceurl(url, row, table), __('Copy'), $(this).data() || {});
  488. }
  489. }
  490. );
  491. var table = $("#table");
  492. // 初始化表格
  493. table.bootstrapTable({
  494. url: $.fn.bootstrapTable.defaults.extend.index_url,
  495. pk: 'id',
  496. sortName: 'weigh',
  497. placeholder: '请输入产品名称',
  498. columns: [
  499. [
  500. {checkbox: true},
  501. {field: 'id', title: __('Id')},
  502. {field: 'category_id', title: __('Category_id'), visible: false},
  503. {
  504. field: 'category', title: __('Category name'), formatter: function (value, row, index) {
  505. if (value) {
  506. if (value.parent) {
  507. return value.parent.name + ' / ' + value.name;
  508. } else {
  509. return value.name;
  510. }
  511. }
  512. return value;
  513. }
  514. },
  515. {field: 'title', title: __('Title')},
  516. {
  517. field: 'image',
  518. title: __('Image'),
  519. events: Table.api.events.image,
  520. formatter: Table.api.formatter.image
  521. },
  522. {
  523. field: 'images',
  524. title: __('Images'),
  525. events: Table.api.events.image,
  526. formatter: Table.api.formatter.images,
  527. visible: false
  528. },
  529. {field: 'sales_price', title: __('Lower price')},
  530. {field: 'stock', title: __('Stock')},
  531. {field: 'look', title: __('Look')},
  532. {field: 'sales', title: __('Sales')},
  533. {field: 'real_sales', title: __('Real sales')},
  534. {field: 'no_buy_yet', title: __('No buy yet')},
  535. {field: 'real_look', title: __('Real look')},
  536. {field: 'delivery_id', title: __('Delivery_id'), visible: false},
  537. {field: 'delivery.name', title: __('Delivery_id'), visible: false},
  538. {
  539. field: 'updatetime',
  540. title: __('Updatetime'),
  541. operate: 'RANGE',
  542. addclass: 'datetimerange',
  543. formatter: Table.api.formatter.datetime,
  544. visible: false
  545. },
  546. {
  547. field: 'createtime',
  548. title: __('Createtime'),
  549. operate: 'RANGE',
  550. addclass: 'datetimerange',
  551. formatter: Table.api.formatter.datetime
  552. },
  553. {field: 'weigh', title: __('Weigh')},
  554. {field: 'switch', title: __('Switch'), formatter: Table.api.formatter.toggle},
  555. {
  556. field: 'operate',
  557. title: __('Operate'),
  558. table: table,
  559. events: Table.api.events.operate,
  560. formatter: Table.api.formatter.operate,
  561. buttons:[
  562. {
  563. name: 'copy',
  564. text: __('Copy'),
  565. classname: 'btn btn-xs btn-info btn-copy',
  566. extend: 'data-toggle="tooltip"',
  567. icon: 'fa fa-copy'
  568. }
  569. ]
  570. }
  571. ]
  572. ]
  573. });
  574. // 为表格绑定事件
  575. Table.api.bindevent(table);
  576. },
  577. recyclebin: function () {
  578. // 初始化表格参数配置
  579. Table.api.init({
  580. extend: {
  581. 'dragsort_url': ''
  582. }
  583. });
  584. var table = $("#table");
  585. // 初始化表格
  586. table.bootstrapTable({
  587. url: 'unishop/product/recyclebin' + location.search,
  588. pk: 'id',
  589. sortName: 'id',
  590. columns: [
  591. [
  592. {checkbox: true},
  593. {field: 'id', title: __('Id')},
  594. {field: 'title', title: __('Title'), align: 'left'},
  595. {
  596. field: 'deletetime',
  597. title: __('Deletetime'),
  598. operate: 'RANGE',
  599. addclass: 'datetimerange',
  600. formatter: Table.api.formatter.datetime
  601. },
  602. {
  603. field: 'operate',
  604. width: '130px',
  605. title: __('Operate'),
  606. table: table,
  607. events: Table.api.events.operate,
  608. buttons: [
  609. {
  610. name: 'Restore',
  611. text: __('Restore'),
  612. classname: 'btn btn-xs btn-info btn-ajax btn-restoreit',
  613. icon: 'fa fa-rotate-left',
  614. url: 'unishop/product/restore',
  615. refresh: true
  616. },
  617. {
  618. name: 'Destroy',
  619. text: __('Destroy'),
  620. classname: 'btn btn-xs btn-danger btn-ajax btn-destroyit',
  621. icon: 'fa fa-times',
  622. url: 'unishop/product/destroy',
  623. refresh: true
  624. }
  625. ],
  626. formatter: Table.api.formatter.operate
  627. }
  628. ]
  629. ]
  630. });
  631. // 为表格绑定事件
  632. Table.api.bindevent(table);
  633. },
  634. add: function () {
  635. Controller.api.bindevent();
  636. var component = new specComponent().$mount();
  637. // 插入页面
  638. document.getElementById('spec').appendChild(component.$el);
  639. $('#spec').on('click', function () {
  640. // 选择图片
  641. let chooseImageButtons = $(".fachoose-spec", $("#spec"));
  642. if (chooseImageButtons) {
  643. //console.log(chooseImageButtons);
  644. for (let i = 0; i < chooseImageButtons.length; i++) {
  645. let events = $._data(chooseImageButtons[i], 'events');
  646. if (events && events['click']) {
  647. // 已绑定事件
  648. //console.log('获取图片不重新绑定事件');
  649. } else {
  650. $(chooseImageButtons[i]).on('click', function () {
  651. var that = this;
  652. var multiple = $(this).data("multiple") ? $(this).data("multiple") : false;
  653. var mimetype = $(this).data("mimetype") ? $(this).data("mimetype") : '';
  654. parent.Fast.api.open("general/attachment/select?element_id=" + $(this).attr("id") + "&multiple=" + multiple + "&mimetype=" + mimetype , __('Choose'), {
  655. callback: function (data) {
  656. var button = $("#" + $(that).attr("id"));
  657. var preview_id = $(button).data("preview-id") ? $(button).data("preview-id") : "";
  658. var input_id = $(button).data("input-id") ? $(button).data("input-id") : "";
  659. if (input_id) {
  660. $("#" + input_id).val(data.url).trigger("change");
  661. //TODO 出发一下input事件,让vue的v-model接收到数据
  662. document.getElementById(input_id).dispatchEvent(new Event('input'));
  663. // 插入图片
  664. if (preview_id && input_id) {
  665. var inputStr = data.url;
  666. var inputArr = inputStr.split(/\,/);
  667. $("#" + preview_id).empty();
  668. var tpl = $("#" + preview_id).data("template") ? $("#" + preview_id).data("template") : "";
  669. $.each(inputArr, function (i, j) {
  670. if (!j) {
  671. return true;
  672. }
  673. var data = {
  674. url: j,
  675. fullurl: Fast.api.cdnurl(j),
  676. data: $(that).data()
  677. };
  678. var html = tpl ? Template(tpl, data) : Template.render(Upload.config.previewtpl, data);
  679. let preview = $("#" + preview_id);
  680. preview.append(html);
  681. $('.btn-trash', preview).on('click', function () {
  682. preview.empty();
  683. })
  684. });
  685. }
  686. }
  687. }
  688. });
  689. return false;
  690. });
  691. }
  692. }
  693. }
  694. });
  695. },
  696. edit: function () {
  697. Controller.api.bindevent();
  698. var component = new specComponent().$mount();
  699. // 插入页面
  700. document.getElementById('spec').appendChild(component.$el);
  701. $('#spec').on('click', function () {
  702. // 选择图片
  703. let chooseImageButtons = $(".fachoose-spec", $("#spec"));
  704. if (chooseImageButtons) {
  705. for (let i = 0; i < chooseImageButtons.length; i++) {
  706. let events = $._data(chooseImageButtons[i], 'events');
  707. let that = chooseImageButtons[i];
  708. let button = $("#" + $(that).attr("id"))
  709. let maxcount = $(button).data("maxcount");
  710. let preview_id = $(button).data("preview-id") ? $(button).data("preview-id") : "";
  711. let input_id = $(button).data("input-id") ? $(button).data("input-id") : "";
  712. if (events && events['click']) {
  713. // 已绑定事件
  714. //console.log('获取图片不重新绑定事件');
  715. } else {
  716. $(chooseImageButtons[i]).on('click', function () {
  717. let multiple = $(this).data("multiple") ? $(this).data("multiple") : false;
  718. let mimetype = $(this).data("mimetype") ? $(this).data("mimetype") : '';
  719. parent.Fast.api.open("general/attachment/select?element_id=" + $(this).attr("id") + "&multiple=" + multiple + "&mimetype=" + mimetype , __('Choose'), {
  720. callback: function (data) {
  721. maxcount = typeof maxcount !== "undefined" ? maxcount : 0;
  722. if (input_id) {
  723. $("#" + input_id).val(data.url).trigger("change");
  724. //TODO 出发一下input事件,让vue的v-model接收到数据
  725. document.getElementById(input_id).dispatchEvent(new Event('input'));
  726. // 插入图片
  727. if (preview_id && input_id) {
  728. let inputStr = data.url;
  729. let inputArr = inputStr.split(/\,/);
  730. $("#" + preview_id).empty();
  731. let tpl = $("#" + preview_id).data("template") ? $("#" + preview_id).data("template") : "";
  732. $.each(inputArr, function (i, j) {
  733. if (!j) {
  734. return true;
  735. }
  736. let data = {
  737. url: j,
  738. fullurl: Fast.api.cdnurl(j),
  739. data: $(that).data()
  740. };
  741. let html = tpl ? Template(tpl, data) : Template.render(Upload.config.previewtpl, data);
  742. let preview = $("#" + preview_id);
  743. preview.append(html);
  744. $('.btn-trash', preview).on('click', function(){
  745. preview.empty();
  746. $("#" + input_id).val('');
  747. //TODO 出发一下input事件,让vue的v-model接收到数据
  748. document.getElementById(input_id).dispatchEvent(new Event('input'));
  749. })
  750. });
  751. }
  752. }
  753. }
  754. });
  755. return false;
  756. });
  757. }
  758. // 首次加载的时候用到, 加载数据
  759. let inputStr = $('#' + input_id).val();
  760. if (inputStr && input_id) {
  761. let inputArr = inputStr.split(/\,/);
  762. $("#" + preview_id).empty();
  763. let tpl = $("#" + preview_id).data("template") ? $("#" + preview_id).data("template") : "";
  764. $.each(inputArr, function (i, j) {
  765. if (!j) {
  766. return true;
  767. }
  768. let data = {
  769. url: j,
  770. fullurl: Fast.api.cdnurl(j),
  771. data: $(that).data()
  772. };
  773. let html = tpl ? Template(tpl, data) : Template.render(Upload.config.previewtpl, data);
  774. //console.log(preview_id);
  775. let preview = $("#" + preview_id);
  776. preview.append(html);
  777. $('.btn-trash', preview).on('click', function(){
  778. $("#" + preview_id).empty();
  779. $('#' + input_id).val('');
  780. //TODO 出发一下input事件,让vue的v-model接收到数据
  781. document.getElementById(input_id).dispatchEvent(new Event('input'));
  782. })
  783. });
  784. }
  785. }
  786. }
  787. });
  788. $('#spec').click();
  789. },
  790. copy:function(){
  791. Controller.api.bindevent();
  792. var component = new specComponent().$mount();
  793. // 插入页面
  794. document.getElementById('spec').appendChild(component.$el);
  795. $('#spec').on('click', function () {
  796. // 选择图片
  797. let chooseImageButtons = $(".fachoose-spec", $("#spec"));
  798. if (chooseImageButtons) {
  799. for (let i = 0; i < chooseImageButtons.length; i++) {
  800. let events = $._data(chooseImageButtons[i], 'events');
  801. let that = chooseImageButtons[i];
  802. let button = $("#" + $(that).attr("id"))
  803. let maxcount = $(button).data("maxcount");
  804. let preview_id = $(button).data("preview-id") ? $(button).data("preview-id") : "";
  805. let input_id = $(button).data("input-id") ? $(button).data("input-id") : "";
  806. if (events && events['click']) {
  807. // 已绑定事件
  808. //console.log('获取图片不重新绑定事件');
  809. } else {
  810. $(chooseImageButtons[i]).on('click', function () {
  811. let multiple = $(this).data("multiple") ? $(this).data("multiple") : false;
  812. let mimetype = $(this).data("mimetype") ? $(this).data("mimetype") : '';
  813. parent.Fast.api.open("general/attachment/select?element_id=" + $(this).attr("id") + "&multiple=" + multiple + "&mimetype=" + mimetype , __('Choose'), {
  814. callback: function (data) {
  815. maxcount = typeof maxcount !== "undefined" ? maxcount : 0;
  816. if (input_id) {
  817. $("#" + input_id).val(data.url).trigger("change");
  818. //TODO 出发一下input事件,让vue的v-model接收到数据
  819. document.getElementById(input_id).dispatchEvent(new Event('input'));
  820. // 插入图片
  821. if (preview_id && input_id) {
  822. let inputStr = data.url;
  823. let inputArr = inputStr.split(/\,/);
  824. $("#" + preview_id).empty();
  825. let tpl = $("#" + preview_id).data("template") ? $("#" + preview_id).data("template") : "";
  826. $.each(inputArr, function (i, j) {
  827. if (!j) {
  828. return true;
  829. }
  830. let data = {
  831. url: j,
  832. fullurl: Fast.api.cdnurl(j),
  833. data: $(that).data()
  834. };
  835. let html = tpl ? Template(tpl, data) : Template.render(Upload.config.previewtpl, data);
  836. let preview = $("#" + preview_id);
  837. preview.append(html);
  838. $('.btn-trash', preview).on('click', function(){
  839. preview.empty();
  840. $("#" + input_id).val('');
  841. //TODO 出发一下input事件,让vue的v-model接收到数据
  842. document.getElementById(input_id).dispatchEvent(new Event('input'));
  843. })
  844. });
  845. }
  846. }
  847. }
  848. });
  849. return false;
  850. });
  851. }
  852. // 首次加载的时候用到, 加载数据
  853. let inputStr = $('#' + input_id).val();
  854. if (inputStr && input_id) {
  855. let inputArr = inputStr.split(/\,/);
  856. $("#" + preview_id).empty();
  857. let tpl = $("#" + preview_id).data("template") ? $("#" + preview_id).data("template") : "";
  858. $.each(inputArr, function (i, j) {
  859. if (!j) {
  860. return true;
  861. }
  862. let data = {
  863. url: j,
  864. fullurl: Fast.api.cdnurl(j),
  865. data: $(that).data()
  866. };
  867. let html = tpl ? Template(tpl, data) : Template.render(Upload.config.previewtpl, data);
  868. //console.log(preview_id);
  869. let preview = $("#" + preview_id);
  870. preview.append(html);
  871. $('.btn-trash', preview).on('click', function(){
  872. $("#" + preview_id).empty();
  873. $('#' + input_id).val('');
  874. //TODO 出发一下input事件,让vue的v-model接收到数据
  875. document.getElementById(input_id).dispatchEvent(new Event('input'));
  876. })
  877. });
  878. }
  879. }
  880. }
  881. });
  882. $('#spec').click();
  883. },
  884. api: {
  885. bindevent: function () {
  886. Form.api.bindevent($("form[role=form]"));
  887. }
  888. },
  889. select: function () {
  890. // 初始化表格参数配置
  891. Table.api.init({
  892. extend: {
  893. index_url: 'unishop/product/index',
  894. }
  895. });
  896. $.fn.bootstrapTable.locales[Table.defaults.locale]['formatSearch'] = function () {
  897. return "请输入产品名称";
  898. };
  899. var table = $("#table");
  900. // 初始化表格
  901. table.bootstrapTable({
  902. url: $.fn.bootstrapTable.defaults.extend.index_url,
  903. sortName: 'id',
  904. placeholder: '请输入产品名称',
  905. columns: [
  906. [
  907. {field: 'state', checkbox: true,},
  908. {field: 'id', title: __('Id'), sortable: true},
  909. {field: 'title', title: __('Title')},
  910. {field: 'image', title: __('Image'), operate: false, formatter: Table.api.formatter.image},
  911. {field: 'stock', title: __('Stock')},
  912. {field: 'category.name', title: __('Category name')},
  913. {
  914. field: 'switch',
  915. title: __('Switch'),
  916. formatter: Table.api.formatter.status,
  917. searchList: {"1": __('Yes'), "0": __('No')}
  918. },
  919. {
  920. field: 'createtime',
  921. title: __('Createtime'),
  922. formatter: Table.api.formatter.datetime,
  923. operate: 'RANGE',
  924. addclass: 'datetimerange',
  925. sortable: true
  926. },
  927. {
  928. field: 'operate', title: __('Operate'), events: {
  929. 'click .btn-chooseone': function (e, value, row, index) {
  930. var dataArr = new Array();
  931. dataArr.push(row);
  932. Fast.api.close({data: dataArr, multiple: false});
  933. },
  934. }, formatter: function () {
  935. return '<a href="javascript:;" class="btn btn-danger btn-chooseone btn-xs"><i class="fa fa-check"></i> ' + __('Choose') + '</a>';
  936. }
  937. }
  938. ]
  939. ]
  940. });
  941. // 选中多个
  942. $(document).on("click", ".btn-choose-multi", function () {
  943. var dataArr = new Array();
  944. $.each(table.bootstrapTable("getAllSelections"), function (i, j) {
  945. dataArr.push(j);
  946. });
  947. var multiple = Backend.api.query('multiple');
  948. multiple = multiple == 'true' ? true : false;
  949. Fast.api.close({data: dataArr, multiple: true});
  950. });
  951. // 为表格绑定事件
  952. //Table.api.bindevent(table);
  953. }
  954. };
  955. return Controller;
  956. });