index.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425
  1. <template>
  2. <div class="el-container-md">
  3. <el-form :model="queryParams" class="live-goods-css" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
  4. <el-form-item label="商品名称" prop="keywords" >
  5. <el-input
  6. v-model="queryParams.keywords"
  7. placeholder="请输入商品名称"
  8. clearable
  9. size="small"
  10. @keyup.enter.native="handleQuery"
  11. />
  12. </el-form-item>
  13. <el-form-item label="上下架" prop="status" >
  14. <el-input
  15. v-model="queryParams.status"
  16. placeholder="请输入直播间状态"
  17. clearable
  18. size="small"
  19. @keyup.enter.native="handleQuery"
  20. />
  21. </el-form-item>
  22. <el-form-item>
  23. <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
  24. <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
  25. </el-form-item>
  26. </el-form>
  27. <div class="selection-toolbar">
  28. <el-checkbox :indeterminate="isIndeterminate" v-model="allChecked" @change="toggleSelectAll">
  29. {{ multipleSelection.length > 0 ? `已选 ${multipleSelection.length} 条` : '选中本页' }}
  30. </el-checkbox>
  31. <el-button plain size="mini" @click="handleShelf">上架</el-button>
  32. <el-button plain size="mini" @click="handleUnshelf">下架</el-button>
  33. <el-button plain size="mini" @click="handleDeleteSelected">删除</el-button>
  34. <el-button plain type="mini" icon="el-icon-plus" @click="handleAddLiveGoods">添加商品</el-button>
  35. </div>
  36. <el-table
  37. ref="goodTable"
  38. :data="goodsLiveList"
  39. style="width: 100%"
  40. v-loading="loading"
  41. @selection-change="handleSelectionChange"
  42. >
  43. <el-table-column type="selection" width="55"></el-table-column>
  44. <!-- 题干列:显示试题的主要内容 -->
  45. <el-table-column
  46. prop="goodsId"
  47. label="商品id"
  48. show-overflow-tooltip
  49. ></el-table-column>
  50. <el-table-column
  51. label="商品图片"
  52. >
  53. <template slot-scope="scope">
  54. <img
  55. :src="scope.row.imgUrl"
  56. style="display: block; max-width: 100%; width: 100px; height: 100px"
  57. />
  58. </template>
  59. </el-table-column>
  60. <el-table-column
  61. prop="productName"
  62. label="商品名称"
  63. ></el-table-column>
  64. <el-table-column
  65. prop="price"
  66. label="价格"
  67. ></el-table-column>
  68. <el-table-column
  69. prop="stock"
  70. label="库存"
  71. ></el-table-column>
  72. <el-table-column
  73. prop="sales"
  74. label="销量"
  75. ></el-table-column>
  76. <el-table-column
  77. prop="status"
  78. label="上下架"
  79. >
  80. <template slot-scope="scope">
  81. <el-tag v-if="scope.row.status == 1">上架</el-tag>
  82. <el-tag v-if="scope.row.status == 0">下架</el-tag>
  83. </template>
  84. </el-table-column>
  85. <!-- 操作列:包含编辑和删除按钮 -->
  86. <el-table-column
  87. label="操作"
  88. width="180"
  89. fixed="right"
  90. >
  91. <template slot-scope="scope">
  92. <el-button
  93. type="text"
  94. size="small"
  95. style="color: #F56C6C;"
  96. @click="handleGoodDelete(scope.row)"
  97. >删除</el-button>
  98. </template>
  99. </el-table-column>
  100. </el-table>
  101. <!-- 分页组件:用于分页展示试题列表 -->
  102. <pagination
  103. v-show="goodsLiveTotal > 0"
  104. :total="goodsLiveTotal"
  105. :page.sync="goodsParams.pageNum"
  106. :limit.sync="goodsParams.pageSize"
  107. @pagination="getLiveGoodsList"
  108. style="margin-top: 20px;"
  109. />
  110. <!-- 添加商品弹窗 -->
  111. <el-dialog
  112. title="添加商品"
  113. :visible.sync="goodsDialogVisible"
  114. width="800px"
  115. :close-on-click-modal="false"
  116. :close-on-press-escape="false"
  117. >
  118. <div class="dialog-content">
  119. <div style="text-align: right; margin-bottom: 20px;">
  120. <el-input
  121. v-model="searchTitle"
  122. placeholder="请输入产品名称"
  123. style="width: 300px;"
  124. @input="handleGoodsSearch"
  125. ></el-input>
  126. </div>
  127. <el-table
  128. :data="goodsList"
  129. style="width: 100%"
  130. v-loading="goodsLoading"
  131. @selection-change="handleGoodsChange"
  132. @row-click="handleGoodsRowClick"
  133. row-key="id"
  134. >
  135. <el-table-column
  136. type="selection"
  137. width="55"
  138. >
  139. </el-table-column>
  140. <el-table-column
  141. prop="storeName"
  142. label="商铺名称"
  143. class-name="clickable-column"
  144. ></el-table-column>
  145. <el-table-column
  146. prop="productName"
  147. label="产品"
  148. class-name="clickable-column"
  149. ></el-table-column>
  150. <el-table-column
  151. prop="price"
  152. label="价格"
  153. class-name="clickable-column"
  154. ></el-table-column>
  155. <el-table-column
  156. prop="stock"
  157. label="库存"
  158. class-name="clickable-column"
  159. ></el-table-column>
  160. </el-table>
  161. <pagination
  162. v-show="goodsTotal > 0"
  163. :total="goodsTotal"
  164. :page.sync="queryGoodParams.pageNum"
  165. :limit.sync="queryGoodParams.pageSize"
  166. @pagination="getStoreProductLists"
  167. style="margin-top: 20px;"
  168. />
  169. </div>
  170. <div slot="footer" class="dialog-footer">
  171. <div style="display: flex; justify-content: space-between; align-items: center;">
  172. <span class="selected-count">当前已选择 <span style="color: #00BFFF; font-style: italic;">{{ selectedGoods.length }}</span> 商品</span>
  173. <div>
  174. <el-button @click="goodsDialogVisible = false">取 消</el-button>
  175. <el-button type="primary" @click="confirmAddGoods">确 定</el-button>
  176. </div>
  177. </div>
  178. </div>
  179. </el-dialog>
  180. </div>
  181. </template>
  182. <script>
  183. import {addLiveGoods, delLiveGoods, listLiveGoods, listStoreProduct, handleShelfOrUn, handleDeleteSelected} from "@/api/live/liveGoods";
  184. export default {
  185. data() {
  186. return {
  187. liveId: '',
  188. loading: true,
  189. searchTitle: '',
  190. queryGoodParams: {
  191. pageNum: 1,
  192. pageSize: 10,
  193. productName: null,
  194. liveId: null
  195. },
  196. // 显示搜索条件
  197. showSearch: true,
  198. goodsLiveList: [],
  199. goodsLiveTotal: 0,
  200. goodsParams: {
  201. pageNum: 1,
  202. pageSize: 10,
  203. liveId: null
  204. },
  205. goodsList: [],
  206. goodsTotal: 0,
  207. selectedGoods: [],
  208. goodsLoading: false,
  209. goodsDialogVisible: false,
  210. multipleSelection: [],
  211. allChecked: false,
  212. isIndeterminate: false,
  213. queryParams: {
  214. pageNum: 1,
  215. pageSize: 10,
  216. keywords: null,
  217. status: null,
  218. liveId: null,
  219. desc: null,
  220. createTime: null,
  221. updateTime: null,
  222. },
  223. };
  224. },
  225. created() {
  226. this.liveId = this.$route.query.liveId
  227. this.goodsParams.liveId = this.liveId
  228. this.queryParams.liveId = this.liveId
  229. this.getLiveGoodsList();
  230. },
  231. methods: {
  232. /** 搜索按钮操作 */
  233. handleQuery() {
  234. this.queryParams.pageNum = 1;
  235. this.loading = true
  236. listLiveGoods(this.queryParams).then(response => {
  237. this.goodsLiveList = response.rows
  238. this.goodsLiveTotal = response.total
  239. this.loading = false
  240. })
  241. },
  242. /** 重置按钮操作 */
  243. resetQuery() {
  244. this.$refs.queryForm.resetFields();
  245. },
  246. handleShelf(){
  247. this.handleShelfOrUn(1)
  248. },
  249. handleUnshelf(){
  250. this.handleShelfOrUn(0)
  251. },
  252. handleShelfOrUn(type){
  253. if (this.multipleSelection.length > 0) {
  254. const goodsList = this.getSelectedList();
  255. handleShelfOrUn({"goodsIds":goodsList,"status":type}).then(res=>{
  256. this.dealResult(res)
  257. })
  258. } else {
  259. this.$message.info("请选择下架商品!")
  260. }
  261. },
  262. handleDeleteSelected(){
  263. if (this.multipleSelection.length > 0) {
  264. const goodsList = this.getSelectedList();
  265. handleDeleteSelected({"goodsIds":goodsList}).then(res=>{
  266. this.dealResult(res)
  267. })
  268. } else {
  269. this.$message.info("请选择被删除的商品!")
  270. }
  271. },
  272. dealResult(res){
  273. if (res.code == 200) {
  274. this.getLiveGoodsList();
  275. this.$refs.goodTable.clearSelection();
  276. } else {
  277. this.$message.error(res.msg);
  278. }
  279. },
  280. getSelectedList(){
  281. var goodsList = []
  282. this.multipleSelection.forEach(item => {
  283. goodsList.push(item.goodsId);
  284. })
  285. return goodsList;
  286. },
  287. // 全选或取消全选
  288. toggleSelectAll(val) {
  289. this.checked = val; // 更新 checkbox 的状态
  290. if (val) {
  291. // 如果 checkbox 被选中,则全选
  292. this.toggleSelection(this.goodsLiveList);
  293. } else {
  294. // 如果 checkbox 被取消选中,则取消全选
  295. this.toggleSelection();
  296. }
  297. },
  298. toggleSelection(rows) {
  299. if (rows && !this.isIndeterminate) {
  300. rows.forEach(row => {
  301. this.$refs.goodTable.toggleRowSelection(row);
  302. });
  303. } else {
  304. this.$refs.goodTable.clearSelection();
  305. }
  306. },
  307. // 多选框选中数据
  308. handleSelectionChange(val) {
  309. this.multipleSelection = val;
  310. // 根据选择项的数量更新 checkbox 的状态
  311. this.allChecked = val.length === this.goodsLiveList.length;
  312. this.isIndeterminate = val.length > 0 && val.length < this.goodsLiveList.length;
  313. },
  314. getLiveGoodsList() {
  315. this.loading = true
  316. listLiveGoods(this.goodsParams).then(response => {
  317. this.goodsLiveList = response.rows
  318. this.goodsLiveTotal = response.total
  319. this.loading = false
  320. })
  321. },
  322. handleAddLiveGoods(){
  323. this.goodsDialogVisible = true;
  324. this.getStoreProductLists()
  325. },
  326. handleGoodsSearch(){
  327. this.queryGoodParams.pageNum = 1
  328. this.queryGoodParams.productName = this.searchTitle
  329. this.getStoreProductLists()
  330. },
  331. handleGoodsChange(goods) {
  332. this.selectedGoods = goods
  333. },
  334. confirmAddGoods(){
  335. if (this.selectedGoods.length === 0) {
  336. this.$message({
  337. message: '请选择要添加的商品',
  338. type: 'warning'
  339. })
  340. return
  341. }
  342. addLiveGoods({
  343. liveId: this.liveId,
  344. productsId: this.selectedGoods.map(item => item.productId).join(',')
  345. }).then(response => {
  346. this.goodsDialogVisible = false
  347. this.getLiveGoodsList()
  348. })
  349. },
  350. handleGoodDelete(row){
  351. delLiveGoods(row.goodsId).then(response => {
  352. this.getLiveGoodsList()
  353. })
  354. },
  355. /** 处理行点击事件 */
  356. handleGoodsRowClick(row, column) {
  357. // 如果点击的是复选框列,不进行处理
  358. if (column.type === 'selection') {
  359. return
  360. }
  361. // 获取表格实例
  362. const table = this.$refs.goodsTable[0]
  363. if (!table) {
  364. return
  365. }
  366. // 判断当前行是否已经被选中
  367. const isSelected = this.selectedGoods.some(item => item.id === row.id)
  368. // 切换选中状态
  369. table.toggleRowSelection(row, !isSelected)
  370. },
  371. getStoreProductLists() {
  372. this.queryGoodParams.liveId = this.liveId
  373. listStoreProduct(this.queryGoodParams).then(response => {
  374. this.goodsList = response.rows
  375. this.goodsTotal = response.total
  376. this.loading = false
  377. })
  378. }
  379. }
  380. };
  381. </script>
  382. <style scoped>
  383. .selection-toolbar {
  384. display: flex;
  385. align-items: center;
  386. margin-bottom: 10px;
  387. padding-left: 10px;
  388. }
  389. .selection-toolbar .el-checkbox {
  390. margin-right: 10px;
  391. }
  392. /* 调整 checkbox 内部输入框的对齐 */
  393. .selection-toolbar .el-checkbox .el-checkbox__inner {
  394. top: 8px; /* 根据实际需求调整 */
  395. }
  396. .live-goods-css {
  397. padding-left: 10px;
  398. padding-top: 30px;
  399. }
  400. </style>