partner-poster.vue 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. <!-- 合伙人推广海报 -->
  2. <template>
  3. <div class="partner-poster">
  4. <div class="search-bar" style="margin-bottom: 12px">
  5. <el-input
  6. v-model="searchKeyword"
  7. placeholder="请输入模板名称"
  8. style="width: 300px"
  9. />
  10. <el-button
  11. style="width: 90px; margin-left: 14px"
  12. type="primary"
  13. @click="handleSearch"
  14. >查询</el-button
  15. >
  16. <el-button style="width: 90px" type="info" @click="reset"
  17. >重置</el-button
  18. >
  19. </div>
  20. <!-- 表格 -->
  21. <common-table
  22. ref="tableRef"
  23. :page-config="{
  24. cacheKey: 'partnerPosterTable',
  25. fileName: '合伙人推广海报',
  26. pageUrl: '/user/userPartnerPosterTemplate/pagelist'
  27. }"
  28. :flex-table="true"
  29. :body-style="{ padding: '0px' }"
  30. :columns="columns"
  31. @selection-change="handleSelectionChange"
  32. >
  33. <template #toolbar="{ row }">
  34. <el-button type="primary" @click="openEdit()">
  35. <el-icon><Plus /></el-icon>添加模板
  36. </el-button>
  37. <el-button type="danger" @click="handleDelete()"
  38. >删除</el-button
  39. >
  40. </template>
  41. <!-- 图片列 -->
  42. <template #image="{ row }">
  43. <el-image
  44. :src="row.background"
  45. fit="contain"
  46. style="width: 80px; height: 80px"
  47. :preview-src-list="[row.background]"
  48. :initial-index="0"
  49. preview-teleported
  50. />
  51. </template>
  52. <!-- 状态列 -->
  53. <template #status="{ row }">
  54. <el-switch
  55. v-model="row.status"
  56. style="--el-switch-on-color: #13ce66"
  57. active-value="1"
  58. inactive-value="2"
  59. @change="statusSwitchChange($event, row)"
  60. />
  61. <el-text style="margin-left: 5px">{{
  62. row.status == 2 ? '已停用' : '已开启'
  63. }}</el-text>
  64. </template>
  65. <!-- 操作列 -->
  66. <template #operation="{ row }">
  67. <el-button type="primary" link @click="openEdit(row)"
  68. >编辑</el-button
  69. >
  70. <el-button type="danger" link @click="handleDelete(row)"
  71. >删除</el-button
  72. >
  73. </template>
  74. </common-table>
  75. <!-- 编辑弹窗 -->
  76. <poster-edit ref="posterEditRef" @success="handleEditSuccess" />
  77. </div>
  78. </template>
  79. <script setup>
  80. import { ref } from 'vue';
  81. import { Plus } from '@element-plus/icons-vue';
  82. import { ElMessage, ElMessageBox } from 'element-plus';
  83. import CommonTable from '@/components/CommonPage/CommonTable.vue';
  84. import PosterEdit from './poster-edit.vue';
  85. import {
  86. deletePosterTemplate,
  87. updatePosterTemplateStatus
  88. } from '@/api/marketing/partner';
  89. // 搜索关键词
  90. const searchKeyword = ref('');
  91. // 表格实例
  92. const tableRef = ref();
  93. // 选中的行数据
  94. const selectedRows = ref([]);
  95. // 编辑弹窗实例
  96. const posterEditRef = ref();
  97. // 表格列配置
  98. const columns = [
  99. { type: 'selection', width: 70, align: 'center' },
  100. { prop: 'name', label: '模板名称' },
  101. { prop: 'background', label: '图片', slot: 'image', align: 'center' },
  102. { prop: 'createTime', label: '添加时间', align: 'center' },
  103. { prop: 'status', label: '状态', slot: 'status', align: 'center' },
  104. { label: '操作', slot: 'operation', width: 150, align: 'center' }
  105. ];
  106. // 打开编辑弹窗
  107. const openEdit = (row) => {
  108. posterEditRef.value?.open(row);
  109. };
  110. // 处理表格选择变化
  111. const handleSelectionChange = (selection) => {
  112. selectedRows.value = selection;
  113. };
  114. // 处理搜索
  115. const handleSearch = () => {
  116. tableRef.value?.reload({ name: searchKeyword.value });
  117. };
  118. // 重置
  119. const reset = () => {
  120. searchKeyword.value = '';
  121. handleSearch();
  122. };
  123. // 删除海报
  124. const handleDelete = (row) => {
  125. const rows = row ? [row] : selectedRows.value;
  126. if (!rows.length) {
  127. ElMessage.warning('请选择要删除的数据');
  128. return;
  129. }
  130. ElMessageBox.confirm(
  131. `确认删除选中的 ${rows.length} 条数据吗?`,
  132. '提示',
  133. {
  134. type: 'warning'
  135. }
  136. ).then(async () => {
  137. try {
  138. const ids = rows.map((item) => item.id);
  139. await deletePosterTemplate({ ids });
  140. ElMessage.success('删除成功');
  141. handleSearch();
  142. } catch (error) {
  143. ElMessage.error(error.message);
  144. }
  145. });
  146. };
  147. // 修改状态
  148. const statusSwitchChange = (value, row) => {
  149. // 保存原始状态值,用于取消时恢复
  150. const originalStatus = value === '1' ? '2' : '1';
  151. let message = value == '2' ? '确认停用?' : '确认开启?';
  152. ElMessageBox.confirm(message, '提示', {
  153. confirmButtonText: '确定',
  154. cancelButtonText: '关闭',
  155. type: 'warning'
  156. })
  157. .then(() => {
  158. updatePosterTemplateStatus({
  159. id: row.id,
  160. status: value
  161. })
  162. .then((res) => {
  163. if (res.data.code === 200) {
  164. ElMessage.success('操作成功');
  165. handleSearch();
  166. } else {
  167. ElMessage.error(res.data.msg);
  168. // 如果API调用失败,恢复原始状态
  169. row.status = originalStatus;
  170. }
  171. })
  172. .catch(() => {
  173. // API调用异常时,恢复原始状态
  174. row.status = originalStatus;
  175. ElMessage.error('操作失败');
  176. });
  177. })
  178. .catch(() => {
  179. // 用户点击"关闭"按钮,恢复原始状态
  180. row.status = originalStatus;
  181. });
  182. };
  183. // 编辑成功回调
  184. const handleEditSuccess = () => {
  185. handleSearch();
  186. };
  187. </script>
  188. <style lang="scss" scoped>
  189. .partner-poster {
  190. padding: 16px;
  191. background-color: #fff;
  192. .toolbar {
  193. margin-bottom: 16px;
  194. display: flex;
  195. align-items: center;
  196. }
  197. :deep(.el-switch__label) {
  198. font-size: 12px;
  199. &.is-active {
  200. color: var(--el-color-primary);
  201. }
  202. }
  203. }
  204. </style>