Browse Source

页面内容管理

Xiao_123 5 months ago
parent
commit
9ad625e6ae

+ 50 - 0
src/api/menduner/system/web/index.ts

@@ -0,0 +1,50 @@
+import request from '@/config/axios'
+
+// 页面内容 VO
+export interface WebContentVO {
+  id: number // id
+  pcTop: string // pc顶部
+  pcLeft: string // pc左侧
+  pcRight: string // pc右侧
+  pcAdvertisement: string // pc广告
+  pcHomeCarousel: string // pc首页轮播图
+  pcLoginCarousel: string // pc登录轮播图
+  pcLoginBackground: string // pc登录背景
+  pcBackendAdvertisement: string // pc企业端广告
+  appHomeCarousel: string // 手机端首页轮播图
+  appAdvertisement: string // 手机端广告
+  status: string // 状态(0开启 1关闭)
+}
+
+// 页面内容 API
+export const WebContentApi = {
+  // 查询页面内容分页
+  getWebContentPage: async (params: any) => {
+    return await request.get({ url: `/menduner/system/web-content/page`, params })
+  },
+
+  // 查询页面内容详情
+  getWebContent: async (id: number) => {
+    return await request.get({ url: `/menduner/system/web-content/get?id=` + id })
+  },
+
+  // 新增页面内容
+  createWebContent: async (data: WebContentVO) => {
+    return await request.post({ url: `/menduner/system/web-content/create`, data })
+  },
+
+  // 修改页面内容
+  updateWebContent: async (data: any) => {
+    return await request.put({ url: `/menduner/system/web-content/update`, data })
+  },
+
+  // 删除页面内容
+  deleteWebContent: async (id: number) => {
+    return await request.delete({ url: `/menduner/system/web-content/delete?id=` + id })
+  },
+
+  // 导出页面内容 Excel
+  exportWebContent: async (params) => {
+    return await request.download({ url: `/menduner/system/web-content/export-excel`, params })
+  }
+}

+ 161 - 0
src/views/menduner/system/web/WebContentForm.vue

