Переглянути джерело

视频库优化以及好多样式优化等

pansl 1 рік тому
батько
коміт
222869ff60

+ 37 - 0
src/api/dataStatistics/rechargeStatistics/index.ts

@@ -0,0 +1,37 @@
+import http from '@/api/http';
+/**
+ * 充值统计-列表,导出
+ */
+export function statisticChargeList(params?: object) {
+  return http.get('/statistic/charge/list', params);
+}
+/**
+ * 充值统计-列表累计
+ */
+export function statisticChargeListTotalCharge(params: object) {
+  return http.get('/statistic/charge/listTotalCharge', params);
+}
+/**
+ * 充值统计-今日充值
+ */
+export function statisticChargeTodayCharge(params?: object) {
+  return http.get('/statistic/charge/todayCharge', params);
+}
+/**
+ * 充值统计-本月充值
+ */
+export function statisticChargeCurrentMonthCharge(params?: object) {
+  return http.get('/statistic/charge/currentMonthCharge', params);
+}
+/**
+ * 充值统计-上月充值
+ */
+export function statisticChargeLastMonthCharge(params?: object) {
+  return http.get('/statistic/charge/lastMonthCharge', params);
+}
+/**
+ * 充值统计-累计充值
+ */
+export function statisticChargeTotalCharge(params?: object) {
+  return http.get('/statistic/charge/totalCharge', params);
+}

+ 13 - 0
src/api/dataStatistics/roiStatistical/index.ts

@@ -0,0 +1,13 @@
+import http from '@/api/http';
+/**
+ * 投入产出-列表
+ */
+export function statisticRoiList(params?: object) {
+  return http.get('/statistic/roi/list', params);
+}
+/**
+ * 投入产出-总计
+ */
+export function statisticRoiListTotal(params: object) {
+  return http.get('/statistic/roi/listTotal', params);
+}

+ 13 - 0
src/api/dataStatistics/shortStatistical/index.ts

@@ -0,0 +1,13 @@
+import http from '@/api/http';
+/**
+ * 短剧统计列表
+ */
+export function statisticVideoList(params?: object) {
+  return http.get('/statistic/video/list', params);
+}
+/**
+ * 短剧统计-汇总
+ */
+export function statisticVideoStats(params: object) {
+  return http.get('/statistic/video/stats', params);
+}

+ 49 - 12
src/components/admin/icons/index.vue

@@ -1,20 +1,33 @@
 <template>
-  <div :class="`grid ${grid} gap-y-6`">
-    <div v-for="icon in icons" :key="icon" class="flex justify-center hover:cursor-pointer" @click="selectIcon(icon)">
-      <div v-if="modelValue === icon">
-        <div class="flex justify-center w-full text-violet-700"><Icon :name="icon" /></div>
-        <div class="text-sm text-violet-700">{{ icon }}</div>
-      </div>
+  <div class="pl-2 pr-2 h-84">
+    <div :class="`grid ${grid} gap-y-4 gap-x-4` + ' mt-3 h-72'">
+      <div v-for="icon in icons" :key="icon" class="flex justify-center hover:cursor-pointer" @click="selectIcon(icon)">
+        <div v-if="modelValue === icon">
+          <div class="flex justify-center w-full text-red-700">
+            <Icon :name="icon" className="w-5 h-5" />
+          </div>
+          <div class="text-[1px] text-red-700 name">{{ icon }}</div>
+        </div>
 
-      <div v-else>
-        <div class="flex justify-center w-full"><Icon :name="icon" /></div>
-        <div class="text-sm">{{ icon }}</div>
+        <div v-else>
+          <div class="flex justify-center w-full">
+            <Icon :name="icon" className="w-5 h-5" />
+          </div>
+          <div class="text-[1px] name">{{ icon }}</div>
+        </div>
       </div>
     </div>
+
+    <div class="flex justify-center mt-6">
+      <el-pagination layout="prev,next" :page-size="limit" :total="total" prev-text="上一页" next-text="下一页"
+        @next-click="handleNext" @prev-click="handlePrev" />
+    </div>
   </div>
 </template>
 
 <script lang="ts" setup>
+import { onMounted, ref } from 'vue'
+
 const props = defineProps({
   modelValue: {
     type: String,
@@ -22,18 +35,38 @@ const props = defineProps({
   },
   grid: {
     type: String,
-    default: 'grid-cols-5',
+    default: 'grid-cols-4',
   },
 })
 
 const emits = defineEmits(['update:modelValue', 'close'])
 
+const limit = ref(16)
+const icons = ref([])
+const total = ref(0)
+function getIcons(page = 1) {
+  const start = (page - 1) * limit.value
+  const end = start + limit.value
+  icons.value = constIcons.slice(start, end)
+}
+
+onMounted(() => {
+  getIcons()
+  total.value = constIcons.length
+})
+const handleNext = value => {
+  getIcons(value)
+}
+
+const handlePrev = value => {
+  getIcons(value)
+}
 const selectIcon = (icon: string) => {
   emits('update:modelValue', icon)
   emits('close')
 }
 // icons
-const icons = [
+const constIcons = [
   'academic-cap',
   'adjustments-horizontal',
   'adjustments-vertical',
@@ -329,4 +362,8 @@ const icons = [
 ]
 </script>
 
-<style scoped></style>
+<style scoped lang="scss">
+.name {
+  @include text-ellipsis(1);
+}
+</style>

+ 43 - 40
src/hook/curd/useGetList.ts

@@ -1,100 +1,103 @@
-import http from '@/support/http'
-import { provide, ref, unref } from 'vue'
-import { Code } from '@/enum/app'
-import Message from '@/support/message'
+import http from '@/support/http';
+import { provide, ref, unref } from 'vue';
+import { Code } from '@/enum/app';
+import Message from '@/support/message';
 
-const initLimit = 10
-const initPage = 1
-const initTotal = 10
+const initLimit = 10;
+const initPage = 1;
+const initTotal = 10;
 
 // get table list
 export function useGetList(path: string, isPaginate: boolean = true) {
-  const data = ref<object>()
-  const page = ref<number>(initPage)
-  const limit = ref<number>(initLimit)
-  const total = ref<number>(initTotal)
-  const query = ref<object>({})
+  const data = ref<object>();
+  const page = ref<number>(initPage);
+  const limit = ref<number>(initLimit);
+  const total = ref<number>(initTotal);
+  const query = ref<object>({});
   if (isPaginate) {
     query.value = Object.assign({
       page: page.value,
-      limit: limit.value,
-    })
+      limit: limit.value
+    });
   }
 
-  const loading = ref(true)
+  const loading = ref(true);
   // fetch list
   function getList() {
     // when table's data page >= 100, it will loading
     if (page.value >= 100) {
-      loading.value = true
+      loading.value = true;
     }
     http
       .get(path, unref(query))
       .then(r => {
-        closeLoading()
+        closeLoading();
         if (r.data.code === Code.SUCCESS) {
-          data.value = r.data
+          data.value = r.data;
           // eslint-disable-next-line @typescript-eslint/ban-ts-comment
           // @ts-ignore
-          total.value = data.value?.total
+          total.value = data.value?.total;
         } else {
-          Message.error(r.data.message)
+          Message.error(r.data.message);
         }
       })
       .finally(() => {
-        closeLoading()
-      })
+        closeLoading();
+      });
   }
 
   // close loading
   function closeLoading() {
-    loading.value = false
+    loading.value = false;
   }
   // search
   function search() {
-    getList()
+    getList();
   }
 
   // reset
   function reset() {
-    resetPage()
+    resetPage();
 
-    if (isPaginate) {
-      query.value = Object.assign({ page: page.value, limit: limit.value })
-    }
+    // if (isPaginate) {
+    //   query.value = Object.assign({ page: page.value, limit: limit.value })
+    // }
+    query.value = Object.assign(
+      isPaginate ? { page: page.value, limit: limit.value } : {}
+    );
 
-    getList()
+    getList();
   }
 
   // change page
   function changePage(p: number) {
-    page.value = p
+    page.value = p;
     // eslint-disable-next-line @typescript-eslint/ban-ts-comment
     // @ts-ignore
-    query.value.page = p
-    search()
+    query.value.page = p;
+    search();
   }
 
   function resetPage() {
-    page.value = 1
+    page.value = 1;
   }
 
   // change limit
   function changeLimit(l: number) {
-    limit.value = l
-    resetPage()
+    limit.value = l;
+    resetPage();
     // eslint-disable-next-line @typescript-eslint/ban-ts-comment
     // @ts-ignore
-    query.value.page = 1
+    query.value.page = 1;
     // eslint-disable-next-line @typescript-eslint/ban-ts-comment
     // @ts-ignore
-    query.value.limit = l
+    query.value.limit = l;
 
-    search()
+    search();
   }
 
   // provider for paginate component
-  provide('paginate', { page, limit, total, changePage, changeLimit })
+  provide('paginate', { page, limit, total, changePage, changeLimit });
 
-  return { data, query, search, reset, loading }
+  return { data, query, search, reset, loading };
 }

