add-edit.php 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647
  1. <div id="app" v-cloak>
  2. <el-card shadow="never" style="border:0" class="box-card" body-style="background-color: #f3f3f3;padding: 10px 0 0;" v-loading="cardLoading" v-loading="cardLoading">
  3. <div slot="header">
  4. <div flex="cross:center box:first">
  5. <div><span @click="$navigate({r:'mall/cate/index'})" class="text">分类</span>/分类编辑</div>
  6. <div flex="dir:right">
  7. <div>
  8. <el-button class="button-item" :loading="btnLoading" type="primary" @click="store('ruleForm')" size="small">保存</el-button>
  9. </div>
  10. </div>
  11. </div>
  12. </div>
  13. <div class="form-body">
  14. <el-form :model="ruleForm" :rules="rules" size="small" ref="ruleForm" label-width="120px">
  15. <el-form-item label="选择分类级别">
  16. <div flex="dir:left" class="radio-box">
  17. <div @click="changeParent(1)">
  18. <el-radio :disabled="ruleForm.id ? true : false" v-model="currentRadioKey" :label="1">一级分类</el-radio>
  19. </div>
  20. <div @click="changeParent(2)">
  21. <el-radio :disabled="ruleForm.id ? true : false" v-model="currentRadioKey" :label="2">二级分类</el-radio>
  22. </div>
  23. <div @click="changeParent(3)">
  24. <el-radio :disabled="ruleForm.id ? true : false" v-model="currentRadioKey" :label="3">三级分类</el-radio>
  25. </div>
  26. </div>
  27. </el-form-item>
  28. <el-form-item v-if="currentCatLevelShow == 2 && currentCatShow.value" label="一级分类">
  29. <div flex="dir:left">
  30. <div>{{currentCatShow.label}}</div>
  31. <div v-if="!ruleForm.id" @click="changeParent(currentCatLevelShow)" class="cat-edit-text">修改</div>
  32. </div>
  33. </el-form-item>
  34. <template v-if="currentCatLevelShow == 3 && currentCatShow.value">
  35. <el-form-item label="一级分类">
  36. <div flex="dir:left">
  37. <div>{{currentCatShow.label}}</div>
  38. <div v-if="!currentCatShow.oneChildren && !ruleForm.id" @click="changeParent(currentCatLevelShow)" class="cat-edit-text">修改
  39. </div>
  40. </div>
  41. </el-form-item>
  42. <el-form-item v-if="currentCatShow.oneChildren" label="二级分类">
  43. <div flex="dir:left">
  44. <div>{{currentCatShow.oneChildren.label}}</div>
  45. <div v-if="!ruleForm.id" @click="changeParent(currentCatLevelShow)" class="cat-edit-text">修改</div>
  46. </div>
  47. </el-form-item>
  48. </template>
  49. <el-form-item label="分类名称" prop="name">
  50. <el-input v-model="ruleForm.name"></el-input>
  51. </el-form-item>
  52. <el-form-item prop="sort">
  53. <template slot='label'>
  54. <span>排序</span>
  55. <el-tooltip effect="dark" content="排序值越小排序越靠前" placement="top">
  56. <i class="el-icon-info"></i>
  57. </el-tooltip>
  58. </template>
  59. <el-input type="number" v-model="ruleForm.sort"></el-input>
  60. </el-form-item>
  61. <el-form-item label="分类图标" prop="pic">
  62. <com-attachment :multiple="false" :max="1" v-model="ruleForm.pic">
  63. <el-tooltip effect="dark" content="建议尺寸200*200" placement="top">
  64. <el-button style="margin-bottom: 10px;" size="mini">选择文件</el-button>
  65. </el-tooltip>
  66. </com-attachment>
  67. <com-gallery :url="ruleForm.pic" :show-delete="true" @deleted="ruleForm.pic = ''" width="80px" height="80px">
  68. </com-gallery>
  69. </el-form-item>
  70. <template>
  71. <el-form-item prop="advert_pic" :rules="ruleForm.advert_pic&&ruleForm.advert_pic.length > 0 ? rules.advert_pic : [{required: true, message: '请选择图片', trigger: 'change'}]" class="com-goods">
  72. <template slot="label">
  73. <span>分类广告图</span>
  74. </template>
  75. <div class="pic-url-remark">
  76. 可拖拽使其改变顺序,最多支持上传9张
  77. </div>
  78. <div flex="dir:left">
  79. <draggable v-model="ruleForm.advert_pic" flex>
  80. <template v-if="ruleForm.advert_pic && ruleForm.advert_pic.length>0">
  81. <div v-for="(item,index) in ruleForm.advert_pic" :key="index" style="margin-right: 20px;position: relative;cursor: move;">
  82. <com-attachment @selected="selectedAdvertPic" :params="{'currentIndex': index}">
  83. <com-image mode="aspectFill" width="100px" height='100px' :src="item"> </com-image>
  84. </com-attachment>
  85. <el-button class="del-btn" size="mini" type="danger" icon="el-icon-close" circle @click="delPic(index)"></el-button>
  86. </div>
  87. </template>
  88. </draggable>
  89. <template v-if="ruleForm.advert_pic&&ruleForm.advert_pic.length < 9">
  90. <com-attachment style="margin-bottom: 10px;" :multiple="true" :max="9" @selected="selectedAdvertPic">
  91. <el-tooltip class="item" effect="dark" content="建议尺寸:750 * 750" placement="top">
  92. <div flex="main:center cross:center" class="add-image-btn">
  93. + 添加图片
  94. </div>
  95. </el-tooltip>
  96. </com-attachment>
  97. </template>
  98. </div>
  99. </el-form-item>
  100. <el-form-item label="收取服务费" prop="is_collect_service_fee">
  101. <el-radio v-model="ruleForm.is_collect_service_fee" label="0">免服务费</el-radio>
  102. <el-radio v-model="ruleForm.is_collect_service_fee" label="1">收取服务费</el-radio>
  103. </el-form-item>
  104. <el-form-item label="服务费比例" prop="collect_service_fee">
  105. <el-input placeholder="" class="width-150" v-model="ruleForm.collect_service_fee" onkeyup="value=toNumber(value,2)">
  106. <template slot="append">%</template>
  107. </el-input>
  108. </el-form-item>
  109. <el-form-item label="分类广告链接" prop="advert_url">
  110. <el-input size="small" v-model="advertUrl" placeholder="点击选择链接">
  111. <com-pick-link @selected="selectAdvertUrl" slot="append">
  112. <el-button size="small">选择链接</el-button>
  113. </com-pick-link>
  114. </el-input>
  115. </el-form-item>
  116. </template>
  117. <el-form-item label="是否启用" prop="status">
  118. <el-switch v-model="ruleForm.status" :active-value="1" :inactive-value="0"></el-switch>
  119. </el-form-item>
  120. <el-form-item label="是否显示" prop="is_show">
  121. <el-switch v-model="ruleForm.is_show" :active-value="1" :inactive-value="0"></el-switch>
  122. </el-form-item>
  123. </el-form>
  124. </div>
  125. </el-card>
  126. <div class="el-dialog-1">
  127. <el-dialog title="选择归属的一级分类" :visible.sync="dialogVisible1" width="20%">
  128. <el-form v-loading="dialogLoading" size="small" :inline="true" :model="search" @submit.native.prevent>
  129. <el-form-item>
  130. <div class="search-input-item">
  131. <el-input style="width:100%" @keyup.enter.native="searchCat" size="small" placeholder="请输入分类名称搜索" v-model="search.keyword" clearable @clear="searchCat">
  132. <el-button slot="append" icon="el-icon-search" @click="searchCat"></el-button>
  133. </el-input>
  134. </div>
  135. </el-form-item>
  136. <div class="dialog-cat-box">
  137. <el-table :show-header="false" :data="catList1" highlight-current-row @current-change="tableRowClick" :row-class-name="tableRowClassName" style="width: 100%">
  138. <el-table-column prop="label"></el-table-column>
  139. </el-table>
  140. </div>
  141. </el-form>
  142. <span slot="footer" class="dialog-footer">
  143. <el-button size="small" @click="dialogVisible1 = false">取 消</el-button>
  144. <el-button size="small" type="primary" @click="selectCatSubmit">确 定</el-button>
  145. </span>
  146. </el-dialog>
  147. </div>
  148. <div class="el-dialog-2">
  149. <el-dialog title="选择归属的二级分类" :visible.sync="dialogVisible2" width="30%">
  150. <el-form v-loading="dialogLoading" size="small" :inline="true" :model="search" @submit.native.prevent>
  151. <el-form-item>
  152. <div class="search-input-item">
  153. <el-input style="width:100%" @keyup.enter.native="searchCat" size="small" placeholder="请输入分类名称搜索" v-model="search.keyword" clearable @clear="searchCat">
  154. <el-button slot="append" icon="el-icon-search" @click="searchCat"></el-button>
  155. </el-input>
  156. </div>
  157. </el-form-item>
  158. <div flex="dir:left">
  159. <div class="dialog-cat-box">
  160. <el-table :show-header="false" :data="catList2" highlight-current-row @current-change="tableRowClick" :row-class-name="tableRowClassName2" style="width: 100%">
  161. <el-table-column>
  162. <template slot-scope="scope">
  163. <div flex="box:last">
  164. <div>{{scope.row.label}}</div>
  165. <div v-if="scope.row.child">
  166. <i class="el-icon-arrow-right"></i>
  167. </div>
  168. </div>
  169. </template>
  170. </el-table-column>
  171. </el-table>
  172. </div>
  173. <div class="dialog-cat-box">
  174. <el-table :show-header="false" :data="catList3" highlight-current-row @current-change="tableRowClick2" :row-class-name="tableRowClassName3" style="width: 100%">
  175. <el-table-column prop="label">
  176. </el-table-column>
  177. </el-table>
  178. </div>
  179. </div>
  180. </el-form>
  181. <span slot="footer" class="dialog-footer">
  182. <el-button size="small" @click="dialogVisible2 = false">取 消</el-button>
  183. <el-button size="small" type="primary" @click="selectCatSubmit">确 定</el-button>
  184. </span>
  185. </el-dialog>
  186. </div>
  187. <el-dialog :title="imageShowData.title" :visible.sync="imageDialogVisible" width="20%">
  188. <div class="image-show-box" flex="main:center">
  189. <image :src="imageShowData.image_url"></image>
  190. </div>
  191. <div slot="footer">
  192. <el-button type="primary" size="small" @click="imageDialogVisible = false">我知道了</el-button>
  193. </div>
  194. </el-dialog>
  195. </div>
  196. <script src="/resources/js/Sortable.min.js"></script>
  197. <script src="/resources/unpkg/vuedraggable@2.18.1/dist/vuedraggable.umd.min.js"></script>
  198. <script>
  199. const app = new Vue({
  200. el: '#app',
  201. data() {
  202. return {
  203. ruleForm: {
  204. pic: '',
  205. big_pic: '',
  206. advert_pic: [],
  207. status: 1,
  208. advert_url: {},
  209. sort: 100,
  210. is_show: 1,
  211. advert_open_type: '',
  212. advert_params: '',
  213. is_collect_service_fee: '0',
  214. collect_service_fee: 0,
  215. },
  216. parentIds: [],
  217. options: [],
  218. rules: {
  219. name: [{
  220. required: true,
  221. message: '请输入分类名称',
  222. trigger: 'change'
  223. },
  224. {
  225. min: 1,
  226. max: 16,
  227. message: '长度在 1 到 16 个字符',
  228. trigger: 'blur'
  229. }
  230. ],
  231. sort: [{
  232. required: true,
  233. message: '请输入排序',
  234. trigger: 'change'
  235. }, ],
  236. },
  237. btnLoading: false,
  238. cardLoading: false,
  239. dialogVisible1: false,
  240. dialogVisible2: false,
  241. search: {
  242. keyword: ''
  243. },
  244. catList1: [],
  245. catList2: [],
  246. catList3: [],
  247. dialogLoading: false,
  248. currentCat: null,
  249. currentCatShow: null,
  250. currentCatLevel: 1,
  251. currentCatLevelShow: 1,
  252. imageDialogVisible: false,
  253. imageShowData: {
  254. title: '',
  255. image_url: ''
  256. },
  257. currentRadioKey: 1,
  258. advertUrl: '', // 广告链接
  259. };
  260. },
  261. mounted: function() {
  262. this.getOptions();
  263. },
  264. methods: {
  265. store(formName) {
  266. this.$refs[formName].validate((valid) => {
  267. let self = this;
  268. if (valid) {
  269. self.btnLoading = true;
  270. this.ruleForm.parent_id = this.parentIds[this.parentIds.length - 1];
  271. request({
  272. params: {
  273. r: 'store/store-category/storage'
  274. },
  275. method: 'post',
  276. data: {
  277. form: self.ruleForm,
  278. }
  279. }).then(e => {
  280. self.btnLoading = false;
  281. if (e.data.code == 0) {
  282. self.$message.success(e.data.msg);
  283. navigateTo({
  284. r: 'store/store-category/index'
  285. })
  286. } else {
  287. self.$message.error(e.data.msg);
  288. }
  289. }).catch(e => {
  290. self.$message.error(e.data.msg);
  291. self.btnLoading = false;
  292. });
  293. } else {
  294. console.log('error submit!!');
  295. return false;
  296. }
  297. });
  298. },
  299. getOptions() {
  300. let self = this;
  301. request({
  302. params: {
  303. r: 'store/store-category/storage',
  304. id: getQuery('id'),
  305. keyword: this.search.keyword
  306. },
  307. method: 'get',
  308. }).then(e => {
  309. // console.log(e, '=======');
  310. this.dialogLoading = false;
  311. if (e.data.code == 0) {
  312. if (!Array.isArray(e.data.data.detail)) {
  313. self.ruleForm = e.data.data.detail;
  314. self.handleData();
  315. self.ruleForm.is_collect_service_fee = self.ruleForm.is_collect_service_fee.toString();
  316. }
  317. if (e.data.data.detail.advert_url) {
  318. this.advertUrl = e.data.data.detail.advert_url.title + ' [ ' + e.data.data.detail.advert_url.route + ' ]';
  319. } else {
  320. this.advertUrl = '';
  321. }
  322. self.options = e.data.data.cates;
  323. self.setCatList1();
  324. self.setCatList2();
  325. } else {
  326. self.$message.error(e.data.msg);
  327. }
  328. }).catch(e => {
  329. console.log(e);
  330. });
  331. },
  332. // 所有一级分类列表
  333. setCatList1() {
  334. let self = this;
  335. self.catList1 = [];
  336. self.options.forEach(function(item) {
  337. if (self.ruleForm.id != item.value) {
  338. self.catList1.push({
  339. label: item.label,
  340. value: item.value,
  341. })
  342. }
  343. });
  344. },
  345. // 所有二级分类列表
  346. setCatList2() {
  347. let self = this;
  348. self.catList2 = [];
  349. self.options.forEach(function(item) {
  350. if (self.ruleForm.id != item.value) {
  351. self.catList2.push({
  352. label: item.label,
  353. value: item.value,
  354. child: item.children ? item.children : null,
  355. });
  356. }
  357. });
  358. },
  359. // 所有三级分类列表
  360. setCatList3(list) {
  361. let self = this;
  362. self.catList3 = [];
  363. if (list) {
  364. list.forEach(function(item) {
  365. if (self.ruleForm.id != item.value) {
  366. self.catList3.push({
  367. label: item.label,
  368. value: item.value,
  369. });
  370. }
  371. });
  372. }
  373. },
  374. // 分类 编辑时数据处理
  375. handleData() {
  376. let self = this;
  377. self.currentCatShow = {};
  378. self.parentIds = [];
  379. self.currentRadioKey = self.ruleForm.parents.length + 1;
  380. self.currentCatLevelShow = self.ruleForm.parents.length + 1;
  381. let parents = self.ruleForm.parents.reverse();
  382. parents.forEach(function(item, index) {
  383. self.parentIds.push(item.id);
  384. // 一级分类
  385. if (index === 0) {
  386. self.currentCatShow.label = item.name;
  387. self.currentCatShow.value = item.id;
  388. }
  389. // 二级分类
  390. if (index === 1) {
  391. self.currentCatShow.oneChildren = {
  392. label: item.name,
  393. value: item.id
  394. }
  395. }
  396. })
  397. },
  398. selectAdvertUrl(e) {
  399. // console.log('kkkkkkkk: ', e);
  400. let self = this;
  401. if (e.length) {
  402. self.ruleForm.advert_url = e[0];
  403. self.advertUrl = e[0].title + ' [ ' + e[0].route + ' ]';
  404. }
  405. // console.log('jjjjjjj: ', self.ruleForm);
  406. },
  407. changeParent(catLevel) {
  408. if (this.ruleForm.id) {
  409. return false;
  410. }
  411. this.currentRadioKey = catLevel;
  412. if (catLevel !== 1) {
  413. this.currentCatLevel = catLevel;
  414. if (this.currentCatShow) {
  415. this.currentCat = this.currentCatShow;
  416. }
  417. if (catLevel === 2) {
  418. this.setCatList1();
  419. this.dialogVisible1 = true;
  420. }
  421. if (catLevel === 3) {
  422. this.setCatList2();
  423. this.dialogVisible2 = true;
  424. }
  425. } else {
  426. this.currentCat = null;
  427. this.currentCatShow = {};
  428. this.parentIds = [];
  429. }
  430. },
  431. searchCat() {
  432. this.dialogLoading = true;
  433. this.getOptions();
  434. },
  435. // 选择分类 表格行点击事件
  436. tableRowClick(currentRow, oldCurrentRow) {
  437. if (currentRow) {
  438. this.currentCat = currentRow;
  439. if (this.currentCatLevel === 3) {
  440. this.setCatList3(currentRow.child)
  441. }
  442. }
  443. },
  444. tableRowClick2(currentRow, oldCurrentRow) {
  445. this.currentCat.oneChildren = currentRow;
  446. },
  447. // 选择分类 确认事件
  448. selectCatSubmit() {
  449. this.dialogVisible1 = false;
  450. this.dialogVisible2 = false;
  451. this.currentCatShow = this.currentCat;
  452. this.currentCatLevelShow = this.currentCatLevel;
  453. if (this.currentCatShow) {
  454. this.parentIds = [];
  455. this.parentIds.push(this.currentCatShow.value);
  456. if (this.currentCatShow.oneChildren) {
  457. this.parentIds.push(this.currentCatShow.oneChildren.value);
  458. }
  459. }
  460. if (this.currentCatLevel == 3 && !this.currentCat.oneChildren) {
  461. this.currentRadioKey = 2;
  462. this.currentCatLevel = 2;
  463. this.currentCatLevelShow = 2;
  464. }
  465. },
  466. imageShow(type) {
  467. this.imageDialogVisible = true;
  468. if (type === 1) {
  469. this.imageShowData.title = '分类大图图例';
  470. this.imageShowData.image_url = 'resources/img/mall/cat/example-1.png';
  471. }
  472. if (type === 2) {
  473. this.imageShowData.title = '分类广告图图例';
  474. this.imageShowData.image_url = 'resources/img/mall/cat/example-2.png';
  475. }
  476. },
  477. tableRowClassName({
  478. row,
  479. rowIndex
  480. }) {
  481. if (this.currentCat && this.currentCat.value == row.value) {
  482. return 'current-row';
  483. }
  484. return '';
  485. },
  486. tableRowClassName2({
  487. row,
  488. rowIndex
  489. }) {
  490. console.log(this.currentCat)
  491. console.log(row.value)
  492. if (this.currentCat && this.currentCat.value == row.value) {
  493. this.currentCat.child = row.child;
  494. this.catList3 = row.child;
  495. return 'current-row';
  496. }
  497. return '';
  498. },
  499. tableRowClassName3({
  500. row,
  501. rowIndex
  502. }) {
  503. if (this.currentCat && this.currentCat.oneChildren &&
  504. this.currentCat.oneChildren.value == row.value) {
  505. return 'current-row';
  506. }
  507. return '';
  508. },
  509. // 选中图片
  510. selectedAdvertPic(e) {
  511. console.log('ttttt: ', e);
  512. this.ruleForm.advert_pic.push(e[0].url);
  513. },
  514. // 删除图片
  515. delPic(index) {
  516. this.ruleForm.advert_pic.splice(index, 1)
  517. },
  518. }
  519. });
  520. </script>
  521. <style>
  522. .form-body {
  523. padding: 20px 0;
  524. background-color: #fff;
  525. margin-bottom: 20px;
  526. padding-right: 50%;
  527. }
  528. .form-button {
  529. margin: 0;
  530. }
  531. .form-button .el-form-item__content {
  532. margin-left: 0 !important;
  533. }
  534. .button-item {
  535. padding: 9px 25px;
  536. }
  537. .radio-box div {
  538. margin-right: 20px;
  539. }
  540. .input-item {
  541. display: inline-block;
  542. width: 250px;
  543. margin: 0;
  544. }
  545. .input-item .el-input__inner {
  546. border-right: 0;
  547. }
  548. .input-item .el-input__inner:hover {
  549. border: 1px solid #dcdfe6;
  550. border-right: 0;
  551. outline: 0;
  552. }
  553. .input-item .el-input__inner:focus {
  554. border: 1px solid #dcdfe6;
  555. border-right: 0;
  556. outline: 0;
  557. }
  558. .input-item .el-input-group__append {
  559. background-color: #fff;
  560. border-left: 0;
  561. width: 10%;
  562. padding: 0 10px;
  563. }
  564. .input-item .el-input-group__append .el-button {
  565. padding: 15px;
  566. }
  567. .el-dialog-1 .el-dialog {
  568. min-width: 350px;
  569. }
  570. .dialog-cat-box {
  571. border: 1px solid #E3E3E3;
  572. height: 250px;
  573. -webkit-border-radius: 5px;
  574. -moz-border-radius: 5px;
  575. border-radius: 5px;
  576. width: 100%;
  577. margin-right: 10px;
  578. overflow-y: auto;
  579. }
  580. .el-dialog__body {
  581. padding: 10px 20px;
  582. }
  583. .el-table td,
  584. .el-table th {
  585. padding: 5px 0;
  586. }
  587. .cat-edit-text {
  588. color: #409EFF;
  589. margin-left: 10px;
  590. cursor: pointer;
  591. }
  592. .com-gallery .com-gallery-item {
  593. margin-bottom: 0;
  594. margin-right: 0;
  595. cursor: pointer;
  596. }
  597. .show-example {
  598. cursor: pointer;
  599. color: #409EFF;
  600. }
  601. .text {
  602. cursor: pointer;
  603. color: #419EFB;
  604. }
  605. .pic-url-remark {
  606. font-size: 13px;
  607. color: #c9c9c9;
  608. margin-bottom: 12px;
  609. }
  610. .add-image-btn {
  611. width: 100px;
  612. height: 100px;
  613. color: #419EFB;
  614. border: 1px solid #e2e2e2;
  615. cursor: pointer;
  616. }
  617. .del-btn {
  618. position: absolute;
  619. top: -4%;
  620. right: -4%;
  621. }
  622. </style>