zmq 1 anno fa
parent
commit
3dd0ef2163

+ 2 - 2
.env.development

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

+ 49 - 0
src/api/admin/ProjectLink.ts

@@ -0,0 +1,49 @@
+import { AxiosResponse } from 'axios'
+import {
+    pageInputProjectLinkManagePageInput,
+    ResultOutputPageOutputProjectLinkManagePageOutput,
+    PageInputProjectLinkGetPageDto,
+    ResultOutputPageOutputProjectLinkListOutput
+} from './data-contracts'
+import { ContentType, HttpClient, RequestParams } from './http-client'
+
+export class ProjectLinkApi<SecurityDataType = unknown> extends HttpClient<SecurityDataType>{ 
+    /**
+   * No description
+   *
+   * @tags projectlink
+   * @name GetPage
+   * @summary 查询管理分页
+   * @request POST:/api/admin/project-link/get-manage-page
+   * @secure
+   */
+    getPageManage = (data: pageInputProjectLinkManagePageInput, params: RequestParams = {}) =>  
+        this.request<ResultOutputPageOutputProjectLinkManagePageOutput, any>({
+            path: `/api/admin/project-link/get-manage-page`,
+            method: 'Post',
+            body: data,
+            secure: true,
+            type: ContentType.Json,
+            format: 'json',
+            ...params,
+        })
+    /**
+  * No description
+  *
+  * @tags projectlink
+  * @name GetPage
+  * @summary 查询分页
+  * @request POST:/api/admin/project-link/get-page
+  * @secure
+  */
+    getPage = (data: PageInputProjectLinkGetPageDto, params: RequestParams = {}) =>
+        this.request<ResultOutputPageOutputProjectLinkListOutput, any>({
+            path: `/api/admin/project-link/get-page`,
+            method: 'Post',
+            body: data,
+            secure: true,
+            type: ContentType.Json,
+            format: 'json',
+            ...params,
+        })
+}

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

@@ -4631,7 +4631,21 @@ export interface ProjectGetOutput {
   /** 价格 */
   prices?: ProjectPriceAddInput[] | null
 }