+ 2 - 3
src/layout/components/Menu/index.vue

@@ -109,9 +109,8 @@ export default defineComponent({
     // const permissions = ref()
     const vnodes = ref()
     watch(() => userStore.getPermissions, (newVal, oldVal) => {
-      console.log(newVal, oldVal, 'newVal,oldValnewVal,oldValnewVal,oldValuserStore.getPermissions');
-      // permissions.value == userStore.getPermissions === undefined ? [] : newVal
-      vnodes.value = getVNodes(filterMenus(permissionsStore.getMenusFrom(newVal, true)), props.subMenuClass)
+      const permissions = newVal === undefined ? [] : newVal
+      vnodes.value = getVNodes(filterMenus(permissionsStore.getMenusFrom(permissions, true)), props.subMenuClass)
     }, {
       immediate: true,
       deep: true

+ 12 - 3
src/layout/components/Menu/item.vue

@@ -13,13 +13,16 @@
     <el-icon>
       <Icon :name="menu?.meta?.icon" v-if="menu?.meta?.icon" class="text-sm" />
     </el-icon>
-    <span>{{ menu?.meta?.title }}</span>
+    <span v-if="menu?.path.indexOf('https://') !== -1 || menu?.path.indexOf('http://') !== -1">
+      <span @click="openUrl(menu?.path as string)">{{ menu?.meta?.title }}</span>
+    </span>
+    <span v-else>{{ menu?.meta?.title }}</span>
   </el-menu-item>
 </template>
 
-<script lang="ts" name="MenuItem" setup>
+<script lang="ts" setup>
 import { Menu } from '@/types/Menu'
-import { onMounted, PropType, ref } from 'vue'
+import { PropType } from 'vue'
 import { useAppStore } from '@/stores/modules/app'
 import { isMiniScreen } from '@/support/helper'
 
@@ -37,6 +40,12 @@ defineProps({
     require: true,
   },
 })
+
+const openUrl = (path: string) => {
+  const start = path.indexOf('https://') || path.indexOf('http://')
+  window.open(path.substring(start))
+  return false
+}
 </script>
 
 <style scoped lang="scss">

+ 1 - 1
src/layout/components/header/index.vue

@@ -1,7 +1,7 @@
 <template>
   <div class="flex flex-row w-full h-16 border-l border-gray-200 drop-shadow dark:border-l-0"
     style="background-color: var(--header-bg-color)">
-    <div class="flex flex-row justify-between w-full">
+    <div class="flex flex-row justify-between w-full h-16">
       <div class="flex flex-row min-w-[17rem]">
         <div class="flex items-center w-8 h-full ml-2 hover:cursor-pointer" @click="store.changeExpaned">
           <Icon name="list-bullet" class="w-6 h-8" />

+ 27 - 27
src/router/modules/charge.ts

@@ -1,28 +1,28 @@
-import { RouteRecordRaw } from 'vue-router';
-// eslint-disable-next-line @typescript-eslint/ban-ts-comment
-// @ts-ignore
-const router: RouteRecordRaw[] = [
-  {
-    path: '/charge',
-    component: () => import('@/layout/index.vue'),
-    meta: { title: '数据统计', icon: 'user' },
-    children: [
-      {
-        path: 'index',
-        name: 'user-account11',
-        meta: { title: '短剧统计', icon: 'home' },
-        component: () =>
-          import('@/views/dataStatistics/shortStatistical/index.vue')
-      },
-      {
-        path: 'index1',
-        name: 'user-account',
-        meta: { title: '充值统计', icon: 'home' },
-        component: () =>
-          import('@/views/dataStatistics/rechargeStatistics/index.vue')
-      }
-    ]
-  }
-];
+// import { RouteRecordRaw } from 'vue-router';
+// // eslint-disable-next-line @typescript-eslint/ban-ts-comment
+// // @ts-ignore
+// const router: RouteRecordRaw[] = [
+//   {
+//     path: '/charge',
+//     component: () => import('@/layout/index.vue'),
+//     meta: { title: '数据统计', icon: 'user' },
+//     children: [
+//       {
+//         path: 'index',
+//         name: 'user-account11',
+//         meta: { title: '短剧统计', icon: 'home' },
+//         component: () =>
+//           import('@/views/dataStatistics/shortStatistical/index.vue')
+//       },
+//       {
+//         path: 'index1',
+//         name: 'user-account',
+//         meta: { title: '充值统计', icon: 'home' },
+//         component: () =>
+//           import('@/views/dataStatistics/rechargeStatistics/index.vue')
+//       }
+//     ]
+//   }
+// ];
 
-export default router;
+// export default router;

+ 7 - 2
src/stores/modules/user/permissions.ts

@@ -145,7 +145,12 @@ export const usePermissionsStore = defineStore('PermissionsStore', {
           }
           const menu: Menu = Object.assign({
             path: this.resolveRoutePathRoutePath(permission.route, path),
-            name: permission.module + '_' + permission.permission_mark + "_" + permission.id,
+            name:
+              permission.module +
+              '_' +
+              permission.permission_mark +
+              '_' +
+              permission.id,
             component: importComponent,
             redirect: permission.redirect,
             meta: Object.assign({
@@ -217,7 +222,7 @@ export const usePermissionsStore = defineStore('PermissionsStore', {
      */
     resolveRoutePathRoutePath(route: string, path: string): string {
       if (path.length) {
-        return (path + (route.indexOf('/') === -1 ? '/' : '') + route).replace(
+        return (path + (!route.startsWith('/') ? '/' : '') + route).replace(
           /\/$/g,
           ''
         );

+ 11 - 3
src/views/Permissions/permissions/form/create.vue

@@ -42,7 +42,15 @@
           <el-input v-model="action" disabled clearable v-if="isAction"></el-input>
         </el-form-item>
         <el-form-item label="菜单Icon" prop="icon" v-if="!isAction">
-          <el-input v-model="formData.icon" name="icon" clearable @click="open" />
+          <!-- <el-input v-model="formData.icon" name="icon" clearable @click="open" /> -->
+          <el-popover placement="right" :width="500" trigger="click">
+            <template #reference>
+              <el-input v-model="formData.icon" name="icon" clearable />
+            </template>
+            <div>
+              <Icons v-model="formData.icon" @close="closeSelectIcon" />
+            </div>
+          </el-popover>
         </el-form-item>
         <el-form-item label="所属组件" prop="component" :rules="[{ required: true, message: '所属组件必须填写' }]" v-if="!isAction">
           <!-- <Select v-model="formData.component" placeholder="请选择" allow-create api="components" :query="{ module: formData.module }" /> -->
@@ -83,9 +91,9 @@
     </div>
   </el-form>
 
-  <Dialog v-model="visible" title="选择 Icon" width="1000px" destroy-on-close>
+  <!-- <Dialog v-model="visible" title="选择 Icon" width="1000px" destroy-on-close>
     <Icons v-model="formData.icon" @close="closeSelectIcon" />
-  </Dialog>
+  </Dialog> -->
 </template>
 
 <script lang="ts" setup>

+ 10 - 7
src/views/Permissions/permissions/index.vue

@@ -9,24 +9,27 @@
     </Search>
     <div class="table-default">
       <Operate :show="open" />
-      <el-table :data="tableData" class="mt-3" v-loading="loading" row-key="id" default-expand-all
+      <el-table :data="tableData" class="mt-3" v-loading="loading" row-key="id" :default-expand-all="false"
         :tree-props="{ children: 'children' }">
         <el-table-column prop="permission_name" label="菜单名称" />
         <el-table-column prop="route" label="菜单路由" />
         <el-table-column prop="permission_mark" label="权限标识" width="360">
           <template #default="scope">
             <div v-if="scope.row.actions.length">
-              <el-tag v-for="action in scope.row.actions" class="mb-3 mr-3 cursor-pointer w-fit min-w-fit"
-                @click="open(action.id)" closable @close="destroy(api, action.id)">{{ action.permission_name }}</el-tag>
+              <el-tag v-for="action in scope.row.actions" :key="action.id"
+                class="mb-3 mr-3 cursor-pointer w-fit min-w-fit" @click="open(action.id)" closable
+                @close="destroy(api, action.id)">{{ action.permission_name }}</el-tag>
             </div>
             <div v-else>
               <el-popconfirm confirm-button-text="确认" title="添加基础actions" @confirm="actionGenerate(scope.row.id)"
                 placement="top">
                 <template #reference>
-                  <el-tag class="w-8 cursor-pointer" v-if="scope.row.type === MenuType.PAGE_TYPE">
-                    <Icon name="cog-6-tooth" class="w-5 h-5 animate-spin" v-if="actionLoading" />
-                    <Icon name="plus" className="w-4 h-4" v-else />
-                  </el-tag>
+                  <span>
+                    <el-tag class="w-8 cursor-pointer" v-if="scope.row.type === MenuType.PAGE_TYPE">
+                      <Icon name="cog-6-tooth" class="w-5 h-5 animate-spin" v-if="actionLoading" />
+                      <Icon name="plus" className="w-4 h-4" v-else />
+                    </el-tag>
+                  </span>
                 </template>
               </el-popconfirm>
             </div>

+ 11 - 2
src/views/Permissions/roles/form/create.vue

@@ -173,7 +173,16 @@ const getParent = (parentId: any) => {
   return typeof parentId === 'undefined' ? 0 : parentId[parentId.length - 1];
 };
 </script>
-<style scoped>
+<style scoped lang="scss">
 :deep(.el-tree .el-tree__empty-block .el-tree__empty-text) {
   @apply left-10 top-4;
-}</style>
+}
+
+:deep(.el-tree-node .is-expanded .el-tree-node__children) {
+  @apply flex flex-wrap pl-9;
+}
+
+:deep(.el-tree-node .is-expanded .el-tree-node__children .el-tree-node__content) {
+  padding-left: 0 !important;
+}
+</style>

+ 53 - 65
src/views/dataStatistics/rechargeStatistics/index.vue

@@ -1,39 +1,5 @@
 <template>
   <div>
-    <div class="flex">
-      <el-card class="box-card">
-        <template #header>
-          <div class="flex items-center card-header">
-            <span>今日充值</span>
-            <el-tooltip placement="top">
-              <template #content>
-                当前推广链接的状态<br />
-                启用:当前推广ID已绑定回传配置<br />
-                禁用:当前推广ID未绑定回传配置
-              </template>
-              <el-icon>
-                <InfoFilled />
-              </el-icon>
-            </el-tooltip>
-          </div>
-        </template>
-        <div class="money-wrapper">¥890</div>
-        <div class="flex items-center justify-around">
-          <div>
-            <p class="text-lg font-bold">普通充值</p>
-            <div><span class="text-sm">已支付:</span><span class="text-base">25单</span></div>
-            <div><span class="text-sm">未支付:</span><span class="text-base">4单</span></div>
-            <div><span class="text-sm">支付率:</span><span class="text-base">83.33%</span></div>
-          </div>
-          <div>
-            <p class="text-lg font-bold">会员充值</p>
-            <div><span class="text-sm">已支付:</span><span class="text-base">25单</span></div>
-            <div><span class="text-sm">未支付:</span><span class="text-base">4单</span></div>
-            <div><span class="text-sm">支付率:</span><span class="text-base">83.33%</span></div>
-          </div>
-        </div>
-      </el-card>
-    </div>
     <Search :search="search" :reset="resetQuery">
       <template v-slot:body>
         <el-form-item label="短剧名称" prop="trade_no">
@@ -65,18 +31,16 @@
     </div>
     <div class="table-default">
       <el-table :data="tableData" class="mt-3" v-loading="loading">
-        <el-table-column prop="id" label="时间" />
-        <el-table-column prop="miniprogram_name" label="优化师" min-width="200px" />
-        <el-table-column prop="miniprogram_name" label="小程序名称" min-width="200px" />
-        <el-table-column label="充值金额">
+        <el-table-column prop="day_at" label="时间" />
+        <el-table-column prop="username" label="优化师" min-width="160px" />
+        <el-table-column prop="miniprogram_name" label="小程序名称" min-width="160px" />
+        <el-table-column label="充值金额" prop="pay_money">
           <template #header>
             <div class="flex items-center">
               <span>充值金额</span>
               <el-tooltip placement="top">
                 <template #content>
-                  当前推广链接的状态<br />
-                  启用:当前推广ID已绑定回传配置<br />
-                  禁用:当前推广ID未绑定回传配置
+                  当日累计充值金额<br />
                 </template>
                 <el-icon>
                   <InfoFilled />
@@ -86,19 +50,17 @@
           </template>
           <template #default="scope">
             <div class="wrapper">
-              <div>充值金额</div>
+              <div>{{ scope.row.pay_money }}</div>
             </div>
           </template>
         </el-table-column>
-        <el-table-column label="充值笔数">
+        <el-table-column label="充值笔数" prop="pay_count">
           <template #header>
             <div class="flex items-center">
               <span>充值笔数</span>
               <el-tooltip placement="top">
                 <template #content>
-                  当前推广链接的状态<br />
-                  启用:当前推广ID已绑定回传配置<br />
-                  禁用:当前推广ID未绑定回传配置
+                  当日累计充值笔数<br />
                 </template>
                 <el-icon>
                   <InfoFilled />
@@ -108,19 +70,17 @@
           </template>
           <template #default="scope">
             <div class="wrapper">
-              <div>充值笔数</div>
+              <div>{{ scope.row.pay_count }}</div>
             </div>
           </template>
         </el-table-column>
-        <el-table-column label="新增用户充值总额">
+        <el-table-column label="新增用户充值总额" prop="new_user_pay_money">
           <template #header>
             <div class="flex items-center">
               <span>新增用户充值总额</span>
               <el-tooltip placement="top">
                 <template #content>
-                  当前推广链接的状态<br />
-                  启用:当前推广ID已绑定回传配置<br />
-                  禁用:当前推广ID未绑定回传配置
+                  当日新用户充值总额<br />
                 </template>
                 <el-icon>
                   <InfoFilled />
@@ -130,24 +90,52 @@
           </template>
           <template #default="scope">
             <div class="wrapper">
-              <div>新增用户充值总额</div>
+              <div>{{ scope.row.new_user_pay_money }}</div>
+              <div>普通:{{ scope.row.new_user_common_pay_money }}</div>
+              <div>会员:{{ scope.row.new_user_vip_pay_money }}</div>
             </div>
           </template>
         </el-table-column>
-        <el-table-column label="普通充值">
-          <el-table-column prop="name" label="金额" width="120">
-
+        <el-table-column label="普通充值" min-width="250">
+          <el-table-column prop="common_pay_money" label="金额">
+            <template #default="scope">
+              <div class="wrapper">
+                <div>总额:{{ scope.row.common_pay_money }}</div>
+                <div>人均:{{ scope.row.common_pay_money }}</div>
+              </div>
+            </template>
           </el-table-column>
-          <el-table-column label="支付订单数">
-
+          <el-table-column label="支付订单数" prop="common_pay_count">
+            <template #default="scope">
+              <div class="wrapper">
+                <div class="mb-2">
+                  <span class="mr-2">已:{{ scope.row.common_pay_count }}</span>
+                  <span>未:{{ scope.row.common_unpay_count }}</span>
+                </div>
+                <div>支付率:{{ scope.row.common_pay_rate }}</div>
+              </div>
+            </template>
           </el-table-column>
         </el-table-column>
-        <el-table-column label="会员充值">
-          <el-table-column prop="name" label="金额" width="120">
-
+        <el-table-column label="会员充值" min-width="250">
+          <el-table-column prop="vip_pay_money" label="金额">
+            <template #default="scope">
+              <div class="wrapper">
+                <div>总额:{{ scope.row.vip_pay_money }}</div>
+                <div>人均:{{ scope.row.vip_pay_money_per }}</div>
+              </div>
+            </template>
           </el-table-column>
-          <el-table-column label="支付订单数">
-
+          <el-table-column label="支付订单数" prop="vip_pay_count">
+            <template #default="scope">
+              <div class="wrapper">
+                <div class="mb-2">
+                  <span class="mr-2">已:{{ scope.row.vip_pay_count }}</span>
+                  <span>未:{{ scope.row.vip_unpay_count }}</span>
+                </div>
+                <div>支付率:{{ scope.row.vip_pay_rate }}</div>
+              </div>
+            </template>
           </el-table-column>
         </el-table-column>
       </el-table>
@@ -161,12 +149,12 @@ import { shortcuts } from '@/utils/shortcuts'
 import { useRouter, useRoute } from 'vue-router'
 import { InfoFilled } from '@element-plus/icons-vue';
 import { useGetList } from '@/hook/curd/useGetList';
-import { titleObj } from "./excelTitle"
+import { titleObj } from "./excelTitle";
 import moment from 'moment';
 const start_date = moment().startOf('month').format('YYYY-MM-DD')
 const end_date = moment().endOf('month').format('YYYY-MM-DD')
 const statisticalData = ref({})
-const api = 'channel/order_list';
+const api = 'statistic/charge/list';
 const router = useRouter()
 const route = useRoute()
 const { data, query, search, reset, loading } = useGetList(api);
@@ -221,7 +209,7 @@ onMounted(() => {
 }
 
 .table-default {
-  padding: 0;
+  padding: 2px 4px 8px 4px;
 
   .set-warpper {
     height: 60px;

+ 66 - 0
src/views/dataStatistics/rechargeStatistics/summary.vue

@@ -0,0 +1,66 @@
+<template>
+  <div>
+    <div class="flex">
+      <el-card class="box-card">
+        <template #header>
+          <div class="flex items-center card-header">
+            <span>今日充值</span>
+            <el-tooltip placement="top">
+              <template #content>
+                当前推广链接的状态<br />
+                启用:当前推广ID已绑定回传配置<br />
+                禁用:当前推广ID未绑定回传配置
+              </template>
+              <el-icon>
+                <InfoFilled />
+              </el-icon>
+            </el-tooltip>
+          </div>
+        </template>
+        <div class="money-wrapper">¥890</div>
+        <div class="flex items-center justify-around">
+          <div>
+            <p class="text-lg font-bold">普通充值</p>
+            <div><span class="text-sm">已支付:</span><span class="text-base">25单</span></div>
+            <div><span class="text-sm">未支付:</span><span class="text-base">4单</span></div>
+            <div><span class="text-sm">支付率:</span><span class="text-base">83.33%</span></div>
+          </div>
+          <div>
+            <p class="text-lg font-bold">会员充值</p>
+            <div><span class="text-sm">已支付:</span><span class="text-base">25单</span></div>
+            <div><span class="text-sm">未支付:</span><span class="text-base">4单</span></div>
+            <div><span class="text-sm">支付率:</span><span class="text-base">83.33%</span></div>
+          </div>
+        </div>
+      </el-card>
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { useRouter, useRoute } from 'vue-router'
+import { InfoFilled } from '@element-plus/icons-vue';
+import { useGetList } from '@/hook/curd/useGetList';
+const statisticalData = ref({})
+const router = useRouter()
+const route = useRoute()
+const rolesIdentify = inject('rolesIdentify')
+
+onMounted(() => {
+  
+});
+</script>
+
+<style scoped lang="scss">
+.box-card {
+  width: 300px;
+  margin: 8px;
+
+  .money-wrapper {
+    height: 50px;
+    width: 100%;
+    color: #ed892c;
+    font-size: 26px;
+  }
+}
+</style>

+ 10 - 0
src/views/dataStatistics/roiStatistical/excelTitle.ts

@@ -0,0 +1,10 @@
+// 导出中文/字段
+export const titleObj = {
+  时间: 'day',
+  短剧名称: 'video_name',
+  短剧ID: 'video_id',
+  充值金额: 'amount',
+  充值次数: 'charge_count',
+  充值人数: 'charge_user_num',
+  播放次数: 'play_count'
+};

+ 199 - 0
src/views/dataStatistics/roiStatistical/index.vue

@@ -0,0 +1,199 @@
+<template>
+  <div>
+    <Search :search="moreSearch" :reset="moreReset">
+      <template v-slot:body>
+        <el-form-item label="短剧名称" prop="video_name">
+          <el-input v-model="query.video_name" placeholder="请输入短剧名称" clearable />
+        </el-form-item>
+        <el-form-item label="时间">
+          <el-date-picker unlink-panels clearable @change="timeChange" format="YYYY/MM/DD" value-format="YYYY-MM-DD"
+            v-model="query.time" type="daterange" :shortcuts="shortcuts" range-separator="To" start-placeholder="开始时间"
+            end-placeholder="结束时间" />
+        </el-form-item>
+      </template>
+      <template v-slot:extra_button>
+        <exportExcel api="statistic/video/list" sheet_name="短剧统计" :title_obj="titleObj"
+          :extro_params="{ is_export: true, ...query }">
+        </exportExcel>
+      </template>
+    </Search>
+    <div style="margin:8px 0;" v-action="'statistic.VideoStat.stats'">
+      <el-card shadow="hover" :body-style="{ padding: '20px' }">
+        <div class="stat-wrapper">
+          <div>所选时间段内累计充值金额: <span class="ml-2 mr-4 stat">{{ statisticalData.amount || '暂无数据' }}</span>
+          </div>
+          <div>累计充值次数: <span class="ml-2 mr-4 stat">{{ statisticalData.charge_count || '暂无数据' }}</span>
+          </div>
+          <div>累计充值人数: <span class="ml-2 mr-4 stat">{{ statisticalData.charge_user_num || '暂无数据' }}</span></div>
+        </div>
+      </el-card>
+    </div>
+    <div class="table-default" v-action="'statistic.VideoStat.index'">
+      <el-table :data="tableData" class="mt-3" v-loading="loading">
+        <el-table-column prop="day" label="时间" />
+        <el-table-column prop="video_name" label="短剧名称" min-width="160px" />
+        <el-table-column prop="video_id" label="短剧ID" />
+        <el-table-column label="充值金额" sortable prop="amount">
+          <template #header>
+            <span>充值金额</span>
+            <el-tooltip placement="top">
+              <template #content>
+                当日短剧充值总额;基于推广公司的小程序统计;<br />
+              </template>
+              <el-icon>
+                <InfoFilled />
+              </el-icon>
+            </el-tooltip>
+          </template>
+          <template #default="scope">
+            <div class="wrapper">
+              <div>{{ scope.row.amount }}</div>
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column label="充值次数" sortable prop="charge_count">
+          <template #header>
+            <span>充值次数</span>
+            <el-tooltip placement="top">
+              <template #content>
+                当日短剧充值总次数;基于推广公司的小程序统计;<br />
+              </template>
+              <el-icon>
+                <InfoFilled />
+              </el-icon>
+            </el-tooltip>
+          </template>
+          <template #default="scope">
+            <div class="wrapper">
+              <div>{{ scope.row.charge_count }}</div>
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column label="充值人数" sortable prop="charge_user_num">
+          <template #header>
+            <span>充值人数</span>
+            <el-tooltip placement="top">
+              <template #content>
+                当日累计充值人数;基于推广公司的小程序统计;<br />
+              </template>
+              <el-icon>
+                <InfoFilled />
+              </el-icon>
+            </el-tooltip>
+          </template>
+          <template #default="scope">
+            <div class="wrapper">
+              <div>{{ scope.row.charge_user_num }}</div>
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column label="播放次数" sortable prop="play_count">
+          <template #header>
+            <span>播放次数</span>
+            <el-tooltip placement="top">
+              <template #content>
+                当日短剧累计播放次数:指当日绑定此短剧的所有推广链接,累计被点击次数<br />
+              </template>
+              <el-icon>
+                <InfoFilled />
+              </el-icon>
+            </el-tooltip>
+          </template>
+          <template #default="scope">
+            <div class="wrapper">
+              <div>{{ scope.row.play_count }}</div>
+            </div>
+          </template>
+        </el-table-column>
+      </el-table>
+      <Paginate />
+    </div>
+  </div>
+</template>
+<script lang="ts" setup>
+import { shortcuts } from '@/utils/shortcuts';
+import { useRouter, useRoute } from 'vue-router';
+import { InfoFilled } from '@element-plus/icons-vue';
+import { useGetList } from '@/hook/curd/useGetList';
+import { statisticVideoStats } from '@/api/dataStatistics/shortStatistical/index';
+import { titleObj } from "./excelTitle";
+import moment from 'moment';
+const start_date = moment().subtract(7, 'days').format('YYYY-MM-DD');
+const end_date = moment().format('YYYY-MM-DD');
+const statisticalData = ref({});
+const api = 'statistic/video/list';
+const router = useRouter()
+const route = useRoute()
+const { data, query, search, reset, loading } = useGetList(api);
+const rolesIdentify = inject('rolesIdentify')
+
+const timeChange = (e: object) => {
+  console.log(e, 'timeChangetimeChangetimeChange');
+  if (query.value.time) {
+    const timeArr = toRaw(e);
+    query.value.start_date = timeArr[0]
+    query.value.end_date = timeArr[1]
+  } else {
+    delete query.value.start_date
+    delete query.value.end_date
+  }
+}
+
+const moreSearch = () => {
+  search();
+  statisticVideoStats({ ...query.value }).then(res => {
+    statisticalData.value = res.data
+  })
+}
+
+const moreReset = () => {
+  reset()
+  statisticVideoStats({ ...query.value }).then(res => {
+    statisticalData.value = res.data
+  })
+}
+
+const tableData = computed(() => data.value?.data);
+
+onMounted(() => {
+  query.value.time = [start_date, end_date];
+  query.value.start_date = start_date;
+  query.value.end_date = end_date;
+  moreSearch();
+});
+</script>
+
+<style scoped lang="scss">
+.stat-wrapper {
+  display: flex;
+  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
+
+  .stat {
+    box-sizing: border-box;
+    font-size: 18px;
+    font-weight: 550;
+    padding: 0 12px;
+  }
+}
+
+.table-default {
+  .set-warpper {
+    height: 60px;
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+  }
+
+  .wrapper {
+    margin: 8px;
+
+    .label {
+      margin-right: 6px;
+    }
+
+    .content {
+      font-size: 15px;
+    }
+  }
+}
+</style>

+ 8 - 15
src/views/dataStatistics/shortStatistical/excelTitle.ts

@@ -1,17 +1,10 @@
 // 导出中文/字段
 export const titleObj = {
-  商户名称: 'company_name',
-  商户ID: 'puser_id',
-  优化师: 'username',
-  小程序: 'play_name',
-  用户ID: 'uid',
-  订单号: 'trade_no',
-  订单时间: 'created_at',
-  染色注册时间: 'ranse_created_at',
-  累计充值成功次数: 'total_count',
-  充值金额: 'price',
-  推广名称: 'promotion_title',
-  充值类型: 'tip_text',
-  支付方式: 'pay_name',
-  订单状态: 'status_txt'
-};
+  时间: 'day',
+  短剧名称: 'video_name',
+  短剧ID: 'video_id',
+  充值金额: 'amount',
+  充值次数: 'charge_count',
+  充值人数: 'charge_user_num',
+  播放次数: 'play_count'
+};

+ 83 - 86
src/views/dataStatistics/shortStatistical/index.vue

@@ -1,9 +1,9 @@
 <template>
   <div>
-    <Search :search="search" :reset="resetQuery">
+    <Search :search="moreSearch" :reset="moreReset">
       <template v-slot:body>
-        <el-form-item label="短剧名称" prop="trade_no">
-          <el-input v-model="query.trade_no" placeholder="请输入短剧名称" clearable />
+        <el-form-item label="短剧名称" prop="video_name">
+          <el-input v-model="query.video_name" placeholder="请输入短剧名称" clearable />
         </el-form-item>
         <el-form-item label="时间">
           <el-date-picker unlink-panels clearable @change="timeChange" format="YYYY/MM/DD" value-format="YYYY-MM-DD"
@@ -12,112 +12,96 @@
         </el-form-item>
       </template>
       <template v-slot:extra_button>
-        <exportExcel api="channel/order_list" sheet_name="订单列表" :title_obj="titleObj"
+        <exportExcel api="statistic/video/list" sheet_name="短剧统计" :title_obj="titleObj"
           :extro_params="{ is_export: true, ...query }">
         </exportExcel>
       </template>
     </Search>
-    <div style="margin:8px 0;">
+    <div style="margin:8px 0;" v-action="'statistic.VideoStat.stats'">
       <el-card shadow="hover" :body-style="{ padding: '20px' }">
         <div class="stat-wrapper">
-          <div>所选时间段内累计充值金额: <span class="ml-2 mr-4 stat">{{ statisticalData.yesterday_total_coins || '暂无数据' }}</span>
+          <div>所选时间段内累计充值金额: <span class="ml-2 mr-4 stat">{{ statisticalData.amount || '暂无数据' }}</span>
           </div>
-          <div>累计充值次数: <span class="ml-2 mr-4 stat">{{ statisticalData.yesterday_available_amount || '暂无数据' }}</span>
+          <div>累计充值次数: <span class="ml-2 mr-4 stat">{{ statisticalData.charge_count || '暂无数据' }}</span>
           </div>
-          <div>累计充值人数: <span class="ml-2 mr-4 stat">{{ statisticalData.yesterday_final_amount || '暂无数据' }}</span></div>
+          <div>累计充值人数: <span class="ml-2 mr-4 stat">{{ statisticalData.charge_user_num || '暂无数据' }}</span></div>
         </div>
       </el-card>
     </div>
-    <div class="table-default">
+    <div class="table-default" v-action="'statistic.VideoStat.index'">
       <el-table :data="tableData" class="mt-3" v-loading="loading">
-        <el-table-column prop="id" label="时间" />
-        <el-table-column prop="miniprogram_name" label="短剧名称" min-width="200px" />
-        <el-table-column prop="callback_type_str" label="短剧ID" />
-        <el-table-column label="充值金额">
+        <el-table-column prop="day" label="时间" />
+        <el-table-column prop="video_name" label="短剧名称" min-width="160px" />
+        <el-table-column prop="video_id" label="短剧ID" />
+        <el-table-column label="充值金额" sortable prop="amount">
           <template #header>
-            <div class="flex items-center">
-              <span>充值金额</span>
-              <el-tooltip placement="top">
-                <template #content>
-                  当前推广链接的状态<br />
-                  启用:当前推广ID已绑定回传配置<br />
-                  禁用:当前推广ID未绑定回传配置
-                </template>
-                <el-icon>
-                  <InfoFilled />
-                </el-icon>
-              </el-tooltip>
-            </div>
+            <span>充值金额</span>
+            <el-tooltip placement="top">
+              <template #content>
+                当日短剧充值总额;基于推广公司的小程序统计;<br />
+              </template>
+              <el-icon>
+                <InfoFilled />
+              </el-icon>
+            </el-tooltip>
           </template>
           <template #default="scope">
             <div class="wrapper">
-              <div>充值金额</div>
+              <div>{{ scope.row.amount }}</div>
             </div>
           </template>
         </el-table-column>
-        <el-table-column label="充值次数">
+        <el-table-column label="充值次数" sortable prop="charge_count">
           <template #header>
-            <div class="flex items-center">
-              <span>充值次数</span>
-              <el-tooltip placement="top">
-                <template #content>
-                  当前推广链接的状态<br />
-                  启用:当前推广ID已绑定回传配置<br />
-                  禁用:当前推广ID未绑定回传配置
-                </template>
-                <el-icon>
-                  <InfoFilled />
-                </el-icon>
-              </el-tooltip>
-            </div>
+            <span>充值次数</span>
+            <el-tooltip placement="top">
+              <template #content>
+                当日短剧充值总次数;基于推广公司的小程序统计;<br />
+              </template>
+              <el-icon>
+                <InfoFilled />
+              </el-icon>
+            </el-tooltip>
           </template>
           <template #default="scope">
             <div class="wrapper">
-              <div>充值次数</div>
+              <div>{{ scope.row.charge_count }}</div>
             </div>
           </template>
         </el-table-column>
-        <el-table-column label="充值人数">
+        <el-table-column label="充值人数" sortable prop="charge_user_num">
           <template #header>
-            <div class="flex items-center">
-              <span>充值人数</span>
-              <el-tooltip placement="top">
-                <template #content>
-                  当前推广链接的状态<br />
-                  启用:当前推广ID已绑定回传配置<br />
-                  禁用:当前推广ID未绑定回传配置
-                </template>
-                <el-icon>
-                  <InfoFilled />
-                </el-icon>
-              </el-tooltip>
-            </div>
+            <span>充值人数</span>
+            <el-tooltip placement="top">
+              <template #content>
+                当日累计充值人数;基于推广公司的小程序统计;<br />
+              </template>
+              <el-icon>
+                <InfoFilled />
+              </el-icon>
+            </el-tooltip>
           </template>
           <template #default="scope">
             <div class="wrapper">
-              <div>充值人数</div>
+              <div>{{ scope.row.charge_user_num }}</div>
             </div>
           </template>
         </el-table-column>
-        <el-table-column label="播放次数">
+        <el-table-column label="播放次数" sortable prop="play_count">
           <template #header>
-            <div class="flex items-center">
-              <span>播放次数</span>
-              <el-tooltip placement="top">
-                <template #content>
-                  当前推广链接的状态<br />
-                  启用:当前推广ID已绑定回传配置<br />
-                  禁用:当前推广ID未绑定回传配置
-                </template>
-                <el-icon>
-                  <InfoFilled />
-                </el-icon>
-              </el-tooltip>
-            </div>
+            <span>播放次数</span>
+            <el-tooltip placement="top">
+              <template #content>
+                当日短剧累计播放次数:指当日绑定此短剧的所有推广链接,累计被点击次数<br />
+              </template>
+              <el-icon>
+                <InfoFilled />
+              </el-icon>
+            </el-tooltip>
           </template>
           <template #default="scope">
             <div class="wrapper">
-              <div>播放次数</div>
+              <div>{{ scope.row.play_count }}</div>
             </div>
           </template>
         </el-table-column>
@@ -126,18 +110,18 @@
     </div>
   </div>
 </template>
-
 <script lang="ts" setup>
-import { shortcuts } from '@/utils/shortcuts'
-import { useRouter, useRoute } from 'vue-router'
+import { shortcuts } from '@/utils/shortcuts';
+import { useRouter, useRoute } from 'vue-router';
 import { InfoFilled } from '@element-plus/icons-vue';
 import { useGetList } from '@/hook/curd/useGetList';
-import { titleObj } from "./excelTitle"
+import { statisticVideoStats } from '@/api/dataStatistics/shortStatistical/index';
+import { titleObj } from "./excelTitle";
 import moment from 'moment';
-const start_date = moment().startOf('month').format('YYYY-MM-DD')
-const end_date = moment().endOf('month').format('YYYY-MM-DD')
-const statisticalData = ref({})
-const api = 'channel/order_list';
+const start_date = moment().subtract(7, 'days').format('YYYY-MM-DD');
+const end_date = moment().format('YYYY-MM-DD');
+const statisticalData = ref({});
+const api = 'statistic/video/list';
 const router = useRouter()
 const route = useRoute()
 const { data, query, search, reset, loading } = useGetList(api);
@@ -147,22 +131,35 @@ const timeChange = (e: object) => {
   console.log(e, 'timeChangetimeChangetimeChange');
   if (query.value.time) {
     const timeArr = toRaw(e);
-    query.value.created_at_start = timeArr[0]
-    query.value.created_at_end = timeArr[1]
+    query.value.start_date = timeArr[0]
+    query.value.end_date = timeArr[1]
   } else {
-    delete query.value.created_at_start
-    delete query.value.created_at_end
+    delete query.value.start_date
+    delete query.value.end_date
   }
 }
 
-const resetQuery = () => {
+const moreSearch = () => {
+  search();
+  statisticVideoStats({ ...query.value }).then(res => {
+    statisticalData.value = res.data
+  })
+}
+
+const moreReset = () => {
   reset()
+  statisticVideoStats({ ...query.value }).then(res => {
+    statisticalData.value = res.data
+  })
 }
 
 const tableData = computed(() => data.value?.data);
 
 onMounted(() => {
-  search();
+  query.value.time = [start_date, end_date];
+  query.value.start_date = start_date;
+  query.value.end_date = end_date;
+  moreSearch();
 });
 </script>
 

+ 7 - 105
src/views/videoManage/videoLibraryList/detail.vue

@@ -78,58 +78,15 @@
     </video>
   </el-dialog>
   <Dialog v-model="linkVisible" title="创建推广链接" destroy-on-close>
-    <el-form :model="formDataForm" label-width="120px" ref="form" v-loading="loading" class="pr-4">
-      <el-form-item label="推广名称" prop="name" :rules="[{ required: true, message: '推广名称必须填写' }]">
-        <el-input v-model="formDataForm.name" name="name" clearable />
-      </el-form-item>
-      <el-form-item label="入口章节" prop="series_sequence" :rules="[{ required: false, message: '入口章节必须填写' }]">
-        <el-input disabled v-model="current.series_name" name="author" clearable />
-      </el-form-item>
-      <el-form-item label="充值模板配置">
-        <template #label>
-          <div class="flex items-center">
-            <span class="mr-1 text-red-600">*</span>充值模板配置
-          </div>
-        </template>
-        <div class="items-center w-full withdraw-popup-warn">
-          <div>如果没有目标充值模板,请前往<span class="text-lg font-bold text-blue-400 cursor-pointer"
-              @click="toCharge">充值管理</span>进行添加</div>
-        </div>
-        <div class="flex flex-col">
-          <div class="flex items-center">
-            <div style="width:80px;text-align: end;" class="mb-3 mr-2">首充模板:</div>
-            <el-select v-model="formDataForm.first_charge_template_id" filterable remote clearable
-              :remote-method="(query) => { remoteMethod(query, 'firstCharge') }" placeholder="请选择首充模板">
-              <el-option v-for="(item, index) in firstTemplateList" :key="index" :label="item.name" :value="item.id" />
-            </el-select>
-          </div>
-          <div class="flex items-center">
-            <div style="width:80px;text-align: end;" class="mr-2">非首充模板:</div>
-            <el-select v-model="formDataForm.not_first_charge_template_id" filterable remote clearable
-              :remote-method="(query) => { remoteMethod(query, 'notFirstCharge') }" placeholder="请选择非首充模板">
-              <el-option v-for="(item, index) in nofirstTemplate" :key="index" :label="item.name" :value="item.id" />
-            </el-select>
-          </div>
-        </div>
-      </el-form-item>
-      <div class="flex justify-end">
-        <el-button type="primary" @click="submitForm(form)">{{
-          $t('system.confirm')
-        }}</el-button>
-      </div>
-    </el-form>
+    <detailForm :primary="formDataExtra"></detailForm>
   </Dialog>
 </template>
 
 <script lang="ts" setup>
-// import router from '@/router'
 import Cache from '@/support/cache';
 import { computed, onMounted, ref } from 'vue';
 import { useGetList } from '@/hook/curd/useGetList';
-import { useOpen } from '@/hook/curd/useOpen';
-import { FormInstance } from 'element-plus';
-import { tuiguangPromotionAdd } from '@/api/promotion/index'
-import { channelPaytemplateList } from '@/api/charge/index'
+import detailForm from './form/detailForm.vue'
 const api = 'videoStock/episode/list';
 const props = defineProps({
   primary: String | Number,
@@ -138,20 +95,15 @@ const isShowCreatePromotion = computed(
   () => JSON.parse(Cache.get('nav_data'))?.advertiser?.miniProgramIds
     && JSON.parse(Cache.get('nav_data'))?.app
 )
-const router = useRouter()
-const form = ref()
-const formDataForm = ref({})
+const formDataExtra = ref({})
 const current = ref({})
 const playVisible = ref(false)
 const linkVisible = ref(false)
 const { data, query, search, reset, loading } = useGetList(api);
-const { open, close, title, visible, id } = useOpen();
-const firstTemplateList = ref([])
-const nofirstTemplate = ref([])
 if (props.primary) {
   query.value.video_id = props.primary.id
-  formDataForm.value.video_id = props.primary.id
-  formDataForm.value.miniprogram_id = JSON.parse(Cache.get('nav_data'))?.app?.id
+  formDataExtra.value.video_id = props.primary.id
+  formDataExtra.value.miniprogram_id = JSON.parse(Cache.get('nav_data'))?.app?.id
 }
 const tableData = computed(() => data.value?.data);
 const play = (e: object) => {
@@ -159,65 +111,15 @@ const play = (e: object) => {
   playVisible.value = true;
 }
 
-const remoteMethod = (query: string, type: string,) => {
-  console.log(query, 'queryquery', type);
-  switch (type) {
-    case 'firstCharge':
-      initRemoteOption('firstCharge', { name: query })
-      break;
-    case 'notFirstCharge':
-      initRemoteOption('notFirstCharge', { name: query })
-      break;
-  }
-}
-const toCharge = () => {
-  router.push({ path: '/chargeManage/charge' })
-}
-
-const initRemoteOption = (type: string, params?: object) => {
-  switch (type) {
-    case 'firstCharge':
-      channelPaytemplateList({ limit: 999, type: 1, ...params }).then(res => {
-        firstTemplateList.value = res.data
-      })
-      break;
-    case 'notFirstCharge':
-      channelPaytemplateList({ limit: 999, type: 2, ...params }).then(res => {
-        nofirstTemplate.value = res.data
-      })
-      break;
-  }
-}
-
 const createLink = (e: object) => {
   current.value = e;
-  formDataForm.value.series_sequence = e.series_sequence
+  formDataExtra.value.series_sequence = e.series_sequence
+  formDataExtra.value.series_name = e.series_name
   linkVisible.value = true;
 }
 
-const submitForm = (formEl: FormInstance | undefined) => {
-  if (!formDataForm.value.first_charge_template_id) return ElMessage.error('请选择首充模板')
-  if (!formDataForm.value.not_first_charge_template_id) return ElMessage.error('请选择非首充模板')
-  if (!formEl) return;
-  formEl
-    .validate(valid => {
-      if (valid) {
-        tuiguangPromotionAdd(formDataForm.value).then(res => {
-          console.log(res, 'tuiguangPromotionAddtuiguangPromotionAdd');
-          ElMessage.success(res.message)
-          linkVisible.value = false;
-          router.push({ path: '/promotion/promotionList', query: { tab: 0 } })
-        })
-      } else {
-      }
-    })
-    .then(() => { });
-}
-
 onMounted(() => {
   search();
-  initRemoteOption('firstCharge')
-  initRemoteOption('notFirstCharge')
 });
 </script>
 

+ 138 - 0
src/views/videoManage/videoLibraryList/form/detailForm.vue

@@ -0,0 +1,138 @@
+<template>
+  <el-form :model="formDataForm" label-width="120px" ref="form" v-loading="loading" class="pr-4">
+    <el-form-item label="推广名称" prop="name" :rules="[{ required: true, message: '推广名称必须填写' }]">
+      <el-input v-model="formDataForm.name" name="name" clearable />
+    </el-form-item>
+    <el-form-item label="入口章节" prop="series_sequence" :rules="[{ required: false, message: '入口章节必须填写' }]">
+      <el-input disabled v-model="formDataForm.series_name" name="author" clearable />
+    </el-form-item>
+    <el-form-item label="充值模板配置">
+      <template #label>
+        <div class="flex items-center">
+          <span class="mr-1 text-red-600">*</span>充值模板配置
+        </div>
+      </template>
+      <div class="items-center w-full withdraw-popup-warn">
+        <div>如果没有目标充值模板,请前往<span class="text-lg font-bold text-blue-400 cursor-pointer" @click="toCharge">充值管理</span>进行添加
+        </div>
+      </div>
+      <div class="flex flex-col">
+        <div class="flex items-center">
+          <div style="width:80px;text-align: end;" class="mb-3 mr-2">首充模板:</div>
+          <el-select v-model="formDataForm.first_charge_template_id" filterable remote clearable
+            :remote-method="(query) => { remoteMethod(query, 'firstCharge') }" placeholder="请选择首充模板">
+            <el-option v-for="(item, index) in firstTemplateList" :key="index" :label="item.name" :value="item.id" />
+          </el-select>
+        </div>
+        <div class="flex items-center">
+          <div style="width:80px;text-align: end;" class="mr-2">非首充模板:</div>
+          <el-select v-model="formDataForm.not_first_charge_template_id" filterable remote clearable
+            :remote-method="(query) => { remoteMethod(query, 'notFirstCharge') }" placeholder="请选择非首充模板">
+            <el-option v-for="(item, index) in nofirstTemplate" :key="index" :label="item.name" :value="item.id" />
+          </el-select>
+        </div>
+      </div>
+    </el-form-item>
+    <div class="flex justify-end">
+      <el-button type="primary" @click="submitForm(form)">{{
+        $t('system.confirm')
+      }}</el-button>
+    </div>
+  </el-form>
+</template>
+
+<script lang="ts" setup>
+import Cache from '@/support/cache';
+import { computed, onMounted, ref } from 'vue';
+import { useOpen } from '@/hook/curd/useOpen';
+import { FormInstance } from 'element-plus';
+import { tuiguangPromotionAdd } from '@/api/promotion/index'
+import { channelPaytemplateList } from '@/api/charge/index'
+const emit = defineEmits(['close']);
+const props = defineProps({
+  primary: Object,
+});
+const router = useRouter()
+const form = ref()
+const formDataForm = ref({})
+const playVisible = ref(false)
+const linkVisible = ref(false)
+const firstTemplateList = ref([])
+const nofirstTemplate = ref([])
+if (props.primary) {
+  console.log(props.primary, 'props.primary');
+  if (props.primary?.video_id) {
+    formDataForm.value = JSON.parse(JSON.stringify(props.primary))
+  }
+}
+
+const remoteMethod = (query: string, type: string,) => {
+  console.log(query, 'queryquery', type);
+  switch (type) {
+    case 'firstCharge':
+      initRemoteOption('firstCharge', { name: query })
+      break;
+    case 'notFirstCharge':
+      initRemoteOption('notFirstCharge', { name: query })
+      break;
+  }
+}
+const toCharge = () => {
+  router.push({ path: '/chargeManage/charge' })
+}
+
+const initRemoteOption = (type: string, params?: object) => {
+  switch (type) {
+    case 'firstCharge':
+      channelPaytemplateList({ limit: 999, type: 1, ...params }).then(res => {
+        firstTemplateList.value = res.data
+      })
+      break;
+    case 'notFirstCharge':
+      channelPaytemplateList({ limit: 999, type: 2, ...params }).then(res => {
+        nofirstTemplate.value = res.data
+      })
+      break;
+  }
+}
+
+const submitForm = (formEl: FormInstance | undefined) => {
+  if (!formDataForm.value.first_charge_template_id) return ElMessage.error('请选择首充模板')
+  if (!formDataForm.value.not_first_charge_template_id) return ElMessage.error('请选择非首充模板')
+  if (!formEl) return;
+  formEl
+    .validate(valid => {
+      if (valid) {
+        tuiguangPromotionAdd(formDataForm.value).then(res => {
+          console.log(res, 'tuiguangPromotionAddtuiguangPromotionAdd');
+          ElMessage.success(res.message)
+          linkVisible.value = false;
+          emit('close')
+          router.push({ path: '/promotion/promotionList', query: { tab: 0 } })
+        })
+      } else {
+      }
+    })
+    .then(() => { });
+}
+
+onMounted(() => {
+  initRemoteOption('firstCharge')
+  initRemoteOption('notFirstCharge')
+});
+</script>
+
+<style lang="scss" scoped>
+.note {
+  font-size: 16px;
+  width: fit-content;
+  word-wrap: break-word;
+  word-break: break-all;
+}
+
+.withdraw-popup-warn {
+  margin-bottom: 10px;
+  font-weight: 600;
+  line-height: 1.8;
+}
+</style>

+ 3 - 6
src/views/videoManage/videoLibraryList/index.vue

@@ -152,13 +152,10 @@
       destroy-on-close>
       <uploadVideo @close="closeType('uploadVisible')" :primary="uploadData"></uploadVideo>
     </Dialog>
-    <el-dialog draggable v-action="'video.video.list'" align-center append-to-body v-model="videoDetailVisible"
-      width="50%" title="短剧详情" destroy-on-close>
-      <videoDetail @close="closeType('videoDetailVisible')" :primary="videoDetailData"></videoDetail>
-    </el-dialog>
-    <!-- <Dialog v-action="'video.video.list'" v-model="videoDetailVisible" width="50%" title="短剧详情" destroy-on-close>
+    <Dialog v-action="'video.video.list'" :alignCenter="true" v-model="videoDetailVisible" width="50%" title="短剧详情"
+      destroy-on-close>
       <videoDetail @close="closeType('videoDetailVisible')" :primary="videoDetailData"></videoDetail>
-    </Dialog> -->
+    </Dialog>
   </div>
 </template>