index.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497
  1. <template>
  2. <div class="app-container">
  3. <div class="setting_title">轮播图管理</div>
  4. <el-divider></el-divider>
  5. <div class="mymain-container">
  6. <div class="btn-group clearfix">
  7. <div class="fl">
  8. <el-button size="small" type="primary" icon="el-icon-plus" @click="addOrEdit('add')">新增轮播图</el-button>
  9. <el-button size="small" type="danger" icon="el-icon-minus" @click="batchDelete()">批量删除</el-button>
  10. </div>
  11. <div class="fr">
  12. <el-select v-model="screenForm.state" placeholder="全部" size="small" style="width: 150px; margin-right: 10px;" @change="getListByScreen">
  13. <el-option label="全部状态" value=""></el-option>
  14. <el-option v-for="(item, index) in select_state" :key="index" :label="item.label" :value="item.value"></el-option>
  15. </el-select>
  16. </div>
  17. </div>
  18. <div class="table">
  19. <el-table ref="multipleTable" v-loading="listLoading" :data="dataList" element-loading-text="Loading" border fit highlight-current-row stripe>
  20. <el-table-column type="selection" width="55" align="center"></el-table-column>
  21. <el-table-column align="center" label="操作" min-width="140">
  22. <template slot-scope="scope">
  23. <el-button type="text" style="margin-right: 10px;" @click="addOrEdit('edit', scope.row.id)">编辑</el-button>
  24. <el-popconfirm v-if="scope.row.state" title="确定隐藏吗?" @onConfirm="changeStatus(scope.row.id, 0)" >
  25. <el-button slot="reference" type="text">隐藏</el-button>
  26. </el-popconfirm>
  27. <el-popconfirm v-else title="确定显示吗?" @onConfirm="changeStatus(scope.row.id, 1)" >
  28. <el-button slot="reference" type="text">显示</el-button>
  29. </el-popconfirm>
  30. <el-popconfirm style="margin-left: 10px;" title="确定删除吗?" @onConfirm="handleDelete(scope.row.id)">
  31. <el-button slot="reference" type="text">删除</el-button>
  32. </el-popconfirm>
  33. </template>
  34. </el-table-column>
  35. <el-table-column align="center" label="轮播图名称" prop="carouselName" min-width="140"></el-table-column>
  36. <el-table-column align="center" label="排序" prop="sortNum"></el-table-column>
  37. <el-table-column align="center" label="创建人" prop="adminNickName" min-width="160"></el-table-column>
  38. <el-table-column align="center" label="创建时间" prop="createTime" min-width="160"></el-table-column>
  39. <el-table-column align="center" label="状态" class-name="status-col">
  40. <template slot-scope="scope">
  41. <el-tag :type="scope.row.state ? 'success':'danger'">{{ scope.row.state ? '显示':'隐藏' }}</el-tag>
  42. </template>
  43. </el-table-column>
  44. </el-table>
  45. </div>
  46. <div class="pagination clearfix">
  47. <div class="fr">
  48. <el-pagination
  49. @size-change="handleSizeChange"
  50. @current-change="handleCurrentChange"
  51. :current-page="currentPage"
  52. :page-sizes="[10, 20, 30, 50]"
  53. :page-size="10"
  54. layout="total, sizes, prev, pager, next, jumper"
  55. :total="listTotal">
  56. </el-pagination>
  57. </div>
  58. </div>
  59. </div>
  60. <!-- 新增编辑 -->
  61. <el-dialog :title="addFormType === 'add' ? '新增轮播图':'编辑轮播图'" :visible.sync="addFormVisible" :show-close="false" width="50%" :close-on-click-modal="false">
  62. <el-form ref="addForm" :model="addForm" :rules="addFormRules" label-position="left" label-width="100px">
  63. <el-form-item label="轮播图名称" prop="bannerName">
  64. <el-input v-model="addForm.bannerName" autocomplete="off" placeholder="请输入轮播图名称"></el-input>
  65. </el-form-item>
  66. <el-form-item label="轮播图" prop="imgUrl">
  67. <el-upload
  68. class="avatar-uploader"
  69. :action="baseURL + 'common/upload'"
  70. :headers="myHeaders"
  71. :show-file-list="false"
  72. :on-success="uploadSuccess"
  73. :before-upload="beforeUpload">
  74. <img v-if="addForm.imgUrl" :src="addForm.imgUrl" class="avatar">
  75. <i v-else class="el-icon-plus avatar-uploader-icon"></i>
  76. </el-upload>
  77. <div class="tips">
  78. <span>支持上传jpg/png文件,尺寸比例为:710*350</span>
  79. </div>
  80. </el-form-item>
  81. <el-form-item label="排序" prop="sortNum">
  82. <el-input v-model="addForm.sortNum" autocomplete="off" placeholder="请输入整数(降序显示轮播顺序)"></el-input>
  83. </el-form-item>
  84. <el-form-item label="链接类型" prop="type">
  85. <el-radio-group v-model="addForm.type">
  86. <el-radio :label="1">商品链接</el-radio>
  87. <el-radio :label="2">凡科活动链接</el-radio>
  88. <el-radio :label="3">专区活动链接</el-radio>
  89. </el-radio-group>
  90. </el-form-item>
  91. <el-form-item label="链接商品" prop="goodsId" v-if="addForm.type === 1">
  92. <el-button @click="showGoods" size="small">查找商品</el-button>
  93. <el-button @click="clearGoodsId" size="small">清除</el-button>
  94. </el-form-item>
  95. <el-form-item label="链接商品名称" prop="goodsName" v-if="addForm.type === 1">
  96. <el-input disabled v-model="selGoodsName"></el-input>
  97. </el-form-item>
  98. <el-form-item label="活动APPID" prop="appid" v-if="addForm.type === 2">
  99. <el-input v-model="addForm.appid" autocomplete="off" placeholder="请输入活动APPID"></el-input>
  100. </el-form-item>
  101. <el-form-item label="活动路径" prop="link" v-if="addForm.type === 2">
  102. <el-input v-model="addForm.link" autocomplete="off" placeholder="请输入活动路径"></el-input>
  103. </el-form-item>
  104. <el-form-item label="选择活动" prop="goodsId" v-if="addForm.type === 3">
  105. <el-select v-model="addForm.goodsId" placeholder="请选择活动">
  106. <el-option
  107. v-for="item in activityList"
  108. :key="item.type"
  109. :label="item.name"
  110. :value="item.type">
  111. </el-option>
  112. </el-select>
  113. </el-form-item>
  114. </el-form>
  115. <el-dialog
  116. width="50%"
  117. title="商品列表"
  118. :visible.sync="innerVisible"
  119. append-to-body>
  120. <el-input v-model="search" placeholder="输入名称搜索">
  121. <el-button slot="append" icon="el-icon-search" @click="searchGoods()"></el-button>
  122. </el-input>
  123. <div class="table" style="margin-top: 10px">
  124. <el-table
  125. :data="goodsList"
  126. height="400px"
  127. style="width: 100%">
  128. <el-table-column align="center">
  129. <template slot="header"></template>
  130. <template slot-scope="scope">
  131. <el-button type="primary" size="small" @click="selGoods(scope.row)" :disabled="scope.row.promotionGroup" >选择</el-button>
  132. </template>
  133. </el-table-column>
  134. <el-table-column label="商品名称" prop="goodsName"></el-table-column>
  135. <el-table-column label="商品图片" prop="imgUrl" align="center">
  136. <template slot-scope="scope">
  137. <div class="demo-image__preview">
  138. <el-image style="width: 40px; height: 40px" :src="scope.row.imgUrl" :preview-src-list="[scope.row.imgUrl]">
  139. <div slot="error" class="image-slot">
  140. <i class="el-icon-picture-outline"></i>
  141. </div>
  142. </el-image>
  143. </div>
  144. </template>
  145. </el-table-column>
  146. </el-table>
  147. </div>
  148. <div class="pagination clearfix">
  149. <div class="fr">
  150. <el-pagination
  151. @size-change="innerHandleSizeChange"
  152. @current-change="innerHandleCurrentChange"
  153. :current-page="innerCurrentPage"
  154. :page-sizes="[10, 20, 30, 50]"
  155. :page-size="10"
  156. layout="total, sizes, prev, pager, next, jumper"
  157. :total="innerListTotal">
  158. </el-pagination>
  159. </div>
  160. </div>
  161. </el-dialog>
  162. <div slot="footer" class="dialog-footer">
  163. <el-button @click="cancelAddForm">取 消</el-button>
  164. <el-button type="primary" @click="submitAddForm">确 定</el-button>
  165. </div>
  166. </el-dialog>
  167. </div>
  168. </template>
  169. <script>
  170. import { mapGetters } from 'vuex'
  171. import { getBannerList, changeBannerStatus, addBanner, editBanner, getBannerDetail, deleteBanner, getGoodsList, batchDeleteBanner } from '@/api/setting'
  172. import { getToken } from '@/utils/auth'
  173. export default {
  174. data() {
  175. let checkInt = (rule, value, callback) => {
  176. if ((Number(value)) && (value) % 1 === 0) {
  177. callback()
  178. } else {
  179. return callback(new Error('请输入整数!'))
  180. }
  181. }
  182. return {
  183. baseURL: process.env.VUE_APP_BASE_API,
  184. myHeaders: {'x-token': getToken()},
  185. dataList: null, // 列表数据
  186. listLoading: true, // 列表加载loading
  187. currentPage: 1, // 当前页码
  188. pageSize: 10, // 每页数量
  189. listTotal: 0, // 列表总数
  190. innerCurrentPage: 1, // 内联当前页码
  191. innerPageSize: 10, // 内联每页数量
  192. innerListTotal: 0, // 内联列表总数
  193. editId: null,
  194. addFormType: 'add',
  195. addFormVisible: false,
  196. addForm: {
  197. imgUrl: '', // 轮播图
  198. bannerName: '', // 轮播图名称
  199. state: true,
  200. goodsId: '',
  201. sortNum: '',
  202. type: 1,
  203. appid: '',
  204. link: '',
  205. },
  206. addFormRules: {
  207. imgUrl: [
  208. { required: true, message: '请上传轮播图', trigger: 'change' }
  209. ],
  210. bannerName: [
  211. { required: true, message: '请输入轮播图名称', trigger: 'blur' }
  212. ],
  213. sortNum: [
  214. { required: false, trigger: 'blur', validator: checkInt }
  215. ],
  216. },
  217. innerVisible: false,
  218. goodsList: [],
  219. search: '',
  220. selGoodsName: '',
  221. select_state: [
  222. { value: 1, label: '显示' },
  223. { value: 0, label: '隐藏' },
  224. ],
  225. screenForm : {
  226. state: ''
  227. },
  228. activityList: [
  229. {type: 2, name: '首页弹窗'},
  230. {type: 3, name: '胶囊图'},
  231. {type: 4, name: '活动专区2-左侧专区'},
  232. {type: 5, name: '活动专区2-右侧专区'},
  233. {type: 6, name: '专场专区-01'},
  234. {type: 7, name: '专场专区-02'},
  235. {type: 8, name: '专场专区-03'},
  236. {type: 9, name: '专场专区-04'},
  237. {type: 10, name: '专题精选-01'},
  238. {type: 11, name: '专题精选-02'},
  239. {type: 12, name: '专题精选-03'},
  240. {type: 13, name: '底部广告图'},
  241. ],
  242. }
  243. },
  244. computed: {
  245. ...mapGetters([
  246. 'userid',
  247. 'name'
  248. ])
  249. },
  250. created() {
  251. this.getList();
  252. },
  253. methods: {
  254. getList() {
  255. this.listLoading = true;
  256. let params = {
  257. state: this.screenForm.state,
  258. pageNum: this.currentPage,
  259. pageSize: this.pageSize
  260. };
  261. getBannerList(params).then(res => {
  262. this.dataList = res.data.records;
  263. this.listTotal = res.data.total;
  264. this.listLoading = false;
  265. })
  266. },
  267. // 筛选后重新获取列表
  268. getListByScreen() {
  269. this.currentPage = 1;
  270. this.getList();
  271. },
  272. // 更改每页数量
  273. handleSizeChange(val) {
  274. this.pageSize = val;
  275. this.currentPage = 1;
  276. this.getList();
  277. },
  278. // 更改当前页
  279. handleCurrentChange(val) {
  280. this.currentPage = val;
  281. this.getList();
  282. },
  283. // 更改内嵌每页数量
  284. innerHandleSizeChange(val) {
  285. this.innerPageSize = val;
  286. this.innerCurrentPage = 1;
  287. this.showGoodsList();
  288. },
  289. // 更改内嵌当前页
  290. innerHandleCurrentChange(val) {
  291. this.innerCurrentPage = val;
  292. this.showGoodsList();
  293. },
  294. // 操作 - 更改状态(type: 禁用0,启用1)
  295. changeStatus(id, type) {
  296. type = !!type
  297. changeBannerStatus({carouselMapId: id, state: type}).then(res => {
  298. this.getList();
  299. this.$successMsg();
  300. })
  301. },
  302. // 操作 - 删除
  303. handleDelete(id) {
  304. deleteBanner({carouselMapId: id}).then(res => {
  305. this.getList();
  306. this.$successMsg();
  307. })
  308. },
  309. // 新增编辑
  310. addOrEdit(type, id) {
  311. this.addFormType = type;
  312. this.addFormVisible = true;
  313. if(type == 'edit') {
  314. this.editId = id;
  315. getBannerDetail({id: id}).then(res => {
  316. this.addForm = {
  317. bannerName: res.data.carouselName,
  318. imgUrl: res.data.imgSrc,
  319. state: res.data.state,
  320. goodsId: res.data.goodsId,
  321. sortNum: res.data.sortNum,
  322. type: res.data.type,
  323. appid: res.data.appId,
  324. link: res.data.linkUrl,
  325. }
  326. if(this.addForm.type === 3) {
  327. this.addForm.goodsId = Number(this.addForm.goodsId);
  328. }
  329. if (this.addForm.goodsId && this.addForm.type === 1) {
  330. let params = {
  331. goodsId: this.addForm.goodsId,
  332. pageNum: 1,
  333. pageSize: 1
  334. };
  335. getGoodsList(params).then(res => {
  336. this.selGoodsName = res.data.records[0].goodsName;
  337. })
  338. }
  339. })
  340. }
  341. },
  342. // 取消 新增编辑
  343. cancelAddForm(){
  344. this.addFormVisible = false;
  345. this.$refs.addForm.resetFields();
  346. this.selGoodsName = ''
  347. },
  348. // 提交 新增编辑
  349. submitAddForm() {
  350. this.$refs.addForm.validate((valid) => {
  351. if (valid) {
  352. let params = {
  353. carouselName: this.addForm.bannerName,
  354. imgSrc: this.addForm.imgUrl,
  355. state: this.addForm.state,
  356. goodsId: this.addForm.goodsId,
  357. sortNum: this.addForm.sortNum,
  358. type: this.addForm.type,
  359. appId: this.addForm.appid,
  360. linkUrl: this.addForm.link,
  361. }
  362. if(this.addFormType == 'edit') {
  363. params.id = this.editId;
  364. editBanner(params).then(res => {
  365. this.cancelAddForm();
  366. this.getList();
  367. this.$successMsg('编辑成功');
  368. })
  369. } else {
  370. params.adminNickName = this.name;
  371. params.adminUserId = this.userid;
  372. addBanner(params).then(res => {
  373. this.cancelAddForm();
  374. this.getList();
  375. this.$successMsg('新增成功');
  376. })
  377. }
  378. }
  379. })
  380. },
  381. uploadSuccess(res, file) {
  382. this.addForm.imgUrl = res.data.url;
  383. },
  384. beforeUpload(file) {
  385. const fileSuffix = file.name.substring(file.name.lastIndexOf(".") + 1);
  386. const whiteList = ['jpg', 'jpeg', 'png'];
  387. if (whiteList.indexOf(fileSuffix) === -1) {
  388. this.$errorMsg('只支持上传jpg/png文件!');
  389. return false;
  390. }
  391. },
  392. batchDelete() {
  393. if(this.$refs.multipleTable.selection && this.$refs.multipleTable.selection.length > 0) {
  394. this.$confirm('此操作将删除选中轮播图, 是否继续?', '提示', {
  395. confirmButtonText: '确定',
  396. cancelButtonText: '取消',
  397. type: 'warning'
  398. }).then(() => {
  399. let ids = []
  400. this.$refs.multipleTable.selection.forEach(value => {
  401. ids.push(value.id)
  402. })
  403. batchDeleteBanner(ids).then(() => {
  404. this.$refs.multipleTable.clearSelection()
  405. this.getList()
  406. this.$successMsg('删除成功');
  407. })
  408. }).catch(() => {});
  409. } else {
  410. this.$errorMsg('请选择要删除的轮播图')
  411. }
  412. },
  413. showGoods() {
  414. this.search = '';
  415. this.innerVisible = true
  416. this.showGoodsList()
  417. },
  418. clearGoodsId() {
  419. this.addForm.goodsId = ''
  420. this.selGoodsName = ''
  421. },
  422. showGoodsList() {
  423. let params = {
  424. goodsName: this.search,
  425. pageNum: this.innerCurrentPage,
  426. pageSize: this.innerPageSize
  427. };
  428. getGoodsList(params).then(res => {
  429. this.goodsList = res.data.records;
  430. this.innerListTotal = res.data.total;
  431. })
  432. },
  433. searchGoods() {
  434. this.innerCurrentPage = 1;
  435. this.showGoodsList()
  436. },
  437. selGoods(row) {
  438. this.innerVisible = false
  439. this.search = ''
  440. this.addForm.goodsId = row.goodsId
  441. this.selGoodsName = row.goodsName
  442. }
  443. }
  444. }
  445. </script>
  446. <style scoped lang="scss">
  447. .tips {
  448. margin-top: 10px;
  449. span {
  450. display: inline-block;
  451. width: 300px;
  452. text-align: center;
  453. line-height: 32px;
  454. background: #ffefef;
  455. font-size: 14px;
  456. color: #f66460;
  457. }
  458. }
  459. </style>
  460. <style>
  461. .demo-table-expand {
  462. font-size: 0;
  463. }
  464. .demo-table-expand label {
  465. width: 80px;
  466. color: #99a9bf;
  467. }
  468. .demo-table-expand .el-form-item {
  469. margin-right: 0;
  470. margin-bottom: 0;
  471. width: 100%;
  472. }
  473. </style>