-
+/** 结果输出 */
+export interface ResultOutputListProjectSelectOutput {
+  /** 是否成功标记 */
+  success?: boolean
+  /** 编码 */
+  code?: string | null
+  /** 消息 */
+  msg?: string | null
+  /** 分页信息输出 */
+  data?: ProjectSelectOutput[]|null
+}
+export interface ProjectSelectOutput { 
+  id: number
+  name:string
+}
 /** 添加项目 */
 export interface ProjectAddInput {
   /**
@@ -4873,4 +4887,146 @@ export interface NoticeGetOutput {
    * @format int64
    */
   id: number
+}
+/** 项目推广码分页信息输入 */
+export interface pageInputProjectLinkManagePageInput {
+  /**
+   * 当前页标
+   * @format int32
+   */
+  currentPage?: number
+  /**
+   * 每页大小
+   * @format int32
+   */
+  pageSize?: number
+  dynamicFilter?: DynamicFilterInfo
+  filter?: ProjectLinkManagePageInput
+}
+export interface ProjectLinkManagePageInput{   
+  /**
+   * 项目Id  
+   */
+  projectId?: number | null,
+  /**
+   * 关键字  
+   */
+  keywords:string
+}
+/** 结果输出 */
+export interface ResultOutputPageOutputProjectLinkManagePageOutput {
+  /** 是否成功标记 */
+  success?: boolean
+  /** 编码 */
+  code?: string | null
+  /** 消息 */
+  msg?: string | null
+  /** 分页信息输出 */
+  data?: PageOutputProjectLinkManagePageOutput
+}
+export interface PageOutputProjectLinkManagePageOutput { 
+  /**
+   * 数据总数
+   * @format int64
+   */
+  total?: number
+  /** 数据 */
+  list?: ProjectLinkManagePageOutput[] | null
+}
+export interface ProjectLinkManagePageOutput { 
+// 公司(推广码来源)
+  projectName: string	
+  // 公司(推广码来源)
+  company: string	
+  // 使用数量
+  useCount: number	
+  // 总数
+  count: number	
+  // 项目Id
+  projectId: number
+}
+/** 项目推广码明细分页信息输入 */
+export interface PageInputProjectLinkGetPageDto {
+  /**
+   * 当前页标
+   * @format int32
+   */
+  currentPage?: number
+  /**
+   * 每页大小
+   * @format int32
+   */
+  pageSize?: number
+  dynamicFilter?: DynamicFilterInfo
+  filter?: ProjectLinkGetPageDto
+}
+export interface ProjectLinkGetPageDto {
+  /**
+  * 项目Id  
+  */
+  projectId?: number | null,
+  /**
+   * 是否使用 1使用 0未使用  
+   */
+  isUse?: number | null,
+  /**
+   * 平台Id  
+   */
+  tenantId?: number | null,
+  /**
+   * 关键字  
+   */
+  keywords: string
+}
+/** 结果输出 */
+export interface ResultOutputPageOutputProjectLinkListOutput {
+  /** 是否成功标记 */
+  success?: boolean
+  /** 编码 */
+  code?: string | null
+  /** 消息 */
+  msg?: string | null
+  /** 分页信息输出 */
+  data?: PageOutputProjectLinkListOutput
+}
+export interface PageOutputProjectLinkListOutput {
+  /**
+   * 数据总数
+   * @format int64
+   */
+  total?: number
+  /** 数据 */
+  list?: ProjectLinkListOutput[] | null
+}
+export interface ProjectLinkListOutput {  
+  // 公司(推广码来源)
+  company: string
+  // 所属平台
+  orgName: string
+  // 二维码类型
+  qrcodeType: string
+  // 编号
+  num: string
+  // 短链
+  shortUrl: string
+  // 二维码链接
+  qrcodeUrl: string
+  // 推广口令
+  shareCommand: string
+  //是否使用 1使用
+  isUse: number
+  //使用时间
+  useTime: string
+  //业务员姓名
+  salesman: string	
+  //业务员手机号
+  salesmanPhone: string	
+  //业务员省
+  salesmanProvince: string	
+  //业务员市
+  salesmanCity: string	
+  //业务员备注
+  salesmanRemark: string
+  //平台Id
+  tenantId: number
 }

+ 22 - 1
src/api/admin/project.ts

@@ -18,6 +18,7 @@ import {
     ProjectAddInput,
     ProjectSetStatusInput,
     ProjectUpdateInput,
+    ResultOutputListProjectSelectOutput,
 } from './data-contracts'
 import { ContentType, HttpClient, RequestParams } from './http-client'
 
@@ -142,5 +143,25 @@ export class ProjectApi<SecurityDataType = unknown> extends HttpClient<SecurityD
             secure: true,
             type: ContentType.Json,
             ...params,
-        })    
+        }) 
+    
+    /**
+     * No description
+     *
+     * @tags project
+     * @name Get
+     * @summary 查询所有项目
+     * @request GET:/api/admin/project/get-all
+     * @secure
+     */    
+    getAll = (data: {}, params: RequestParams = {}) =>
+        this.request<ResultOutputListProjectSelectOutput, any>({
+            path: `/api/admin/project/get-all`,
+            method: 'POST',
+            body: data,
+            secure: true,
+            type: ContentType.Json,
+            format: 'json',
+            ...params,
+        })
 }

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

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

+ 114 - 0
src/views/admin/projectlink/components/link.vue

