Browse Source

公告页面开发

zmq 1 year ago
parent
commit
8df01b1c9a

+ 1 - 1
.env.development

@@ -2,4 +2,4 @@
 ENV = 'development'
 
 # 本地环境接口地址
-VITE_API_URL = 'http://localhost:8000'
+VITE_API_URL = 'http://192.144.191.50:8000'

+ 2 - 1
.env.production

@@ -8,4 +8,5 @@ VITE_COMPRESSION = true
 VITE_PUBLIC_PATH = '/'
 
 # 线上环境接口地址
-VITE_API_URL = 'https://admin.zhontai.net'
+# VITE_API_URL = 'https://admin.zhontai.net'
+VITE_API_URL = 'http://192.144.191.50:8000'

+ 128 - 0
src/api/admin/Notice.ts

@@ -0,0 +1,128 @@
+/* eslint-disable */
+/* tslint:disable */
+/*
+ * ---------------------------------------------------------------
+ * ## THIS FILE WAS GENERATED VIA SWAGGER-TYPESCRIPT-API        ##
+ * ##                                                           ##
+ * ## AUTHOR: acacode                                           ##
+ * ## SOURCE: https://github.com/acacode/swagger-typescript-api ##
+ * ---------------------------------------------------------------
+ */
+
+import { AxiosResponse } from 'axios'
+import {    
+    ResultOutputInt64,
+    ResultOutputPageOutputNoticeGetPageOutput,    
+    ResultOutputNoticeGetOutput,
+    NoticeAddInput,    
+    NoticeUpdateInput,    
+    PageInputNoticeGetPageDto,
+} from './data-contracts'
+import { ContentType, HttpClient, RequestParams } from './http-client'
+
+export class NoticeApi<SecurityDataType = unknown> extends HttpClient<SecurityDataType> {
+    /**
+     * No description
+     *
+     * @tags notice
+     * @name Get
+     * @summary 查询公告
+     * @request GET:/api/admin/notice/get
+     * @secure
+     */
+    get = (
+        query?: {
+            /** @format int64 */
+            id?: number
+        },
+        params: RequestParams = {}
+    ) =>
+        this.request<ResultOutputNoticeGetOutput, any>({
+            path: `/api/admin/notice/get`,
+            method: 'GET',
+            query: query,
+            secure: true,
+            format: 'json',
+            ...params,
+        })
+    /**
+     * No description
+     *
+     * @tags notice
+     * @name GetPage
+     * @summary 查询分页
+     * @request POST:/api/admin/notice/get-page
+     * @secure
+     */
+    getPage = (data: PageInputNoticeGetPageDto, params: RequestParams = {}) =>
+        this.request<ResultOutputPageOutputNoticeGetPageOutput, any>({
+            path: `/api/admin/notice/get-page`,
+            method: 'POST',
+            body: data,
+            secure: true,
+            type: ContentType.Json,
+            format: 'json',
+            ...params,
+        })
+        
+    /**
+     * No description
+     *
+     * @tags notice
+     * @name Add
+     * @summary 新增公告
+     * @request POST:/api/admin/notice/add
+     * @secure
+     */
+    add = (data: NoticeAddInput, params: RequestParams = {}) =>
+        this.request<ResultOutputInt64, any>({
+            path: `/api/admin/notice/add`,
+            method: 'POST',
+            body: data,
+            secure: true,
+            type: ContentType.Json,
+            format: 'json',
+            ...params,
+        })
+    /**
+     * No description
+     *
+     * @tags notice
+     * @name Update
+     * @summary 修改公告
+     * @request PUT:/api/admin/notice/update
+     * @secure
+     */
+    update = (data: NoticeUpdateInput, params: RequestParams = {}) =>
+        this.request<AxiosResponse, any>({
+            path: `/api/admin/notice/update`,
+            method: 'PUT',
+            body: data,
+            secure: true,
+            type: ContentType.Json,
+            ...params,
+        })          
+    /**
+     * No description
+     *
+     * @tags notice
+     * @name SoftDelete
+     * @summary 删除公告
+     * @request DELETE:/api/admin/notice/soft-delete
+     * @secure
+     */
+    softDelete = (
+        query?: {
+            /** @format int64 */
+            id?: number
+        },
+        params: RequestParams = {}
+    ) =>
+        this.request<AxiosResponse, any>({
+            path: `/api/admin/notice/soft-delete`,
+            method: 'DELETE',
+            query: query,
+            secure: true,
+            ...params,
+        })       
+}

