images.php 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527
  1. <!DOCTYPE html>
  2. <!--suppress JSAnnotator -->
  3. <html lang="zh-CN">
  4. <head>
  5. <link rel="stylesheet" href="{__FRAME_PATH}font-awesome/css/font-awesome.min.css">
  6. <link href="{__PLUG_PATH}layui/css/layui.css" rel="stylesheet">
  7. <link rel="stylesheet" href="{__ADMIN_PATH}css/images.css?v=100">
  8. <script src="{__PLUG_PATH}jquery-1.10.2.min.js"></script>
  9. <script src="{__PLUG_PATH}layui/layui.all.js"></script>
  10. <script src="{__PLUG_PATH}vue/dist/vue.min.js"></script>
  11. </head>
  12. <style>
  13. </style>
  14. <body>
  15. <div v-cloak id="app" class="layui-fluid">
  16. <div class="layui-fluid-side">
  17. <div class="layui-tree" lay-filter="LAY-tree-8">
  18. <div data-id="2" class="layui-tree-set layui-tree-setHide">
  19. <div class="layui-tree-entry">
  20. <div class="layui-tree-main" @click="OpenTree({ child: [], id: 0 })">
  21. <span style="visibility: hidden;" class="layui-tree-iconClick">
  22. <i class="layui-tree-iconArrow"></i>
  23. </span>
  24. <span :class="{ on: pid == 0 }" class="layui-tree-txt">全部图片</span>
  25. </div>
  26. </div>
  27. </div>
  28. <div v-for="(item, index) in categoryList" :key="item.id" :class="{ 'layui-tree-spread': item.isOpen }" data-id="2" class="layui-tree-set layui-tree-setHide">
  29. <div class="layui-tree-entry">
  30. <div class="layui-tree-main" @click="OpenTree(item, index)">
  31. <span :style="{ visibility: item.child.length ? 'visible' : 'hidden' }" class="layui-tree-iconClick">
  32. <i class="layui-tree-iconArrow"></i>
  33. </span>
  34. <span :class="{ on: pid == item.id }" class="layui-tree-txt">{{ item.name }}</span>
  35. </div>
  36. <div class="layui-layer layui-layer-tips">
  37. <div id="" class="layui-layer-content">
  38. <div class="layui-btn-group layui-tree-btnGroup">
  39. <i class="layui-icon layui-icon-add-1" data-type="add" @click.stop="addCategory(item)"></i>
  40. <i class="layui-icon layui-icon-edit" data-type="update" @click.stop="updateCategory(item)"></i>
  41. <i v-if="!item.child.length" class="layui-icon layui-icon-delete" data-type="del" @click.stop="delCategory(item)"></i>
  42. </div>
  43. <i class="layui-layer-TipsG layui-layer-TipsT"></i>
  44. </div>
  45. <span class="layui-layer-setwin"></span>
  46. </div>
  47. </div>
  48. <div :style="{ display: item.isOpen ? 'block' : 'none' }" class="layui-tree-pack layui-tree-lineExtend layui-tree-showLine">
  49. <div v-for="cell in item.child" :key="cell.id" data-id="2000" class="layui-tree-set">
  50. <div class="layui-tree-entry">
  51. <div class="layui-tree-main" @click="OpenTree(cell, index)">
  52. <span class="layui-tree-iconClick" style="visibility: hidden;">
  53. <i class="layui-tree-iconArrow" style="display: none;"></i>
  54. </span>
  55. <span :class="{ on: pid == cell.id }" class="layui-tree-txt">{{ cell.name }}</span>
  56. </div>
  57. <div class="layui-layer layui-layer-tips">
  58. <div id="" class="layui-layer-content">
  59. <div class="layui-btn-group layui-tree-btnGroup">
  60. <i class="layui-icon layui-icon-edit" data-type="update" @click.stop="updateCategory(cell)"></i>
  61. <i class="layui-icon layui-icon-delete" data-type="del" @click.stop="delCategory(cell)"></i>
  62. </div>
  63. <i class="layui-layer-TipsG layui-layer-TipsT"></i>
  64. </div>
  65. <span class="layui-layer-setwin"></span>
  66. </div>
  67. </div>
  68. </div>
  69. </div>
  70. </div>
  71. </div>
  72. </div>
  73. <div class="layui-fluid-main">
  74. <div class="main-header">
  75. <div class="layui-btn-group">
  76. <button :class="{ 'layui-btn-normal': selectedImage.length, 'layui-btn-disabled': !selectedImage.length }" type="button" class="layui-btn layui-btn-sm"
  77. @click="useImage">使用选中的图片</button>
  78. <button type="button" class="layui-btn layui-btn-normal layui-btn-sm" @click="addCategory">添加分类</button>
  79. <button ref="upload" type="button" class="layui-btn layui-btn-normal layui-btn-sm">上传图片</button>
  80. <button :class="{ 'layui-btn-normal': selectedImage.length, 'layui-btn-disabled': !selectedImage.length }" type="button" class="layui-btn layui-btn-sm"
  81. @click="moveCategory">图片移至</button>
  82. <button :class="{ 'layui-btn-danger': selectedImage.length, 'layui-btn-disabled': !selectedImage.length }" type="button" class="layui-btn layui-btn-sm"
  83. @click="deleteImage">删除图片</button>
  84. <button type="button" class="layui-btn layui-btn-normal layui-btn-sm" @click="searchImage"><i class="layui-icon layui-icon-search"></i></button>
  85. </div>
  86. </div>
  87. <div class="main-content">
  88. <div v-for="item in imageList" :key="item.att_id" class="image-item">
  89. <div :class="{ on: item.selected }" class="image-wrap" @click="selectImage(item)">
  90. <img :src="item.att_dir">
  91. <span v-show="item.number" class="layui-badge layui-bg-cyan">{{ item.number }}</span>
  92. <div class="layui-btn-group">
  93. <button type="button" class="layui-btn layui-btn-primary layui-btn-xs" @click.stop="lookImage(item.att_dir)">
  94. <i class="fa fa-eye"></i>
  95. </button>
  96. <button type="button" class="layui-btn layui-btn-primary layui-btn-xs" @click.stop="handleEdit(item)">
  97. <i class="fa fa-edit"></i>
  98. </button>
  99. </div>
  100. </div>
  101. <input :ref="item.att_id" v-model.trim="item.title" type="text" :disabled="item.disabled" @blur="handleBlur(item)">
  102. </div>
  103. <img v-if="!imageList.length && !loading" class="empty" src="{__ADMIN_PATH}images/empty.jpg">
  104. </div>
  105. <div ref="main-footer" class="main-footer"></div>
  106. </div>
  107. </div>
  108. </body>
  109. </html>
  110. <script src="{__ADMIN_PATH}js/layuiList.js"></script>
  111. <script>
  112. var form = layui.form;
  113. var pid = {$pid}, small = {$Request.param.small ? : 0}, parentinputname = '{$fodder}', maxLength = {$maxLength};//当前图片分类ID
  114. new Vue({
  115. el: "#app",
  116. data: {
  117. categoryList: [],
  118. searchTitle: '',
  119. pid: pid,
  120. imageList: [],
  121. page: 1,
  122. limit: 20,
  123. loading: false,
  124. small: small,
  125. selectedImage: [],
  126. selectedImageIDS: [],
  127. uploadInst: null,
  128. searchContent: '',
  129. files: {}
  130. },
  131. watch: {
  132. page: function () {
  133. this.getImageList();
  134. },
  135. },
  136. methods: {
  137. searchImage: function () {
  138. var vm = this;
  139. layer.prompt({
  140. title: '输入图片名称,并确认',
  141. formType: 0
  142. }, function (text, index) {
  143. if (!text.trim().length) {
  144. return;
  145. }
  146. this.pid = 0;
  147. this.searchContent = text.trim();
  148. this.page = 1;
  149. layer.close(index);
  150. var load = layer.load(1);
  151. layList.baseGet(this.U({
  152. a: 'get_image_list',
  153. q: {pid: this.pid, page: this.page, limit: this.limit, title: this.searchContent}
  154. }), function (res) {
  155. layer.close(load);
  156. var list = res.data.list;
  157. list.forEach(function (item) {
  158. item.disabled = true;
  159. item.hover = false;
  160. if (!item.title) {
  161. item.title = item.name.slice(0, item.name.lastIndexOf('.'));
  162. }
  163. });
  164. this.$set(this, 'imageList', list);
  165. if (this.page == 1) {
  166. layList.laypage.render({
  167. elem: this.$refs['main-footer']
  168. , count: res.data.count
  169. , limit: this.limit
  170. , theme: '#191C6E',
  171. groups: 3,
  172. jump: function (obj) {
  173. vm.page = obj.curr;
  174. }
  175. });
  176. }
  177. }.bind(this), function (res) {
  178. layer.close(load);
  179. layList.msg(res.msg);
  180. });
  181. }.bind(this));
  182. },
  183. handleEdit: function (item) {
  184. item.disabled = false;
  185. this.oldTitle = item.title;
  186. this.$nextTick(function () {
  187. this.$refs[item.att_id][0].focus();
  188. });
  189. },
  190. handleBlur: function (item) {
  191. item.disabled = true;
  192. if (this.oldTitle !== item.title) {
  193. this.updateTitle(item);
  194. }
  195. },
  196. lookImage: function (image) {
  197. layui.layer.photos({
  198. photos: {
  199. data: [
  200. {
  201. src: image
  202. }
  203. ]
  204. },
  205. anim: 5
  206. });
  207. },
  208. // 修改名称
  209. updateTitle: function (item) {
  210. layList.basePost(this.U({
  211. a: 'updateImageTitle'
  212. }), {
  213. att_id: item.att_id,
  214. title: item.title
  215. }, function (res) {
  216. layList.msg(res.msg);
  217. }, function (res) {
  218. layList.msg(res.msg);
  219. });
  220. },
  221. //删除图片
  222. deleteImage: function () {
  223. var that = this;
  224. if (!this.selectedImage.length) return;
  225. layList.layer.confirm('是否要删除选中图片?', {
  226. btn: ['是的我要删除', '我想想吧'] //按钮
  227. }, function () {
  228. layList.basePost(that.U({a: 'delete'}), {imageid: that.selectedImageIDS}, function (res) {
  229. layList.msg(res.msg);
  230. that.getImageList();
  231. window.location.reload()
  232. }, function (res) {
  233. layList.msg(res.msg);
  234. })
  235. })
  236. },
  237. //移动图片分类
  238. moveCategory: function () {
  239. var that = this;
  240. window.formSuccessBack = function () {
  241. that.getImageList();
  242. that.selectedImage = [];
  243. that.selectedImageIDS = [];
  244. };
  245. this.getOpenWindow('移动图片', this.U({a: 'moveimg'}) + '?imgaes=' + this.selectedImageIDS, {
  246. end: function () {
  247. window.formSuccessBack = null;
  248. }
  249. });
  250. },
  251. //使用选中图片
  252. useImage: function () {
  253. if (!this.selectedImage.length) return;
  254. //判断表单限制图片个数
  255. if (typeof parent.$f != 'undefined') {
  256. //已有图片个数
  257. var nowpics = parent.$f.getValue(parentinputname).length,
  258. props = parent.$f.model()[parentinputname].props || {},
  259. maxlength = props.maxLength || 0;
  260. //已选图片个数
  261. var selectlength = this.selectedImage.length;
  262. //还可以选择多少张
  263. var surplus = maxlength - nowpics;
  264. if (nowpics + selectlength > maxlength) {
  265. return layList.msg('最多只能选择 ' + surplus + ' 张');
  266. }
  267. }
  268. //编辑器中
  269. if (parentinputname.includes('editor')) {
  270. var list = this.selectedImage.map(function (image) {
  271. return {
  272. _src: image,
  273. src: image
  274. };
  275. });
  276. parent.insertEditor(list, parentinputname);
  277. var index = parent.layer.getFrameIndex(window.name);
  278. parent.layer.close(index)
  279. } else {
  280. //form表单中
  281. if (parent.$f) {
  282. var value = parent.$f.getValue(parentinputname);//父级input 值
  283. var list = value || [];
  284. for (var i = 0; i < this.selectedImage.length; i++) {
  285. if (value.indexOf(this.selectedImage[i]) == -1) list.push(this.selectedImage[i]);
  286. }
  287. parent.$f.changeField(parentinputname, list);
  288. parent.$f.closeModal(parentinputname);
  289. } else {
  290. //独立图片选择页面
  291. if (maxLength > 0) {
  292. if (this.selectedImage.length > maxLength) {
  293. return layList.msg('最多能选择' + maxLength + '张');
  294. }
  295. parent.changeIMG(parentinputname, this.selectedImage, 1);
  296. } else {
  297. if (this.selectedImage.length > 1) {
  298. return layList.msg('只能选择一张图片');
  299. }
  300. parent.changeIMG(parentinputname, this.selectedImage[0]);
  301. }
  302. var index = parent.layer.getFrameIndex(window.name);
  303. parent.layer.close(index);
  304. }
  305. }
  306. },
  307. //图片选中和取消
  308. selectImage: function (item, index) {
  309. if (!item.selected) {
  310. if (maxLength) {
  311. if (this.selectedImage.length === maxLength) {
  312. return layList.msg('最多选择' + maxLength + '张图片');
  313. }
  314. } else {
  315. if (parentinputname.indexOf('editor') === -1) {
  316. if (this.selectedImage.length) {
  317. return layList.msg('只能选择1张图片');
  318. }
  319. }
  320. }
  321. }
  322. this.$set(item, 'selected', item.selected == undefined ? true : !item.selected);
  323. var val = small == 1 ? item['satt_dir'] : item['att_dir'];
  324. if (item.selected === true) {
  325. this.selectedImage[this.selectedImage.length] = val;
  326. this.selectedImageIDS[this.selectedImage.length] = item['att_id'];
  327. item.number = this.selectedImage.length;
  328. } else {
  329. this.selectedImage.splice(this.selectedImage.indexOf(val), 1);
  330. this.selectedImageIDS.splice(this.selectedImage.indexOf(item['att_id']), 1);
  331. for (var i = 0; i < this.imageList.length; i++) {
  332. if (this.imageList[i].number > item.number) {
  333. this.imageList[i].number = (this.imageList[i].number - 1) >= 0 ? this.imageList[i].number - 1 : 0;
  334. }
  335. }
  336. item.number = 0;
  337. }
  338. this.$set(this, 'selectedImage', this.selectedImage);
  339. this.$set(this, 'selectedImageIDS', this.selectedImageIDS);
  340. },
  341. //获取图片列表
  342. getImageList: function () {
  343. var that = this;
  344. if (that.loading) return;
  345. that.loading = true;
  346. var index = layList.layer.load(1, {shade: [0.1, '#fff']});
  347. layList.baseGet(this.U({
  348. a: 'get_image_list',
  349. q: {pid: this.pid, page: this.page, limit: this.limit, title: that.searchContent}
  350. }), function (res) {
  351. that.loading = false;
  352. var list = res.data.list;
  353. for (var i = list.length; i--;) {
  354. list[i].disabled = true;
  355. list[i].hover = false;
  356. if (!list[i].title) {
  357. list[i].title = list[i].name.slice(0, list[i].name.lastIndexOf('.'));
  358. }
  359. }
  360. that.$set(that, 'imageList', res.data.list);
  361. layList.layer.close(index);
  362. if (that.page == 1) {
  363. layList.laypage.render({
  364. elem: that.$refs['main-footer']
  365. , count: res.data.count
  366. , limit: that.limit
  367. , theme: '#191C6E',
  368. jump: function (obj) {
  369. that.page = obj.curr;
  370. }
  371. });
  372. }
  373. }, function () {
  374. that.loading = false;
  375. layList.layer.close(index);
  376. });
  377. },
  378. //查询分类
  379. search: function () {
  380. this.getCategoryList();
  381. },
  382. //打开和关闭树形
  383. OpenTree: function (item, index) {
  384. this.searchContent = '';
  385. this.pid = item.id;
  386. if (item.child.length) {
  387. item.isOpen == undefined ? false : item.isOpen;
  388. this.$set(this.categoryList[index], 'isOpen', !item.isOpen);
  389. } else {
  390. this.page = 1;
  391. this.$set(this, 'selectedImage', []);
  392. this.$set(this, 'selectedImageIDS', []);
  393. this.getImageList();
  394. }
  395. this.uploadInst.reload({
  396. url: this.U({a: 'upload'}) + '?pid=' + this.pid
  397. });
  398. },
  399. //组装URL
  400. U: function (opt) {
  401. opt = typeof opt == 'object' ? opt : {};
  402. return layList.U({m: 'merchant', c: "widget.images", a: opt.a || '', q: opt.q || {}, p: opt.q || {}});
  403. },
  404. //获取分类
  405. getCategoryList: function () {
  406. var that = this;
  407. layList.baseGet(that.U({a: 'get_image_cate', q: {name: this.searchTitle}}), function (res) {
  408. that.$set(that, 'categoryList', res.data);
  409. });
  410. },
  411. //鼠标移入显示图标
  412. changeActive: function (item, indexK, index) {
  413. if (index)
  414. this.$set(this.categoryList[indexK]['child'], 'isShow', true);
  415. else
  416. this.$set(this.categoryList[indexK], 'isShow', true);
  417. },
  418. //鼠标移出隐藏
  419. removeActive: function (item, indexK, index) {
  420. if (index)
  421. this.$set(this.categoryList[indexK]['child'], 'isShow', false);
  422. else
  423. this.$set(this.categoryList[indexK], 'isShow', false);
  424. },
  425. //添加分类
  426. addCategory: function (item, pid) {
  427. item = item == undefined ? {} : item;
  428. var id = item.id == undefined ? 0 : item.id,
  429. pid = pid == undefined ? 0 : pid;
  430. return this.getOpenWindow(item.name ? item.name + '编辑' : '新增分类', this.U({
  431. a: 'addcate',
  432. q: {id: pid == 0 ? id : pid}
  433. }));
  434. },
  435. //修改分类
  436. updateCategory: function (item, pid) {
  437. item = item == undefined ? {} : item;
  438. pid = pid == undefined ? 0 : pid;
  439. return this.getOpenWindow(item.name + '编辑', this.U({a: 'editcate', q: {id: item.id}}));
  440. },
  441. //删除分类
  442. delCategory: function (item, pid) {
  443. var that = this;
  444. if (item.child.length) return layList.msg('请先删除子分类再尝试删除此分类!');
  445. layList.layer.confirm('是否要删除[' + item.name + ']分类?', {
  446. btn: ['是的我要删除', '我想想吧'] //按钮
  447. }, function () {
  448. layList.baseGet(that.U({a: 'deletecate', q: {id: item.id}}), function (res) {
  449. layList.msg(res.msg, function () {
  450. that.getCategoryList();
  451. });
  452. }, function (err) {
  453. layList.msg(err.msg);
  454. });
  455. });
  456. },
  457. //打开一个窗口
  458. getOpenWindow: function (title, url, opt) {
  459. opt = opt || {};
  460. return layList.layer.open({
  461. type: 2,
  462. title: title,
  463. shade: [0],
  464. area: [opt.w || 340 + "px", opt.h || 265 + 'px'],
  465. anim: 2,
  466. content: [url, 'no'],
  467. end: opt.end || null
  468. });
  469. },
  470. //回调
  471. SuccessCateg: function () {
  472. this.getCategoryList();
  473. },
  474. renderUpload: function () {
  475. var vm = this;
  476. this.uploadInst = layui.upload.render({
  477. elem: this.$refs.upload,
  478. url: this.U({a: 'upload'}),
  479. acceptMime: 'image/*',
  480. size: 2097152,
  481. before: function (obj) {
  482. layui.layer.load(1);
  483. vm.files = obj.pushFile();
  484. var file;
  485. for (var key in vm.files) {
  486. if (Object.hasOwnProperty.call(vm.files, key)) {
  487. file = vm.files[key];
  488. }
  489. }
  490. this.data = {
  491. pid: vm.pid,
  492. title: file.name.slice(0, file.name.lastIndexOf('.'))
  493. };
  494. },
  495. done: function (res, index, upload) {
  496. for (var key in vm.files) {
  497. if (Object.hasOwnProperty.call(vm.files, key)) {
  498. delete vm.files[key];
  499. }
  500. }
  501. layui.layer.closeAll('loading');
  502. layui.layer.msg(res.msg);
  503. vm.page = 1;
  504. vm.getImageList();
  505. },
  506. error: function (index, upload) {
  507. layui.layer.closeAll('loading');
  508. }
  509. });
  510. }
  511. },
  512. mounted: function () {
  513. this.getCategoryList();
  514. this.getImageList();
  515. window.SuccessCateg = this.SuccessCateg;
  516. this.renderUpload();
  517. }
  518. });
  519. </script>