@@ -0,0 +1,161 @@
+<template>
+  <Dialog :title="dialogTitle" v-model="dialogVisible">
+    <el-form
+      ref="formRef"
+      :model="formData"
+      :rules="formRules"
+      label-width="140px"
+      v-loading="formLoading"
+    >
+      <el-form-item label="上传图片尺寸" prop="imgSize" required>
+        <el-input v-model="formData.imgSize" disabled />
+      </el-form-item>
+      <el-form-item label="图片" prop="url" required>
+        <UploadImg v-model="formData.url" height="150px" width="300px" />
+      </el-form-item>
+      <el-form-item label="点击图片跳转链接" prop="link">
+        <el-input v-model="formData.link" />
+      </el-form-item>
+      <el-form-item label="标题" prop="title">
+        <el-input v-model="formData.title" placeholder="请填写" />
+      </el-form-item>
+      <!-- <el-form-item label="排序" prop="sort">
+        <el-input v-model="formData.sort" />
+      </el-form-item> -->
+    </el-form>
+    <template #footer>
+      <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
+      <el-button @click="dialogVisible = false">取 消</el-button>
+    </template>
+  </Dialog>
+</template>
+
+<script setup lang="ts">
+import { WebContentApi } from '@/api/menduner/system/web'
+
+/** 页面内容 表单 */
+defineOptions({ name: 'WebContentForm' })
+
+const { t } = useI18n() // 国际化
+const message = useMessage() // 消息弹窗
+
+const formData = ref({
+  imgSize: '',
+  link: '',
+  title: '',
+  // sort: 0,
+  url: ''
+})
+const imgSizeList = {
+  'pcLeft': '宽528px*高919px',
+  'pcAdvertisement': '宽900px*高530px',
+  'pcHomeCarousel': '宽792px*高392px',
+  'pcLoginCarousel': '宽792px*高392px',
+  'appHomeCarousel': '宽750px*高350px',
+  'appAdvertisement': '宽331px*高442px'
+}
+const editId = ref('')
+const formType = ref('')
+const currentKey = ref('')
+const dialogVisible = ref(false) // 弹窗的是否展示
+const dialogTitle = ref('') // 弹窗的标题
+const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
+const query = ref({
+  id: undefined,
+  pcTop: undefined,
+  pcLeft: undefined,
+  pcRight: undefined,
+  pcAdvertisement: undefined,
+  pcHomeCarousel: undefined,
+  pcLoginCarousel: undefined,
+  pcLoginBackground: undefined,
+  pcBackendAdvertisement: undefined,
+  appHomeCarousel: undefined,
+  appAdvertisement: undefined,
+  status: undefined
+})
+
+const formRules = reactive({
+  url: [{ required: true, message: '图片不能为空', trigger: 'blur' }]
+})
+const formRef = ref() // 表单 Ref
+
+/** 打开弹窗 */
+const open = async (type: string, key: string, title: string, mark?: string) => {
+  formType.value = type
+  resetForm()
+  currentKey.value = key
+  dialogVisible.value = true
+  dialogTitle.value = title + (type === 'add' ? '新增' : '编辑')
+  formLoading.value = true
+  try {
+    query.value = await WebContentApi.getWebContent(1)
+    // 编辑
+    if (mark) {
+      editId.value = mark
+      const { img: url, link, title } = query.value[key].find(e => e.mark === mark)
+      formData.value = { url, link, title }
+    }
+  } finally {
+    formLoading.value = false
+  }
+  formData.value.imgSize = imgSizeList[key]
+}
+defineExpose({ open }) // 提供 open 方法,用于打开弹窗
+
+/** 提交表单 */
+const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
+const submitForm = async () => {
+  // 校验表单
+  await formRef.value.validate()
+  
+  const mark = new Date().getTime().toString()
+  const obj = { img: formData.value.url, link: formData.value.link, mark, title: formData.value.title }
+  if (formType.value === 'add') {
+    query.value[currentKey.value] = query.value[currentKey.value] ? [...query.value[currentKey.value], obj] : [obj]
+  } else {
+    const index = query.value[currentKey.value].findIndex(e => e.mark === editId.value)
+    if (index === -1) return
+    query.value[currentKey.value][index] = obj
+  }
+
+  // 提交请求
+  formLoading.value = true
+  try {
+    await WebContentApi.updateWebContent(query.value)
+    message.success(t('common.updateSuccess'))
+    dialogVisible.value = false
+    // 发送操作成功的事件
+    emit('success')
+  } finally {
+    formLoading.value = false
+  }
+}
+
+/** 重置表单 */
+const resetForm = () => {
+  editId.value = ''
+  query.value = {
+    id: undefined,
+    pcTop: undefined,
+    pcLeft: undefined,
+    pcRight: undefined,
+    pcAdvertisement: undefined,
+    pcHomeCarousel: undefined,
+    pcLoginCarousel: undefined,
+    pcLoginBackground: undefined,
+    pcBackendAdvertisement: undefined,
+    appHomeCarousel: undefined,
+    appAdvertisement: undefined,
+    status: undefined
+  }
+  formData.value = {
+    imgSize: '',
+    link: '',
+    title: '',
+    url: '',
+    // sort: 0
+  }
+  formRef.value?.resetFields()
+}
+</script>

+ 104 - 0
src/views/menduner/system/web/index.vue