+ 140 - 0
src/api/admin/data-contracts.ts

@@ -4643,4 +4643,144 @@ export interface ProjectPriceAddInput {
    * @minLength 1
    */
   price: number  
+}
+
+/** 添加公告 */
+export interface NoticeAddInput {
+  /**
+   * Id
+   * @format int64
+   */
+  id?: number
+  /**
+   * 标题
+   * @minLength 1
+   */
+  title: string
+  /**
+   * 内容
+   * @minLength 1
+   */
+  content: string
+  /** 排序 */
+  rank: number
+  /** 是否弹窗 1弹窗 0不弹窗 */
+  isAlter: number
+  tags: string
+  
+}
+/** 修改公告 */
+export interface NoticeUpdateInput {
+  
+  /**
+   * 标题
+   * @minLength 1
+   */
+  title: string
+  /**
+   * 内容
+   * @minLength 1
+   */
+  content: string
+  /** 排序 */
+  rank: number
+  /** 是否弹窗 1弹窗 0不弹窗 */
+  isAlter: number
+  tags: string
+  /**
+  * 主键Id
+  * @format int64
+  */
+  id: number
+}
+/** 公告分页信息输入 */
+export interface PageInputNoticeGetPageDto {
+  /**
+   * 当前页标
+   * @format int32
+   */
+  currentPage?: number
+  /**
+   * 每页大小
+   * @format int32
+   */
+  pageSize?: number
+  dynamicFilter?: DynamicFilterInfo
+  /** 用户分页查询条件 */
+  filter?: {}
+}
+/** 公告列表结果输出 */
+export interface ResultOutputPageOutputNoticeGetPageOutput {
+  /** 是否成功标记 */
+  success?: boolean
+  /** 编码 */
+  code?: string | null
+  /** 消息 */
+  msg?: string | null
+  /** 分页信息输出 */
+  data?: PageOutputNoticeGetPageOutput
+}
+/** 分页信息输出 */
+export interface PageOutputNoticeGetPageOutput {
+  /**
+   * 数据总数
+   * @format int64
+   */
+  total?: number
+  /** 数据 */
+  list?: NoticeGetPageOutput[] | null
+}
+export interface NoticeGetPageOutput {
+  /**
+  * 标题  
+  */
+  title: string
+  /**
+   * 内容   
+   */
+  content: string
+  /** 排序 */
+  rank: number
+  /** 是否弹窗 1弹窗 0不弹窗 */
+  isAlter: number
+  /**
+   * 主键Id   
+   */
+  id: number
+  /**
+   * 创建时间
+   * @format date-time
+   */
+  createdTime?: string | null
+}
+/** 公告结果输出 */
+export interface ResultOutputNoticeGetOutput {
+  /** 是否成功标记 */
+  success?: boolean
+  /** 编码 */
+  code?: string | null
+  /** 消息 */
+  msg?: string | null
+  data?: NoticeGetOutput
+}
+export interface NoticeGetOutput {
+  /**
+   * 标题
+   * @minLength 1
+   */
+  title: string
+  /**
+   * 内容
+   * @minLength 1
+   */
+  content: string
+  /** 排序 */
+  rank: number
+  /** 是否弹窗 1弹窗 0不弹窗 */
+  isAlter: number
+  /**
+   * 主键Id
+   * @format int64
+   */
+  id: number
 }

+ 2 - 0
src/types/mitt.d.ts

@@ -22,6 +22,7 @@
  * @method refreshUser 刷新用户
  * @method refreshView 刷新视图
  * @method refreshProject 刷新項目