@@ -0,0 +1,114 @@
+<template>    
+    <el-dialog v-model="state.showDialog" destroy-on-close :title="title" draggable :close-on-click-modal="false"
+        :close-on-press-escape="false" width="769px">
+        <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 lable="选择项目" v-model="state.filter.projectId" value-key="id" clearable >                                         
+                                <el-option v-for="item in state.uploadProjectList" :key="item.id" :label="item.name" :value="item.id" ></el-option>
+                            </el-select> -->
+                        </el-form-item>
+                    <el-form-item label="推广码来源">
+                    <el-input v-model="state.filter.keywords" placeholder="请输入推广码来源" />
+                    </el-form-item>
+                    <el-form-item>
+                    <el-button type="primary" icon="ele-Search" @click="onQuery"> 查询 </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.projectLinkListData" row-key="id" height="'100%'" style="width: 100%; height: 100%">
+                    <el-table-column label="项目名称" prop="projectName" min-width="120" show-overflow-tooltip/>
+                    <el-table-column label="推广码来源" prop="company" min-width="120" show-overflow-tooltip/>
+                    <el-table-column label="推广码数量(已使用/总数" prop="projectName" min-width="120" show-overflow-tooltip>
+                            <template #default="{ row }">
+                            {{ row.useCount }}/{{ row.count }}
+                        </template>
+                    </el-table-column>
+                    <el-table-column label="操作" width="180" header-align="center" align="center" fixed="right">
+                    <!-- <template #default="{ row }">                
+                    <el-button size="small" text type="primary" @click="onEdit(row)">查看明细</el-button>                
+                    <el-button size="small" text type="primary" @click="onEdit(row)">补充推广码</el-button>                
+                    </template> -->
+                </el-table-column>
+                </el-table>
+            </el-card>
+        </div> 
+        <template #footer>
+            <span class="dialog-footer">
+                <el-button @click="onCancel" size="default">关 闭</el-button>                    
+            </span>
+        </template>
+    </el-dialog>
+    
+</template>
+
+<script lang="ts" setup name="admin/projectlink/link">
+import { reactive } from 'vue'
+import { PageInputProjectLinkGetPageDto, ProjectLinkListOutput } from '/@/api/admin/data-contracts'
+import { ProjectLinkApi } from '/@/api/admin/ProjectLink'
+// import eventBus from '/@/utils/mitt'
+
+
+defineProps({
+    title: {
+        type: String,
+        default: '',
+    },
+})
+
+
+const state = reactive({
+    showDialog: false,
+    loading:false,
+    projectName:"",
+    filter: {
+        projectId: 0,        
+        isUse: 0,
+        tenantId: 0,
+        keywords: ''
+    }, pageInput: {
+        currentPage: 1,
+        pageSize: 20,
+    } as PageInputProjectLinkGetPageDto,
+    total: 0,
+    projectLinkListData: [] as Array<ProjectLinkListOutput>,
+})
+//  const { from } = toRefs(state)
+
+
+// 打开对话框
+const open = async (row: any = {}) => {
+    state.showDialog = true;
+    // console.log("aaaaa");
+    state.filter.projectId = row.id;
+    state.projectName = row.projectName;
+
+    
+    onQuery();
+        
+}
+//查询
+const onQuery = async () => {
+    state.loading = true
+    
+    state.pageInput.filter = state.filter
+    const res = await new ProjectLinkApi().getPage(state.pageInput).catch(() => {
+        state.loading = false
+    })
+    state.projectLinkListData = res?.data?.list ?? []
+    state.total = res?.data?.total ?? 0
+    state.loading = false
+}
+// 取消
+const onCancel = () => {
+    state.showDialog = false
+}
+
+
+
+defineExpose({
+    open,
+})
+</script>

+ 113 - 0
src/views/admin/projectlink/components/linktest.vue

