Browse Source

夸克相关功能开发

zmq 1 year ago
parent
commit
80c41ec728

+ 26 - 46
src/api/admin/Banner.ts

@@ -12,13 +12,15 @@
 import { AxiosResponse } from 'axios'
 import {
     ResultOutputBannerGetOutput,
+    PageInputBannerGetPageDto,
+    ResultOutputPageOutputBannerListOutput,
 
     ResultOutputInt64,
-    ResultOutputPageOutputNoticeGetPageOutput,
+    
     ResultOutputNoticeGetOutput,
-    NoticeAddInput,
-    NoticeUpdateInput,
-    PageInputNoticeGetPageDto,
+    BannerAddInput,
+    BannerUpdateInput,
+    
 } from './data-contracts'
 import { ContentType, HttpClient, RequestParams } from './http-client'
 
@@ -56,8 +58,8 @@ export class BannerApi<SecurityDataType = unknown> extends HttpClient<SecurityDa
      * @request POST:/api/admin/banner/get-page
      * @secure
      */
-    getPage = (data: PageInputNoticeGetPageDto, params: RequestParams = {}) =>
-        this.request<ResultOutputPageOutputNoticeGetPageOutput, any>({
+    getPage = (data: PageInputBannerGetPageDto, params: RequestParams = {}) =>
+        this.request<ResultOutputPageOutputBannerListOutput, any>({
             path: `/api/admin/banner/get-page`,
             method: 'POST',
             body: data,
@@ -70,15 +72,15 @@ export class BannerApi<SecurityDataType = unknown> extends HttpClient<SecurityDa
     /**
      * No description
      *
-     * @tags notice
+     * @tags banner
      * @name Add
-     * @summary 新增公告
-     * @request POST:/api/admin/notice/add
+     * @summary 新增轮播图
+     * @request POST:/api/admin/banner/add
      * @secure
      */
-    add = (data: NoticeAddInput, params: RequestParams = {}) =>
+    add = (data: BannerAddInput, params: RequestParams = {}) =>
         this.request<ResultOutputInt64, any>({
-            path: `/api/admin/notice/add`,
+            path: `/api/admin/banner/add`,
             method: 'POST',
             body: data,
             secure: true,
@@ -89,15 +91,15 @@ export class BannerApi<SecurityDataType = unknown> extends HttpClient<SecurityDa
     /**
      * No description
      *
-     * @tags notice
+     * @tags banner
      * @name Update
-     * @summary 修改公告
-     * @request PUT:/api/admin/notice/update
+     * @summary 修改轮播图
+     * @request PUT:/api/admin/banner/update
      * @secure
      */
-    update = (data: NoticeUpdateInput, params: RequestParams = {}) =>
+    update = (data: BannerUpdateInput, params: RequestParams = {}) =>
         this.request<AxiosResponse, any>({
-            path: `/api/admin/notice/update`,
+            path: `/api/admin/banner/update`,
             method: 'PUT',
             body: data,
             secure: true,
@@ -107,48 +109,26 @@ export class BannerApi<SecurityDataType = unknown> extends HttpClient<SecurityDa
     /**
      * No description
      *
-     * @tags notice
+     * @tags banner
      * @name SoftDelete
-     * @summary 删除公告
+     * @summary 修改状态
      * @request DELETE:/api/admin/notice/soft-delete
      * @secure
      */
-    softDelete = (
-        query?: {
+    updateStatus = (
+        query?: {            
             /** @format int64 */
-            id?: number
+            id?: number,
+            status?:number
         },
         params: RequestParams = {}
     ) =>
         this.request<AxiosResponse, any>({
             path: `/api/admin/notice/soft-delete`,
-            method: 'DELETE',
+            method: 'get',
             query: query,
             secure: true,
             ...params,
-        })
-    /**
-     * No description
-     *
-     * @tags notice
-     * @name Get
-     * @summary 查询重要公告
-     * @request GET:/api/admin/notice/get-weight
-     * @secure
-     */
-    getWeight = (
-        query?: {
-
-        },
-        params: RequestParams = {}
-    ) =>
-        this.request<ResultOutputNoticeGetOutput, any>({
-            path: `/api/admin/notice/get-weight`,
-            method: 'GET',
-            query: query,
-            secure: true,
-            format: 'json',
-            ...params,
-        })
+        })    
 }
 

+ 66 - 0
src/api/admin/KuaKe.ts

@@ -0,0 +1,66 @@
+import { AxiosResponse } from 'axios'
+import {
+    PageInputAdKuaKePageInput,
+    ResultOutputPageOutputAdKuaKePageOutput,  
+    UpdateKuaKeStatusInput
+} from './data-contracts'
+import { ContentType, HttpClient, RequestParams } from './http-client'
+
+export class KuaKeApi<SecurityDataType = unknown> extends HttpClient<SecurityDataType>{
+    /**
+   * No description
+   *
+   * @tags ad-kua-ke
+   * @name GetPage
+   * @summary 查询分页
+   * @request POST:/api/admin/ad-kua-ke/get-page
+   * @secure
+   */
+    getPage = (data: PageInputAdKuaKePageInput, params: RequestParams = {}) =>
+        this.request<ResultOutputPageOutputAdKuaKePageOutput, any>({
+            path: `/api/admin/ad-kua-ke/get-page`,
+            method: 'Post',
+            body: data,
+            secure: true,
+            type: ContentType.Json,
+            format: 'json',
+            ...params,
+        })     
+    /**
+     * No description
+     *
+     * @tags ad-kua-ke
+     * @name update-status
+     * @summary 修改状态
+     * @request PUT:/api/admin/notice/update
+     * @secure
+     */
+    updateStatus = (data: UpdateKuaKeStatusInput, params: RequestParams = {}) =>
+        this.request<AxiosResponse, any>({
+            path: `/api/admin/ad-kua-ke/update-status`,
+            method: 'PUT',
+            body: data,
+            secure: true,
+            type: ContentType.Json,
+            ...params,
+        })
+    /**
+   * No description
+   *
+   * @tags ad-kua-ke
+   * @name GetPage
+   * @summary 导出excel
+   * @request POST:/api/admin/ad-kua-ke/get-excel
+   * @secure
+   */
+    getExcel = (data: PageInputAdKuaKePageInput, params: RequestParams = {}) =>
+        this.request<AxiosResponse, any>({
+            path: `/api/admin/ad-kua-ke/get-excel`,
+            method: 'Post',
+            body: data,
+            secure: true,
+            type: ContentType.Json,
+            format: 'json',
+            ...params,
+        })
+}

+ 157 - 2
src/api/admin/data-contracts.ts

@@ -4630,6 +4630,8 @@ export interface ProjectGetOutput {
   id?: number | null
   /** 价格 */
   prices?: ProjectPriceAddInput[] | null
+  // 项目类型 1拉新 2夸克
+  projectType: number
 }
 /** 结果输出 */
 export interface ResultOutputListProjectSelectOutput {
@@ -4688,6 +4690,8 @@ export interface ProjectAddInput {
   hotWords: string  
   // 项目价格
   prices: ProjectPriceAddInput[]
+  // 项目类型 1拉新 2夸克
+  projectType:number
 }
 /** 修改项目 */
 export interface ProjectUpdateInput {
@@ -4732,6 +4736,8 @@ export interface ProjectUpdateInput {
 
   // 项目价格
   prices: ProjectPriceAddInput[]
+  // 项目类型 1拉新 2夸克
+  projectType: number
 }
 export interface ProjectPriceAddInput {
   /**
@@ -5353,7 +5359,7 @@ export interface PageInputBannerGetPageDto {
 export interface BannerGetPageDto{ 
   status?: number
 }
-/** 公告列表结果输出 */
+/** 轮播分页结果输出 */
 export interface ResultOutputPageOutputBannerListOutput {
   /** 是否成功标记 */
   success?: boolean
@@ -5400,6 +5406,59 @@ export interface BannerListOutput {
    */
   id: number  
 }
+/** 添加轮播图 */
+export interface BannerAddInput {
+  /**
+   * Id
+   * @format int64
+   */
+  id?: number
+  /**
+   * 活动名称   
+   */
+  name: string
+  /**
+   * 跳转方式   
+   */
+  skipWay: number
+  /**
+   * 跳转参数 文章Id或项目Id   
+   */
+  skipContent: string
+  /**
+   * 活动图片
+   */
+  imgUrl: string
+  /** 排序 数值越大越靠前 */
+  rank: number  
+}
+/** 修改轮播图 */
+export interface BannerUpdateInput {
+
+  /**
+    * Id
+    * @format int64
+    */
+  id: number
+  /**
+   * 活动名称   
+   */
+  name: string
+  /**
+   * 跳转方式   
+   */
+  skipWay: number
+  /**
+   * 跳转参数 文章Id或项目Id   
+   */
+  skipContent: string
+  /**
+   * 活动图片
+   */
+  imgUrl: string
+  /** 排序 数值越大越靠前 */
+  rank: number
+}
 /** 结果输出 */
 export interface ResultOutputListTenantSelectListOutput {
   /** 是否成功标记 */
@@ -5415,4 +5474,100 @@ export interface TenantSelectListOutput {
   id?: number | null
   /** 企业名称 */
   name?: string | null 
-}
+}
+
+//#region 夸克相关接口
+/** 夸克分页信息输入 */
+export interface PageInputAdKuaKePageInput {
+  /**
+   * 当前页标
+   * @format int32
+   */
+  currentPage?: number
+  /**
+   * 每页大小
+   * @format int32
+   */
+  pageSize?: number
+  dynamicFilter?: DynamicFilterInfo
+  filter?: AdKuaKePageInput
+}
+export interface AdKuaKePageInput {
+  /**
+   * 开始日期  
+   */
+  beginDate?: string | null,
+  /**
+   * 结束日期 
+   */
+  endDate?: string | null,
+  /**
+   * 平台 
+   */
+  tenantId?: number | null,
+  /**
+   * 状态
+   */
+  status?: number | null,
+  /**
+   * 关键字 夸克Id,姓名,手机号  
+   */
+  keyword: string
+}
+/** 结果输出 */
+export interface ResultOutputPageOutputAdKuaKePageOutput {
+  /** 是否成功标记 */
+  success?: boolean
+  /** 编码 */
+  code?: string | null
+  /** 消息 */
+  msg?: string | null
+  /** 分页信息输出 */
+  data?: PageOutputAdKuaKePageOutput
+}
+export interface PageOutputAdKuaKePageOutput {
+  /**
+   * 数据总数
+   * @format int64
+   */
+  total?: number
+  /** 数据 */
+  list?: AdKuaKePageOutput[] | null
+}
+export interface AdKuaKePageOutput {
+  // id
+  id: number
+  // 平台
+  orgName: string
+  // 所属下级
+  userName: string
+  // 所属下级角色
+  userRole: string
+  // 申请时间
+  createdTime: string
+  // 夸克ID
+  kuaKeID: string
+  // 姓名
+  name: string
+  // 手机号
+  phone: string
+  // 行业
+  industry: string
+  // 推广平台
+  platfrom: string
+  // 状态
+  status: number  
+}
+/**
+ * 更新夸克申请状态
+ */
+export interface UpdateKuaKeStatusInput {
+  // Id
+  ids: Array<number>  
+  // 状态
+  status: number
+}
+//#endregion
+
+
+

+ 5 - 1
src/types/mitt.d.ts

@@ -27,6 +27,8 @@
  * @method refreshProjectPrice 刷新项目价格
  * @method refreshCompanyDraw 刷新公司抽成
  * @method refreshProjectStat 刷新项目统计
+ * @method refreshBanner 刷新轮播图
+ * @method refreshKuaKeInfo 刷新夸克提交申请列表
  */
 declare type MittType<T = any> = {
   openSetingsDrawer?: string
@@ -56,7 +58,9 @@ declare type MittType<T = any> = {
   refreshProjectLink?: T
   refreshProjectPrice?: T
   refreshCompanyDraw?: T
-  refreshProjectStat?:T
+  refreshProjectStat?: T
+  refreshBanner?: T
+  refreshKuaKeInfo?:T
 }
 
 // mitt 参数类型定义

+ 213 - 0
src/views/admin/banner/components/banner-form.vue

@@ -0,0 +1,213 @@
+<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="500px"
+    >
+      <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="name" :rules="[{ required: true, message: '请输入活动名称', trigger: ['blur', 'change'] }]">
+              <el-input v-model="form.name" autocomplete="off" placeholder="活动名称"/>
+            </el-form-item>
+          </el-col>
+          <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+              <el-form-item label="跳转方式">
+                <el-select v-model="form.skipWay" prop="skipWay" placeholder="跳转方式">                  
+                  <el-option label="请选择" value="0"></el-option>
+                  <el-option label="文章详情" value="1"></el-option>
+                  <el-option label="项目详情" value="2"></el-option>
+                </el-select>                
+              </el-form-item>
+            </el-col>                                          
+          <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+            <el-form-item label="跳转参数" prop="skipContent">
+              <el-input v-model="form.skipContent" autocomplete="off" placeholder="文章ID或项目ID(不填写则无跳转)"/>
+            </el-form-item>
+          </el-col>
+          <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+                  <el-form-item label="活动图片(690X260)" prop="imgUrl" :rules="[{ required: true, message: '请上传活动图片'}]">
+                    <el-upload class="avatar-uploader"                  
+                  :data="{ fileDirectory: state.fileDirectory }"
+                  :action="ImgAction"  
+                  :headers="imgHeaders"
+                  :show-file-list="false" 
+                  :on-success="onImgSuccess"
+              :on-error="onImgError">
+                    <img v-if="form.imgUrl" :src="form.imgUrl" class="avatar">
+                    <i v-else class="el-icon-plus avatar-uploader-icon"></i>
+                    </el-upload>                                   
+                  </el-form-item>
+                </el-col>
+          <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+              <el-form-item label="排序" prop="rank" >
+                <el-input v-model="form.rank" autocomplete="off" placeholder="数值越大越靠前"/>
+              </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/banner/form">
+
+// import { stat } from 'fs'
+import { reactive, toRefs, getCurrentInstance, ref, computed } from 'vue'
+import { BannerAddInput, BannerUpdateInput } from '/@/api/admin/data-contracts'
+import { BannerApi } from '/@/api/admin/Banner'
+import eventBus from '/@/utils/mitt'
+import { useUserInfo } from '/@/stores/userInfo'
+import pinia from '/@/stores/index'
+import { AxiosResponse } from 'axios'
+
+const storesUserInfo = useUserInfo(pinia)
+
+
+defineProps({
+  title: {
+    type: String,
+    default: '',
+  },
+})
+
+const { proxy } = getCurrentInstance() as any
+
+
+const formRef = ref()
+const state = reactive({
+  showDialog: false,
+  sureLoading: false,  
+  form: {} as BannerAddInput & BannerUpdateInput,   
+  token: storesUserInfo.getToken(),
+  fileDirectory:'banners',
+  imgLoading:false
+})
+const { form } = toRefs(state)
+
+
+// 打开对话框
+const open = async (row: any = {}) => {  
+    
+  if (row.id > 0) {
+    const res = await new BannerApi().get({ id: row.id }, { loading: true }).catch(() => {
+      proxy.$modal.closeLoading()
+    })
+
+    if (res?.success) {
+      state.form = res.data as BannerAddInput & BannerUpdateInput     
+    }
+  } else {
+    state.form = {} as BannerAddInput & BannerUpdateInput    
+  }
+  state.showDialog = true
+}
+
+
+// 取消
+const onCancel = () => {   
+  state.showDialog = false
+}
+
+// 确定
+const onSure = () => {
+  formRef.value.validate(async (valid: boolean) => {
+    if (!valid) return    
+    state.sureLoading = true    
+    let res = {} as any
+    if (state.form.id != undefined && state.form.id > 0) {
+      res = await new BannerApi().update(state.form, { showSuccessMessage: true }).catch(() => {
+        state.sureLoading = false
+      })
+    } else {
+      res = await new BannerApi().add(state.form, { showSuccessMessage: true }).catch(() => {
+        state.sureLoading = false
+      })
+    }
+    state.sureLoading = false
+
+    if (res?.success) {
+      eventBus.emit('refreshBanner')
+      state.showDialog = false
+    }
+  })
+}
+// 上传请求url
+const ImgAction = computed(() => {
+  return import.meta.env.VITE_API_URL + '/api/admin/file/upload-file'
+})
+// 上传请求头部
+const imgHeaders = computed(() => {
+  return { Authorization: 'Bearer ' + state.token }
+})
+// 上传头像成功
+const onImgSuccess = (res: AxiosResponse) => {
+  state.imgLoading = false  
+  if (!res?.success) {
+    if (res.msg) {
+      proxy.$modal.msgError(res.msg)
+    }
+    return
+  }
+  
+  state.form.imgUrl = res?.data?.linkUrl  
+}
+
+// 上传头像失败
+const onImgError = (error: any) => {
+  state.imgLoading = false
+  let message = ''
+  if (error.message) {
+    try {
+      message = JSON.parse(error.message)?.msg
+    } catch (err) {
+      message = error.message || ''
+    }
+  }
+  if (message) proxy.$modal.msgError(message)
+}
+
+defineExpose({
+  open,
+})
+</script>
+<style>
+.avatar-uploader .el-upload {
+  border: 1px dashed #d9d9d9;
+  border-radius: 6px;
+  cursor: pointer;
+  position: relative;
+  overflow: hidden;
+}
+
+.avatar-uploader .el-upload:hover {
+  border-color: #409EFF;
+}
+
+.avatar-uploader-icon {
+  font-size: 28px;
+  color: #8c939d;
+  width: 300px;
+  height: 120px;
+  line-height: 100px;
+  text-align: center;
+}
+
+.avatar {
+  width: 300px;
+  height: 120px;
+  display: block;
+}
+</style>

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

@@ -1,141 +0,0 @@
-<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        
-      state.editor.htmlVal = state.form.content;      
-    }
-  } 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>

+ 37 - 28
src/views/admin/banner/index.vue

@@ -2,24 +2,33 @@
   <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-select placeholder="请选择状态" v-model="state.filter.status" value-key="id" clearable >                                         
+                <el-option label="待上架" value="0" ></el-option>
+                <el-option label="上架" value="1" ></el-option>
+                <el-option label="下架" value="2" ></el-option>
+            </el-select>
+          </el-form-item>
         <el-form-item>
-          <el-button v-auth="'api:admin:notice:add'" type="primary" icon="ele-Plus" @click="onAdd"> 新增
+          <el-button type="primary" icon="ele-Search" @click="onQuery"> 查询 </el-button>
+          <el-button v-auth="'api:admin:banner: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%'"
+      <el-table v-loading="state.loading" :data="state.listData" 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="name" label="活动名称" min-width="120" show-overflow-tooltip />
+        <el-table-column prop="imgUrl" label="活动图片" width="180" show-overflow-tooltip />
+        <el-table-column prop="status" 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"
+            <el-button v-auth="'api:admin:banner:update'" icon="ele-EditPen" size="small" text type="primary"
               @click="onEdit(row)">编辑</el-button>
-              <el-button v-auth="'api:admin:notice:soft-delete'" icon="ele-Delete" size="small" text type="danger"
+              <el-button v-auth="'api:admin:banner:soft-delete'" icon="ele-Delete" size="small" text type="danger"
                 @click="onDelete(row)">删除</el-button>            
           </template>
         </el-table-column>
@@ -32,78 +41,78 @@
       </div>
     </el-card>
 
-    <notice-form ref="noticeFormRef" :title="state.noticeFormTitle"></notice-form>
+    <banner-form ref="bannerFormRef" :title="state.bannerFormTitle"></banner-form>
   </div>
 </template>
 
-<script lang="ts" setup name="admin/notice/index">
+<script lang="ts" setup name="admin/banner/index">
 import { ref, reactive, onMounted, getCurrentInstance, onBeforeMount, defineAsyncComponent } from 'vue'
-import { NoticeGetPageOutput, PageInputNoticeGetPageDto } from '/@/api/admin/data-contracts'
-import { NoticeApi } from '/@/api/admin/Notice'
+import { BannerListOutput, PageInputbannerGetPageDto } from '/@/api/admin/data-contracts'
+import { BannerApi } from '/@/api/admin/Banner'
 import eventBus from '/@/utils/mitt'
 import { auth } from '/@/utils/authFunction'
 
 // 引入组件
-const NoticeForm = defineAsyncComponent(() => import('./components/notice-form.vue'))
+const bannerForm = defineAsyncComponent(() => import('./components/banner-form.vue'))
 const MyDropdownMore = defineAsyncComponent(() => import('/@/components/my-dropdown-more/index.vue'))
 
 const { proxy } = getCurrentInstance() as any
 
-const noticeFormRef = ref()
+const bannerFormRef = ref()
 
 const state = reactive({
   loading: false,
-  noticeFormTitle: '',
+  bannerFormTitle: '',
   total: 0,
   filter: {
-
+      status:''
   },
   pageInput: {
     currentPage: 1,
     pageSize: 20,
-  } as PageInputNoticeGetPageDto,
-  tenantListData: [] as Array<NoticeGetPageOutput>,
+  } as PageInputbannerGetPageDto,
+  listData: [] as Array<BannerListOutput>,
 })
 
 onMounted(() => {
   onQuery()
-  eventBus.off('refreshNotice')
-  eventBus.on('refreshNotice', async () => {
+  eventBus.off('refreshBanner')
+  eventBus.on('refreshBanner', async () => {
     onQuery()
   })
 })
 
 onBeforeMount(() => {
-  eventBus.off('refreshNotice')
+  eventBus.off('refreshBanner')
 })
 
 const onQuery = async () => {
   state.loading = true
   state.pageInput.filter = state.filter
-  const res = await new NoticeApi().getPage(state.pageInput).catch(() => {
+  const res = await new BannerApi().getPage(state.pageInput).catch(() => {
     state.loading = false
   })
 
-  state.tenantListData = res?.data?.list ?? []
+  state.listData = res?.data?.list ?? []
   state.total = res?.data?.total ?? 0
   state.loading = false
 }
 
 const onAdd = () => {
-  state.noticeFormTitle = '新增公告'
-  noticeFormRef.value.open()
+  state.bannerFormTitle = '新增轮播图'
+  bannerFormRef.value.open()
 }
 
-const onEdit = (row: NoticeGetPageOutput) => {
-  state.noticeFormTitle = '编辑公告'
-  noticeFormRef.value.open(row)
+const onEdit = (row: bannerGetPageOutput) => {
+  state.bannerFormTitle = '编辑轮播图'
+  bannerFormRef.value.open(row)
 }
 
-const onDelete = (row: NoticeGetPageOutput) => {
+const onDelete = (row: bannerGetPageOutput) => {
   proxy.$modal
     .confirmDelete(`确定要删除【${row.title}】?`)
     .then(async () => {
-      await new NoticeApi().softDelete({ id: row.id }, { loading: true, showSuccessMessage: true })
+      await new BannerApi().softDelete({ id: row.id }, { loading: true, showSuccessMessage: true })
       onQuery()
     })
     .catch(() => { })

+ 197 - 0
src/views/admin/kuake/index.vue

@@ -0,0 +1,197 @@
+<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-date-picker v-model="state.filter.beginDate" type="date" placeholder="开始日期"
+                     style="width: 140px;"></el-date-picker>                        
+                    </el-form-item>
+                    <el-form-item>
+                        <el-date-picker v-model="state.filter.endDate" type="date" placeholder="结束日期"
+                         style="width: 140px;"></el-date-picker>                        
+                    </el-form-item>
+                <el-form-item>
+                    <el-select placeholder="全部平台" v-model="state.filter.tenantId" value-key="id" clearable style="width: 160px;">
+                        <el-option v-for="item in state.tenantList" :key="item.id" :label="item.name"
+                            :value="item.id"></el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item>
+                        <el-select placeholder="全部状态" v-model="state.filter.status" clearable style="width: 100px;">
+                            <el-option label="未报备" value="1"></el-option>
+                            <el-option label="报备成功" value="2"></el-option>
+                            <el-option label="报备失败" value="3"></el-option>
+                        </el-select>
+                    </el-form-item>
+                <el-form-item>
+                    <el-input v-model="state.filter.keyword" placeholder="夸克ID、推广平台昵称、手机号" />
+                </el-form-item>
+                <el-form-item>
+                    <el-button type="primary" icon="ele-Search" @click="onQuery"> 查询 </el-button>
+                    <el-button :loading="state.excelLoading" type="primary" @click="onDownExcel"> 导出Excel </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.listData" row-key="id" height="'100%'"
+                style="width: 100%; height: 100%">
+                <el-table-column label="所属平台" prop="orgName" min-width="120" show-overflow-tooltip />
+                <el-table-column label="所属下级" min-width="120" show-overflow-tooltip >
+                    <template #default="{ row }">                         
+                            <span v-if="row.userRole === '1'">无</span>
+                            <span v-else>{{ row.userName }}</span>                            
+                        </template>
+                </el-table-column>
+                <el-table-column label="申请时间" prop="createdTime" min-width="180" show-overflow-tooltip />
+                    <el-table-column label="夸克ID" prop="kuaKeID" min-width="160" show-overflow-tooltip />
+                    <el-table-column label="推广平台昵称" prop="name" min-width="120" show-overflow-tooltip />
+                    <el-table-column label="手机号" prop="phone" min-width="120" show-overflow-tooltip />
+                    <el-table-column label="行业" prop="industry" min-width="120" show-overflow-tooltip />
+                    <el-table-column label="推广平台" prop="platfrom" min-width="120" show-overflow-tooltip />
+                <el-table-column label="状态" prop="status" min-width="120" show-overflow-tooltip>
+                    <template #default="{ row }">
+                        <span v-if="row.status==1">未报备</span>
+                        <span v-if="row.status == 2">报备成功</span>
+                        <span v-if="row.status == 3">报备失败</span>                        
+                    </template>
+                </el-table-column>
+                <el-table-column label="操作" width="180" header-align="center" align="center" fixed="right">
+                    <template #default="{ row }">
+                        <el-button v-if="row.status==1" size="small" text type="primary" @click="onYes(row)">报备成功</el-button>
+                        <el-button v-if="row.status == 1" size="small" text type="primary" @click="onNo(row)">报备失败</el-button>                
+                    </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>
+        
+    </div>
+</template>
+<script lang="ts" setup name="admin/kuake">
+import {  onMounted,  reactive, onBeforeMount, getCurrentInstance} from 'vue'
+import { PageInputAdKuaKePageInput, AdKuaKePageOutput, TenantSelectListOutput } from '/@/api/admin/data-contracts'
+import { KuaKeApi } from '/@/api/admin/KuaKe'
+import { TenantApi } from '/@/api/admin/Tenant'
+import { formatPast } from '/@/utils/formatTime'
+
+import eventBus from '/@/utils/mitt'
+
+
+const { proxy } = getCurrentInstance() as any
+
+
+const state = reactive({
+    loading: false,            
+    filter: {       
+        beginDate: '',        
+        endDate: '',        
+        tenantId: '',        
+        status:'',        
+        keyword: ''
+    }, pageInput: {
+        currentPage: 1,
+        pageSize: 20,
+    } as PageInputAdKuaKePageInput,
+    total: 0,
+    listData: [] as Array<AdKuaKePageOutput>,    
+    tenantList: [] as Array<TenantSelectListOutput>,        
+    excelLoading:false
+})
+onMounted(() => {
+    onTenants();
+    onQuery()
+    eventBus.off('refreshKuaKeInfo')
+    eventBus.on('refreshKuaKeInfo', async () => {
+        onQuery()
+    })
+
+})
+onBeforeMount(() => {
+    eventBus.off('refreshKuaKeInfo')
+})
+//查询
+const onQuery = async () => {    
+    state.loading = true
+    state.pageInput.filter = state.filter
+    if (state.filter.beginDate != '')
+        state.pageInput.filter.beginDate = formatPast(state.filter.beginDate)
+    if (state.filter.endDate != '')
+        state.pageInput.filter.endDate = formatPast(state.filter.endDate)
+
+    const res = await new KuaKeApi().getPage(state.pageInput).catch(() => {
+        state.loading = false
+    })
+    state.listData = res?.data?.list ?? []
+    state.total = res?.data?.total ?? 0
+    state.loading = false
+}
+//平台列表
+const onTenants = async () => {
+    let input: any = {}
+    const res = await new TenantApi().getAll(input).catch(() => {
+
+    })
+    state.tenantList = res?.data ?? []    
+}
+//导出推广码模板
+const onDownExcel = () => {            
+    proxy.$modal
+        .confirm('请确定是否导出Excel文件')
+        .then(async () => {
+            state.excelLoading = true
+            state.pageInput.filter = state.filter
+            if (state.filter.beginDate != '')
+                state.pageInput.filter.beginDate = formatPast(state.filter.beginDate)
+            if (state.filter.endDate != '')
+                state.pageInput.filter.endDate = formatPast(state.filter.endDate)
+
+            const res = await new KuaKeApi().getExcel(state.pageInput).catch(() => {
+                state.excelLoading = false
+            })              
+            if (res?.success) { 
+                state.excelLoading = false                
+                window.open(res.data, '_self');
+            }
+        })
+        .catch(() => { })
+}
+//报备成功
+const onYes = (row: AdKuaKePageOutput) => {
+    let ids = new Array<number>;
+    ids.push(row.id);
+    proxy.$modal
+        .confirm('确认报备成功')
+        .then(async () => {
+            await new KuaKeApi().updateStatus({ ids: ids, status:2  }, { loading: true, showSuccessMessage: true })
+            onQuery()
+        })
+        .catch(() => { })
+}
+//报备失败
+const onNo = (row: AdKuaKePageOutput) => {
+    let ids = new Array<number>;
+    ids.push(row.id);
+    proxy.$modal
+        .confirm('确认报备失败')
+        .then(async () => {
+            await new KuaKeApi().updateStatus({ ids: ids, status: 3 }, { 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>

+ 2 - 2
src/views/admin/notice/components/notice-form.vue

@@ -22,8 +22,8 @@
               </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 label="排序" prop="rank"  >
+              <el-input v-model="form.rank" autocomplete="off" placeholder="填写排序数值,越大越靠前"/>
             </el-form-item>
           </el-col>          
             <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">

+ 9 - 1
src/views/admin/project/components/project-form.vue

@@ -11,6 +11,14 @@
     >    
       <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="projectType" :rules="[{ required: true, message: '请输入项目类型', trigger: ['blur', 'change'] }]">                
+                <el-select placeholder="选择项目类型" v-model="form.projectType" clearable >                                         
+                    <el-option label="二维码拉新项目" value="1" checked></el-option>                        
+                    <el-option label="夸克拉新项目" value="2" ></el-option>                        
+                </el-select>
+              </el-form-item>
+            </el-col>
           <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
               <el-form-item label="" prop="logo" :rules="[{ required: true, message: '请上传项目图标', trigger: ['blur', 'change'] }]">
                 <el-upload class="avatar-uploader"
@@ -50,7 +58,7 @@
             </el-col>          
             <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
               <el-form-item label="视频教程" prop="videoUrl">
-                <el-input v-model="form.videoUrl" autocomplete="off" />
+                <el-input v-model="form.videoUrl" autocomplete="off" placeholder="请填写视频网址"/>
               </el-form-item>
             </el-col>
           <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">