+ * @method refreshNotice 刷新項目
  */
 declare type MittType<T = any> = {
   openSetingsDrawer?: string
@@ -47,6 +48,7 @@ declare type MittType<T = any> = {
   refreshView?: T
   refreshFile?: T
   refreshProject?: T
+  refreshNotice?: T
 }
 
 // mitt 参数类型定义

+ 140 - 0
src/views/admin/notice/components/notice-form.vue

@@ -0,0 +1,140 @@
+<template>
+  <div>    
+    <el-dialog
+      v-model="state.showDialog"
+      destroy-on-close
+      :title="title"
+      draggable
+      :close-on-click-modal="false"
+      :close-on-press-escape="false"
+      width="769px"
+    >
+      <el-form ref="formRef" :model="form" size="default" label-width="80px">
+        <el-row :gutter="35">
+          <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+            <el-form-item label="标题" prop="title" :rules="[{ required: true, message: '请输入标题', trigger: ['blur', 'change'] }]">
+              <el-input v-model="form.title" autocomplete="off" />
+            </el-form-item>
+          </el-col>
+          <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+              <el-form-item label="内容">                
+                <Editor v-model:get-html="state.editor.htmlVal" v-model:get-text="state.editor.textVal" :disable="state.editor.disable" />
+              </el-form-item>
+            </el-col>                                          
+          <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+            <el-form-item label="排序" prop="rank" placeholder="填写排序数值,越大越靠前" >
+              <el-input v-model="form.rank" autocomplete="off" />
+            </el-form-item>
+          </el-col>          
+            <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+                <el-form-item label="公告标签" prop="Tags" >
+                  <el-radio-group v-model="form.tags">
+                    <el-radio label="最新" ></el-radio>
+                    <el-radio label="重要"></el-radio>
+                  </el-radio-group>
+                </el-form-item>
+              </el-col>                                        
+        </el-row>
+      </el-form>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="onCancel" size="default">取 消</el-button>
+          <el-button type="primary" @click="onSure" size="default" :loading="state.sureLoading">确 定</el-button>
+        </span>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script lang="ts" setup name="admin/notice/form">
+
+// import { stat } from 'fs'
+import { reactive, toRefs, getCurrentInstance, ref, defineAsyncComponent } from 'vue'
+import { NoticeAddInput, NoticeUpdateInput } from '/@/api/admin/data-contracts'
+import { NoticeApi } from '/@/api/admin/Notice'
+import eventBus from '/@/utils/mitt'
+// 引入组件
+const Editor = defineAsyncComponent(() => import('/@/components/editor/index.vue'))
+
+
+defineProps({
+  title: {
+    type: String,
+    default: '',
+  },
+})
+
+const { proxy } = getCurrentInstance() as any
+
+
+const formRef = ref()
+const state = reactive({
+  showDialog: false,
+  sureLoading: false,  
+  form: {} as NoticeAddInput & NoticeUpdateInput, 
+  editor: {
+    htmlVal:'',
+    textVal: '',
+    disable: false,
+  }, 
+})
+const { form } = toRefs(state)
+
+
+// 打开对话框
+const open = async (row: any = {}) => {  
+    
+  if (row.id > 0) {
+    const res = await new NoticeApi().get({ id: row.id }, { loading: true }).catch(() => {
+      proxy.$modal.closeLoading()
+    })
+
+    if (res?.success) {
+      state.form = res.data as NoticeAddInput & NoticeUpdateInput      
+    }
+  } else {
+    state.form = {} as NoticeAddInput & NoticeUpdateInput
+    state.form.tags = '最新';
+    state.editor.htmlVal = '';
+    state.editor.textVal = '';    
+  }
+  state.showDialog = true
+}
+
+
+// 取消
+const onCancel = () => {   
+  state.showDialog = false
+}
+
+// 确定
+const onSure = () => {
+  formRef.value.validate(async (valid: boolean) => {
+    if (!valid) return
+
+    state.form.content = state.editor.htmlVal;
+
+    state.sureLoading = true
+    let res = {} as any
+    if (state.form.id != undefined && state.form.id > 0) {
+      res = await new NoticeApi().update(state.form, { showSuccessMessage: true }).catch(() => {
+        state.sureLoading = false
+      })
+    } else {
+      res = await new NoticeApi().add(state.form, { showSuccessMessage: true }).catch(() => {
+        state.sureLoading = false
+      })
+    }
+    state.sureLoading = false
+
+    if (res?.success) {
+      eventBus.emit('refreshNotice')
+      state.showDialog = false
+    }
+  })
+}
+
+defineExpose({
+  open,
+})
+</script>

+ 131 - 0
src/views/admin/notice/index.vue

@@ -0,0 +1,131 @@
+<template>
+  <div class="my-layout">
+    <el-card class="mt8" shadow="never" :body-style="{ paddingBottom: '0' }">
+      <el-form :inline="true" @submit.stop.prevent>        
+        <el-form-item>          
+          <el-button v-auth="'api:admin:notice:add'" type="primary" icon="ele-Plus" @click="onAdd"> 新增 </el-button>
+        </el-form-item>
+      </el-form>
+    </el-card>
+
+    <el-card class="my-fill mt8" shadow="never">
+      <el-table v-loading="state.loading" :data="state.tenantListData" row-key="id" height="'100%'" style="width: 100%; height: 100%">
+        <el-table-column prop="title" label="标题" min-width="120" show-overflow-tooltip />
+        <el-table-column prop="createdTime" label="添加时间" width="180" show-overflow-tooltip />        
+        <el-table-column prop="rank" label="排序" width="120" show-overflow-tooltip />                        
+        <el-table-column label="操作" width="140" header-align="center" align="center" fixed="right">
+          <template #default="{ row }">
+            <el-button v-auth="'api:admin:notice:update'" icon="ele-EditPen" size="small" text type="primary" @click="onEdit(row)">编辑</el-button>
+            <my-dropdown-more v-auths="['api:admin:notice:delete']">
+              <template #dropdown>
+                <el-dropdown-menu>
+                  <el-dropdown-item v-if="auth('api:admin:notice:delete')" @click="onDelete(row)">删除租户</el-dropdown-item>
+                </el-dropdown-menu>
+              </template>
+            </my-dropdown-more>
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <div class="my-flex my-flex-end" style="margin-top: 20px">
+        <el-pagination
+          v-model:currentPage="state.pageInput.currentPage"
+          v-model:page-size="state.pageInput.pageSize"
+          :total="state.total"
+          :page-sizes="[10, 20, 50, 100]"
+          small
+          background
+          @size-change="onSizeChange"
+          @current-change="onCurrentChange"
+          layout="total, sizes, prev, pager, next, jumper"
+        />
+      </div>
+    </el-card>
+
+    <notice-form ref="noticeFormRef" :title="state.noticeFormTitle"></notice-form>
+  </div>
+</template>
+
+<script lang="ts" setup name="admin/notice">
+import { ref, reactive, onMounted, getCurrentInstance, onBeforeMount, defineAsyncComponent } from 'vue'
+import { NoticeGetPageOutput, PageInputNoticeGetPageDto } from '/@/api/admin/data-contracts'
+import { NoticeApi } from '/@/api/admin/Notice'
+import eventBus from '/@/utils/mitt'
+import { auth } from '/@/utils/authFunction'
+
+// 引入组件
+const NoticeForm = defineAsyncComponent(() => import('./components/notice-form.vue'))
+const MyDropdownMore = defineAsyncComponent(() => import('/@/components/my-dropdown-more/index.vue'))
+
+const { proxy } = getCurrentInstance() as any
+
+const noticeFormRef = ref()
+
+const state = reactive({
+  loading: false,
+  noticeFormTitle: '',
+  total: 0,
+  filter: {
+    
+  },
+  pageInput: {
+    currentPage: 1,
+    pageSize: 20,
+  } as PageInputNoticeGetPageDto,
+  tenantListData: [] as Array<NoticeGetPageOutput>,
+})
+
+onMounted(() => {
+  onQuery()
+  eventBus.off('refreshNotice')
+  eventBus.on('refreshNotice', async () => {
+    onQuery()
+  })
+})
+
+onBeforeMount(() => {
+  eventBus.off('refreshNotice')
+})
+
+const onQuery = async () => {
+  state.loading = true
+  state.pageInput.filter = state.filter
+  const res = await new NoticeApi().getPage(state.pageInput).catch(() => {
+    state.loading = false
+  })
+
+  state.tenantListData = res?.data?.list ?? []
+  state.total = res?.data?.total ?? 0
+  state.loading = false
+}
+
+const onAdd = () => {
+  state.noticeFormTitle = '新增公告'  
+  noticeFormRef.value.open()
+}
+
+const onEdit = (row: NoticeGetPageOutput) => {
+  state.noticeFormTitle = '编辑公告'
+  noticeFormRef.value.open(row)
+}
+
+const onDelete = (row: NoticeGetPageOutput) => {
+  proxy.$modal
+    .confirmDelete(`确定要删除【${row.title}】?`)
+    .then(async () => {
+      await new NoticeApi().softDelete({ id: row.id }, { loading: true, showSuccessMessage: true })
+      onQuery()
+    })
+    .catch(() => {})
+}
+
+const onSizeChange = (val: number) => {
+  state.pageInput.pageSize = val
+  onQuery()
+}
+
+const onCurrentChange = (val: number) => {
+  state.pageInput.currentPage = val
+  onQuery()
+}
+</script>

+ 1 - 1
src/views/admin/tenant/index.vue

@@ -130,7 +130,7 @@ const onQuery = async () => {
 }
 
 const onAdd = () => {
-  state.tenantFormTitle = '新增租户'
+  state.tenantFormTitle = '新增租户'  
   tenantFormRef.value.open()
 }