@@ -0,0 +1,113 @@
+<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="1000px">
+                <div>            
+                    <el-card class="mt8" shadow="never" :body-style="{ paddingBottom: '0' }">
+                        <el-form :inline="true" @submit.stop.prevent>                            
+                            <el-form-item label="推广码来源">
+                            <el-input v-model="state.filter.keywords" placeholder="请输入推广码来源" />
+                            </el-form-item>
+                            <el-form-item>
+                            <el-button type="primary" icon="ele-Search" @click="onQuery"> 查询 </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.projectLinkListData" row-key="id" height="'100%'" style="width: 100%; height: 100%">
+                        <el-table-column label="推广码来源" prop="company" min-width="120" show-overflow-tooltip/>
+                        <el-table-column label="所属平台" prop="orgName" min-width="120" show-overflow-tooltip/>
+                        <el-table-column label="编号" prop="num" min-width="120" show-overflow-tooltip/>
+                        <el-table-column label="二维码" prop="qrcodeUrl" min-width="120" show-overflow-tooltip/>
+                        <el-table-column label="查单码" prop="company" min-width="120" show-overflow-tooltip/>
+                        <el-table-column label="口令" prop="shareCommand" min-width="120" show-overflow-tooltip/>
+                        <el-table-column label="申请时间" min-width="120" show-overflow-tooltip>
+                            <template #default="{ row }">                                
+                                {{row.isUse===1? row.useTime:'' }}
+                            </template>
+                        </el-table-column>
+                        <el-table-column label="姓名" prop="salesman" min-width="120" show-overflow-tooltip/>
+                        <el-table-column label="手机号" prop="salesmanPhone" min-width="120" show-overflow-tooltip/>
+                        <el-table-column label="备注" prop="salesmanRemark" min-width="120" show-overflow-tooltip/>                        
+                    </el-table>
+                </el-card>
+            </div>        
+        </el-dialog>
+    </div>
+</template>
+
+<script lang="ts" setup name="admin/tenant/form">
+import { reactive, toRefs, getCurrentInstance, ref } from 'vue'
+import { PageInputProjectLinkGetPageDto, ProjectLinkListOutput } from '/@/api/admin/data-contracts'
+import { ProjectLinkApi } from '/@/api/admin/ProjectLink'
+
+import eventBus from '/@/utils/mitt'
+
+import QRCode from 'qrcodejs2-fixes'
+// 定义变量内容
+const qrcodeRef = ref()
+
+defineProps({
+    title: {
+        type: String,
+        default: '',
+    },
+})
+
+// const { proxy } = getCurrentInstance() as any
+
+// const formRef = ref()
+const state = reactive({
+    showDialog: false,
+    sureLoading: false, 
+    loading: false, 
+    filter: {
+        projectId: 0,
+        isUse: -1,
+        tenantId: 0,
+        keywords: ''
+    }, pageInput: {
+        currentPage: 1,
+        pageSize: 20,
+    } as PageInputProjectLinkGetPageDto,
+    total: 0, 
+    projectLinkListData: [] as Array<ProjectLinkListOutput>,
+})
+// const { form } = toRefs(state)
+
+
+
+// 打开对话框
+const open = async (row: any = {}) => {    
+    state.filter.projectId = row.projectId;
+    onQuery();
+    state.showDialog = true
+}
+
+//查询
+const onQuery = async () => {
+    state.loading = true
+
+    state.pageInput.filter = state.filter
+    const res = await new ProjectLinkApi().getPage(state.pageInput).catch(() => {
+        state.loading = false
+    })
+    state.projectLinkListData = res?.data?.list ?? []
+    state.total = res?.data?.total ?? 0
+    state.loading = false
+}
+// 初始化生成二维码
+const initQrcode = (text:string) => {
+    new QRCode(qrcodeRef.value, {
+        text: text,
+        width: 125,
+        height: 125,
+        colorDark: '#000000',
+        colorLight: '#ffffff',
+    })
+}
+
+defineExpose({
+    open,
+})
+</script>

+ 202 - 0
src/views/admin/projectlink/index.vue