@@ -0,0 +1,104 @@
+<template>
+  <ContentWrap>
+    <el-tabs v-model="tab" @tab-click="tabClick">
+      <el-tab-pane v-for="(k, i) in tabList" :key="i" :label="k.label" :name="k.value"/>
+    </el-tabs>
+    <div style="text-align: end;">
+      <el-button @click="getList"><Icon icon="ep:refresh" class="mr-5px" /> 刷 新</el-button>
+      <el-button type="primary" @click="handleAdd"><Icon icon="ep:plus" class="mr-5px" />新 增</el-button>
+    </div>
+    <el-table v-loading="loading" :data="info[tabList[tab].key]" :stripe="true">
+      <!-- <el-table-column label="排序" align="center" prop="sort" /> -->
+      <el-table-column label="标题" align="center" prop="title" />
+      <el-table-column label="图片" align="center" prop="img">
+        <template #default="scope">
+          <el-image v-if="scope.row.img" class="h-150px w-200px" :src="scope.row.img" lazy preview-teleported :preview-src-list="info[tabList[tab].key].map(e => e.img)" fit="scale-down" />
+        </template>
+      </el-table-column>
+      <el-table-column label="点击跳转链接" align="center" prop="link">
+        <template #default="scope">
+          <el-link v-if="scope.row.link" :href="scope.row.link" type="primary" target="_blank">点击查看</el-link>
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" align="center" fixed="right" min-width="220">
+        <template #default="scope">
+          <el-button link type="primary" @click="handleEdit(scope.row.mark)">编辑</el-button>
+          <el-button link type="danger" @click="handleDelete(scope.row.mark)">删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+  </ContentWrap>
+
+  <!-- 表单弹窗:添加/修改 -->
+  <WebContentForm ref="formRef" @success="getList" />
+
+</template>
+
+<script setup lang="ts">
+import { WebContentApi } from '@/api/menduner/system/web'
+import WebContentForm from './WebContentForm.vue'
+
+/** 页面内容 列表 */
+defineOptions({ name: 'WebContent' })
+
+const message = useMessage() // 消息弹窗
+const { t } = useI18n() // 国际化
+const loading = ref(false)
+const tab = ref(2)
+let info = reactive({})
+const tabList = [
+  { label: 'PC首页左侧广告图', value: 0, key: 'pcLeft' },
+  { label: 'PC首页弹窗广告图', value: 1, key: 'pcAdvertisement' },
+  { label: 'PC首页轮播图', value: 2, key: 'pcHomeCarousel' },
+  { label: 'PC登录页轮播图', value: 3, key: 'pcLoginCarousel' },
+  { label: '小程序首页轮播图', value: 4, key: 'appHomeCarousel' },
+  { label: '小程序首页弹窗广告图', value: 5, key: 'appAdvertisement' },
+]
+
+/** 查询列表 */
+const getList = async () => {
+  loading.value = true
+  try {
+    const data = await WebContentApi.getWebContent(1)
+    info = data
+  } finally {
+    loading.value = false
+  }
+}
+
+const tabClick = (val) => {
+  tab.value = val.paneName
+  getList()
+}
+
+const handleAdd = () => {
+  formRef.value.open('add', tabList[tab.value].key, tabList[tab.value].label)
+}
+
+const formRef = ref()
+const handleEdit = (mark: string) => {
+  formRef.value.open('edit', tabList[tab.value].key, tabList[tab.value].label, mark)
+}
+
+/** 删除按钮操作 */
+const handleDelete = async (mark: string) => {
+  const index = info[tabList[tab.value].key].findIndex((item) => item.mark === mark)
+  if (index === -1) return message.warning('图片不存在')
+  try {
+    // 删除的二次确认
+    await message.delConfirm()
+    // 发起删除
+    info[tabList[tab.value].key].splice(index, 1)
+    await WebContentApi.updateWebContent(info)
+
+    message.success(t('common.delSuccess'))
+    // 刷新列表
+    await getList()
+  } catch {}
+}
+
+/** 初始化 **/
+onMounted(() => {
+  getList()
+})
+</script>

+ 188 - 0
src/views/menduner/system/web/indexData.vue