@@ -0,0 +1,202 @@
+<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-select lable="选择项目" v-model="state.uploadFilter.projectId" value-key="id" clearable >                                         
+                        <el-option v-for="item in state.uploadProjectList" :key="item.id" :label="item.name" :value="item.id" ></el-option>                        
+                    </el-select>
+                </el-form-item>
+                <el-form-item>
+                    <el-input v-model="state.uploadFilter.Company" placeholder="请输入推广码来源" />
+                </el-form-item>
+                <el-form-item>
+                    <el-upload style="margin-right: 5px;" 
+                    :action="LinkAction"
+                    :headers="linkHeaders"
+                    :data="{ ProjectId: state.uploadFilter.projectId, Company:state.uploadFilter.Company }"
+                    :show-file-list="false"
+                    :before-upload="OnUploadLinkBefore"
+                    :on-success="onUploadLinkSuccess"
+                    :on-error="onUploadLinkError" 
+                    accept=".xlsx"                                       
+                    >
+                    <el-button type="primary" icon="ele-Upload"> 导入推广码 </el-button>
+                </el-upload>                
+                    <el-button type="primary" icon="ele-Download" @click="onDownExcel"> 导出推广码样式 </el-button>
+                </el-form-item>
+            </el-form>
+        </el-card>
+        <el-card class="mt8" shadow="never" :body-style="{ paddingBottom: '0' }">
+            <el-form :inline="true" @submit.stop.prevent>
+                <el-form-item>
+                        <el-select lable="选择项目" v-model="state.filter.projectId" value-key="id" clearable >                                         
+                            <el-option v-for="item in state.uploadProjectList" :key="item.id" :label="item.name" :value="item.id" ></el-option>
+                        </el-select>
+                    </el-form-item>
+                <el-form-item label="推广码来源">
+                <el-input v-model="state.filter.keywords" placeholder="请输入推广码来源" />
+                </el-form-item>
+                <el-form-item>
+                <el-button type="primary" icon="ele-Search" @click="onQuery"> 查询 </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.projectLinkManageListData" row-key="id" height="'100%'" style="width: 100%; height: 100%">
+                <el-table-column label="项目名称" prop="projectName" min-width="120" show-overflow-tooltip/>
+                <el-table-column label="推广码来源" prop="company" min-width="120" show-overflow-tooltip/>
+                <el-table-column label="推广码数量(已使用/总数" prop="projectName" min-width="120" show-overflow-tooltip>
+                    <template #default="{ row }">
+                    {{ row.useCount }}/{{ row.count }}
+              </template>
+                </el-table-column>
+                <el-table-column label="操作" width="180" header-align="center" align="center" fixed="right">
+              <template #default="{ row }">                
+                <el-button size="small" text type="primary" @click="onDetail(row)">查看明细</el-button>                
+                <el-button size="small" text type="primary" @click="onEdit(row)">补充推广码</el-button>                
+              </template>
+            </el-table-column>
+            </el-table>
+        </el-card>
+
+        <!-- <LinkForm ref="LinkFormRef" :title="state.linkFormTitle"></LinkForm> -->
+        <tenant-form ref="tenantFormRef" :title="state.tenantFormTitle"></tenant-form>
+   </div> 
+</template>
+<script lang="ts" setup name="admin/projectlink">
+import { ref,onMounted, computed, reactive,onBeforeMount,getCurrentInstance, defineAsyncComponent } from 'vue'
+import { pageInputProjectLinkManagePageInput, ProjectLinkManagePageOutput, ProjectSelectOutput } from '/@/api/admin/data-contracts'
+import { ProjectLinkApi } from '/@/api/admin/ProjectLink'
+import { ProjectApi } from '/@/api/admin/project'
+import pinia from '/@/stores/index'
+import { useUserInfo } from '/@/stores/userInfo'
+import eventBus from '/@/utils/mitt'
+import { AxiosResponse } from 'axios'
+
+// const LinkForm = defineAsyncComponent(() => import('./components/link.vue'))
+const TenantForm = defineAsyncComponent(() => import('./components/linktest.vue'))
+
+const { proxy } = getCurrentInstance() as any
+const storesUserInfo = useUserInfo(pinia)
+
+// const linkFormRef = ref()
+const tenantFormRef = ref()
+
+const state = reactive({
+    loading: false,
+    tenantFormTitle: '',
+    linkFormTitle: '',
+    uploadFilter: {
+        projectId: 0,
+        Company: ''
+    },
+    filter: {
+        projectId: 0,
+        keywords:''
+    },pageInput: {
+        currentPage: 1,
+        pageSize: 20,
+    } as pageInputProjectLinkManagePageInput,
+    total: 0,
+    projectLinkManageListData: [] as Array<ProjectLinkManagePageOutput>,
+    uploadProjectList: [] as Array<ProjectSelectOutput>,
+    queryProjectList: [] as Array<ProjectSelectOutput>,
+    LinkLoading: false,
+    token: storesUserInfo.getToken()
+})
+onMounted(() => {
+    onProjects();
+    onQuery()    
+    eventBus.off('refreshProjectLink')
+    eventBus.on('refreshProjectLink', async () => {
+        onQuery()
+    })
+
+})
+onBeforeMount(() => {
+    eventBus.off('refreshProjectLink')
+})
+//查询
+const onQuery=async () => {
+    state.loading = true
+    state.pageInput.filter = state.filter
+    const res = await new ProjectLinkApi().getPageManage(state.pageInput).catch(() => {
+        state.loading = false
+    })
+    state.projectLinkManageListData = res?.data?.list ?? []
+    state.total = res?.data?.total ?? 0
+    state.loading = false
+}
+//项目列表
+const onProjects = async () => {  
+    let input:any = {}  
+    const res = await new ProjectApi().getAll(input).catch(() => {
+        
+    })    
+    state.uploadProjectList = res?.data ?? []        
+    state.queryProjectList = res?.data ?? []
+}
+//导出推广码模板
+const onDownExcel =() => { 
+    // window.location.href= import.meta.env.VITE_API_URL +'/link/linkcode.xlsx'
+    let url= import.meta.env.VITE_API_URL + '/link/linkcode.xlsx'
+    window.open(url,'_self');
+}
+//导入推广码
+// 上传推广码请求url
+const LinkAction = computed(() => {
+    return import.meta.env.VITE_API_URL + '/api/admin/project-link/upload-link'
+})
+// 上传推广码请求头部
+const linkHeaders = computed(() => {
+    return { Authorization: 'Bearer ' + state.token }
+})
+// 上传推广码成功
+const onUploadLinkSuccess = (res: AxiosResponse) => {
+  state.LinkLoading = false
+    if (!res?.success) {
+        if (res.msg) {
+            proxy.$modal.msgError(res.msg)
+        }
+        return
+    } else { 
+        eventBus.off('refreshProjectLink')
+    }  
+}
+// 上传推广码失败
+const onUploadLinkError = (error: any) => {
+    state.LinkLoading = false
+    let message = ''
+    if (error.message) {
+        try {
+            message = JSON.parse(error.message)?.msg
+        } catch (err) {
+            message = error.message || ''
+        }
+    }
+    if (message) proxy.$modal.msgError(message)
+}
+//上传推广码前
+const OnUploadLinkBefore = () => {    
+    if(state.uploadFilter.projectId <= 0)
+    {
+        proxy.$modal.msgError("请选择项目");
+        return false;
+    }
+    if (state.uploadFilter.Company.length <= 0) {
+        proxy.$modal.msgError("请输入推广码来源");
+        return false;
+    }    
+    state.token = storesUserInfo.getToken()
+    state.LinkLoading = true    
+}
+const onDetail = (row: ProjectLinkManagePageOutput) => {
+    state.tenantFormTitle = '编辑租户'
+    tenantFormRef.value.open(row)
+
+    // state.linkFormTitle = '明细'
+    // linkFormRef.value.open(row)
+}
+
+</script>