@@ -0,0 +1,188 @@
+<template>
+  <ContentWrap>
+    <!-- 搜索工作栏 -->
+    <el-form
+      class="-mb-15px"
+      :model="queryParams"
+      ref="queryFormRef"
+      :inline="true"
+      label-width="68px"
+    >
+      <el-form-item label="创建时间" prop="createTime">
+        <el-date-picker
+          v-model="queryParams.createTime"
+          value-format="YYYY-MM-DD HH:mm:ss"
+          type="daterange"
+          start-placeholder="开始日期"
+          end-placeholder="结束日期"
+          :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
+          class="!w-240px"
+        />
+      </el-form-item>
+      <el-form-item>
+        <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
+        <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
+        <el-button
+          type="primary"
+          plain
+          @click="openForm('create')"
+          v-hasPermi="['menduner:system:web-content:create']"
+        >
+          <Icon icon="ep:plus" class="mr-5px" /> 新增
+        </el-button>
+        <el-button
+          type="success"
+          plain
+          @click="handleExport"
+          :loading="exportLoading"
+          v-hasPermi="['menduner:system:web-content:export']"
+        >
+          <Icon icon="ep:download" class="mr-5px" /> 导出
+        </el-button>
+      </el-form-item>
+    </el-form>
+  </ContentWrap>
+
+  <!-- 列表 -->
+  <ContentWrap>
+    <el-table v-loading="loading" :data="list" :stripe="true">
+      <el-table-column label="pc顶部" align="center" prop="pcTop" />
+      <el-table-column label="pc左侧" align="center" prop="pcLeft" />
+      <el-table-column label="pc右侧" align="center" prop="pcRight" />
+      <el-table-column label="pc广告" align="center" prop="pcAdvertisement" />
+      <el-table-column label="pc首页轮播图" align="center" prop="pcHomeCarousel" />
+      <el-table-column label="pc登录轮播图" align="center" prop="pcLoginCarousel" />
+      <el-table-column label="pc登录背景" align="center" prop="pcLoginBackground" />
+      <el-table-column label="pc企业端广告" align="center" prop="pcBackendAdvertisement" />
+      <el-table-column label="手机端首页轮播图" align="center" prop="appHomeCarousel" />
+      <el-table-column label="手机端广告" align="center" prop="appAdvertisement" />
+      <el-table-column label="状态(0开启 1关闭)" align="center" prop="status" />
+      <el-table-column
+        label="创建时间"
+        align="center"
+        prop="createTime"
+        :formatter="dateFormatter"
+        width="180px"
+      />
+      <el-table-column label="操作" align="center">
+        <template #default="scope">
+          <el-button
+            link
+            type="primary"
+            @click="openForm('update', scope.row.id)"
+            v-hasPermi="['menduner:system:web-content:update']"
+          >
+            编辑
+          </el-button>
+          <el-button
+            link
+            type="danger"
+            @click="handleDelete(scope.row.id)"
+            v-hasPermi="['menduner:system:web-content:delete']"
+          >
+            删除
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    <!-- 分页 -->
+    <Pagination
+      :total="total"
+      v-model:page="queryParams.pageNo"
+      v-model:limit="queryParams.pageSize"
+      @pagination="getList"
+    />
+  </ContentWrap>
+
+  <!-- 表单弹窗:添加/修改 -->
+  <WebContentForm ref="formRef" @success="getList" />
+</template>
+
+<script setup lang="ts">
+import { dateFormatter } from '@/utils/formatTime'
+import download from '@/utils/download'
+import { WebContentApi, WebContentVO } from '@/api/menduner/system/web'
+import WebContentForm from './WebContentForm.vue'
+
+/** 页面内容 列表 */
+defineOptions({ name: 'WebContent' })
+
+const message = useMessage() // 消息弹窗
+const { t } = useI18n() // 国际化
+
+const loading = ref(true) // 列表的加载中
+const list = ref<WebContentVO[]>([]) // 列表的数据
+const total = ref(0) // 列表的总页数
+const queryParams = reactive({
+  pageNo: 1,
+  pageSize: 10,
+  createTime: []
+})
+const queryFormRef = ref() // 搜索的表单
+const exportLoading = ref(false) // 导出的加载中
+
+/** 查询列表 */
+const getList = async () => {
+  loading.value = true
+  try {
+    const data = await WebContentApi.getWebContentPage(queryParams)
+    console.log(data.list, 'list');
+    
+    list.value = data.list
+    total.value = data.total
+  } finally {
+    loading.value = false
+  }
+}
+
+/** 搜索按钮操作 */
+const handleQuery = () => {
+  queryParams.pageNo = 1
+  getList()
+}
+
+/** 重置按钮操作 */
+const resetQuery = () => {
+  queryFormRef.value.resetFields()
+  handleQuery()
+}
+
+/** 添加/修改操作 */
+const formRef = ref()
+const openForm = (type: string, id?: number) => {
+  formRef.value.open(type, id)
+}
+
+/** 删除按钮操作 */
+const handleDelete = async (id: number) => {
+  try {
+    // 删除的二次确认
+    await message.delConfirm()
+    // 发起删除
+    await WebContentApi.deleteWebContent(id)
+    message.success(t('common.delSuccess'))
+    // 刷新列表
+    await getList()
+  } catch {}
+}
+
+/** 导出按钮操作 */
+const handleExport = async () => {
+  try {
+    // 导出的二次确认
+    await message.exportConfirm()
+    // 发起导出
+    exportLoading.value = true
+    const data = await WebContentApi.exportWebContent(queryParams)
+    download.excel(data, '页面内容.xls')
+  } catch {
+  } finally {
+    exportLoading.value = false
+  }
+}
+
+/** 初始化 **/
+onMounted(() => {
+  getList()
+})
+</script>