Explorar o código

结算订单等

pansl %!s(int64=2) %!d(string=hai) anos
pai
achega
784cb8f1a7
Modificáronse 41 ficheiros con 3038 adicións e 93 borrados
  1. 35 8
      src/App.vue
  2. 87 7
      src/api/orders/index.ts
  3. 91 0
      src/api/settlement/index.ts
  4. 12 3
      src/layout/components/Menu/index.vue
  5. 31 10
      src/layout/components/header/index.vue
  6. 0 61
      src/views/ordersManage/form/userDetail.vue
  7. 33 0
      src/views/ordersManage/index.vue
  8. 16 0
      src/views/ordersManage/tabs/rechargeList/excelTitle.ts
  9. 309 0
      src/views/ordersManage/tabs/rechargeList/index.vue
  10. 88 0
      src/views/ordersManage/tabs/rechargeList/userDetail/index.vue
  11. 40 0
      src/views/ordersManage/tabs/rechargeList/userDetail/tables/consume.vue
  12. 38 0
      src/views/ordersManage/tabs/rechargeList/userDetail/tables/readLog.vue
  13. 38 0
      src/views/ordersManage/tabs/rechargeList/userDetail/tables/recharge.vue
  14. 16 0
      src/views/ordersManage/tabs/refundList/excelTitle.ts
  15. 370 0
      src/views/ordersManage/tabs/refundList/index.vue
  16. 4 4
      src/views/promotion/promotionList/index.vue
  17. 28 0
      src/views/settleManage/financialControl/index.vue
  18. 8 0
      src/views/settleManage/financialControl/tabs/rechargeSettle/excelTitle.ts
  19. 112 0
      src/views/settleManage/financialControl/tabs/rechargeSettle/form/create.vue
  20. 258 0
      src/views/settleManage/financialControl/tabs/rechargeSettle/index.vue
  21. 108 0
      src/views/settleManage/financialControl/tabs/rechargeSettle/withdrawDetail/index.vue
  22. 11 0
      src/views/settleManage/financialControl/tabs/rechargeSettle/withdrawDetail/tables/settleInfo/excelTitle.ts
  23. 106 0
      src/views/settleManage/financialControl/tabs/rechargeSettle/withdrawDetail/tables/settleInfo/index.vue
  24. 11 0
      src/views/settleManage/financialControl/tabs/rechargeSettle/withdrawDetail/tables/withdrawalRecord/excelTitle.ts
  25. 129 0
      src/views/settleManage/financialControl/tabs/rechargeSettle/withdrawDetail/tables/withdrawalRecord/index.vue
  26. 32 0
      src/views/settleManage/paymentAccountInfo/index.vue
  27. 28 0
      src/views/settleManage/paymentAccountInfo/tabs/cooperate/index.vue
  28. 132 0
      src/views/settleManage/paymentAccountInfo/tabs/paymentInfo/form/create.vue
  29. 160 0
      src/views/settleManage/paymentAccountInfo/tabs/paymentInfo/index.vue
  30. 32 0
      src/views/settleManage/settlementCenter/index.vue
  31. 24 0
      src/views/settleManage/settlementCenter/tabs/rechargeRules/index.vue
  32. 8 0
      src/views/settleManage/settlementCenter/tabs/rechargeSettle/excelTitle.ts
  33. 112 0
      src/views/settleManage/settlementCenter/tabs/rechargeSettle/form/create.vue
  34. 212 0
      src/views/settleManage/settlementCenter/tabs/rechargeSettle/index.vue
  35. 30 0
      src/views/settleManage/settlementCenter/tabs/rechargeSettle/orderDetail/index.vue
  36. 16 0
      src/views/settleManage/settlementCenter/tabs/rechargeSettle/orderDetail/tabs/rechargeList/excelTitle.ts
  37. 60 0
      src/views/settleManage/settlementCenter/tabs/rechargeSettle/orderDetail/tabs/rechargeList/index.vue
  38. 16 0
      src/views/settleManage/settlementCenter/tabs/rechargeSettle/orderDetail/tabs/refundList/excelTitle.ts
  39. 60 0
      src/views/settleManage/settlementCenter/tabs/rechargeSettle/orderDetail/tabs/refundList/index.vue
  40. 11 0
      src/views/settleManage/settlementCenter/tabs/rechargeSettle/withdrawalRecord/excelTitle.ts
  41. 126 0
      src/views/settleManage/settlementCenter/tabs/rechargeSettle/withdrawalRecord/index.vue

+ 35 - 8
src/App.vue

@@ -7,10 +7,19 @@ import router from '@/router'
 import { watch, onMounted, ref } from 'vue'
 import { useAppStore } from '@/stores/modules/app'
 import { RouteLocationNormalizedLoaded } from 'vue-router'
-
+import { useUserStore } from '@/stores/modules/user/index'
 const appStore = useAppStore()
 const breadcrumbs = ref<string[]>([])
+const userStore = useUserStore()
+
+const rolesIdentify = computed(() => userStore.getRoles?.map(el => el?.identify))
 
+provide('rolesIdentify', rolesIdentify)
+// get init breadcrumb
+onMounted(() => {
+  setActiveMenu(router.currentRoute.value)
+  getBreadcrumbs(router.currentRoute.value)
+})
 // 监听当前路由的变化
 watch(router.currentRoute, (newValue, oldValue) => {
   // 激活菜单
@@ -20,13 +29,6 @@ watch(router.currentRoute, (newValue, oldValue) => {
   setActiveMenu(newValue)
   getBreadcrumbs(newValue)
 })
-
-// get init breadcrumb
-onMounted(() => {
-  setActiveMenu(router.currentRoute.value)
-  getBreadcrumbs(router.currentRoute.value)
-})
-
 const setActiveMenu = route => {
   if (route.path !== '/') {
     // 如果是内页,并且设置激活菜单
@@ -49,3 +51,28 @@ function getBreadcrumbs(newRoute: RouteLocationNormalizedLoaded) {
   })
 }
 </script>
+
+<style lang="scss">
+::-webkit-scrollbar {
+  width: 6px;
+  height: 8px;
+  background-color: #ebeef5;
+}
+
+::-webkit-scrollbar-thumb {
+  border-radius: 30px;
+  box-shadow: inset 0 0 6px rgba(0, 0, 0, .3);
+  -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, .3);
+  background-color: #ccc;
+}
+
+::-webkit-scrollbar-thumb:hover {
+  background-color: rgba($color: #000000, $alpha: .5);
+}
+
+::-webkit-scrollbar-track {
+  box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
+  border-radius: 3px;
+  background: rgba(255, 255, 255, 1);
+}
+</style>

+ 87 - 7
src/api/orders/index.ts

@@ -1,12 +1,92 @@
 import http from '@/api/http';
+// 获取微信小程序充值会员信息
+export function wechatMinUserInfo(id: number | string) {
+  return http.get(`/channel/wechat_min_user/detail/${id}`);
+}
 
-export function orderList(params: object) {
-  return http.get('/channel/order_list', params);
+/**
+ * 获取微信小程序充值会员充值记录
+ */
+export function channelWechatMinUserOrderList(params: object) {
+  return http.get('/channel/wechat_min_user/order_list', params);
+}
+/**
+ * 获取微信小程序充会员的消费记录
+ */
+export function channelWechatMinUserConsumeRecord(params: object) {
+  return http.get('/channel/wechat_min_user/consume_record', params);
+}
+/**
+ * 获取微信小程序充值会员观看记录
+ */
+export function channelWechatMinUserWatchRecord(params: object) {
+  return http.get('/channel/wechat_min_user/watch_record', params);
 }
 
+/**
+ * 订单列表
+ */
+export function channelOrderList(params: object) {
+  return http.get('/channel/order_list', params);
+}
+/**
+ * 订单列表小程序选择项
+ */
+export function channelMiniprogramUseList(params: object) {
+  return http.get('/channel/miniprogram/use_list', params);
+}
+/**
+ * 订单列表推广选择项
+ */
+export function channelPromotionsOptions(params: object) {
+  return http.get('/channel/promotions/options', params);
+}
+/**
+ * 订单列表优化师选项
+ */
+export function channelPromotionsUsers(params: object) {
+  return http.get('/channel/promotions/users', params);
+}
+/**
+ * 支付状态选择项
+ */
+export function channelOrderStatus(params?: object) {
+  return http.get('/channel/order_status', params);
+}
+/**
+ * 充值类型选择项
+ */
+export function channelOrderType(params?: object) {
+  return http.get('/channel/order_types', params);
+}
+/**
+ * 退款订单列表
+ */
+export function orderRefundOrderList(params: object) {
+  return http.get('/orderRefund/order_list', params);
+}
 
-export function wechatMinUserInfo(
-  id: number | string
-) {
-  return http.get(`/channel/wechat_min_user/detail/${id}`);
-}
+/**
+ * 退款申请
+ */
+export function orderRefundApply(params: object) {
+  return http.post(`/orderRefund/apply`, params);
+}
+/**
+ * 平台审核
+ */
+export function orderRefundVerifyPt(params: object) {
+  return http.post(`/orderRefund/verify/pt`, params);
+}
+/**
+ * 商户审核
+ */
+export function orderRefundVerifySh(params: object) {
+  return http.post(`/orderRefund/verify/sh`, params);
+}
+/**
+ * 退款操作
+ */
+export function orderRefundPayToUser(params: object) {
+  return http.post(`/orderRefund/payToUser`, params);
+}

+ 91 - 0
src/api/settlement/index.ts

@@ -0,0 +1,91 @@
+import http from '@/api/http';
+
+// 结算-列表
+export function jiesuanManageJiesuanList(params: object) {
+  return http.get(`/jiesuanManage/jiesuan/list`, params);
+}
+
+/**
+ * 结算-账户金额信息
+ */
+export function jiesuanManageJiesuanAccountInfo(params?: object) {
+  return http.get('/jiesuanManage/jiesuan/accountInfo', params);
+}
+
+/**
+ * 结算-申请提现
+ */
+export function jiesuanManageJiesuanTixian(params: object) {
+  return http.post(`/jiesuanManage/jiesuan/tixian`, params);
+}
+
+/**
+ * 结算-提现记录列表
+ */
+export function jiesuanManageJiesuanListTixian(params: object) {
+  return http.get('/jiesuanManage/jiesuan/listTixian', params);
+}
+
+/**
+ * 银行卡账号-添加、修改
+ */
+export function jiesuanManageBankAccountAddCompanyCard(params: object) {
+  return http.post(`/jiesuanManage/bankAccount/addCompanyCard`, params);
+}
+
+/**
+ * 银行列表
+ */
+export function jiesuanManageBankAccountListBank(params?: object) {
+  return http.get('/jiesuanManage/bankAccount/listBank', params);
+}
+
+/**
+ * 银行卡-合作信息
+ */
+export function jiesuanManageBankAccountHezuoInfo(params?: object) {
+  return http.get('/jiesuanManage/bankAccount/hezuoInfo', params);
+}
+/**
+ * 银行卡-商务列表
+ */
+export function jiesuanManageBankAccountListShangwu(params?: object) {
+  return http.get('/jiesuanManage/bankAccount/listShangwu', params);
+}
+/**
+ * 银行卡-所有银行卡列表
+ */
+export function jiesuanManageBankAccountListCompanyCard(params: object) {
+  return http.get('/jiesuanManage/bankAccount/listCompanyCard', params);
+}
+/**
+ * 银行卡-所有可用银行卡列表
+ */
+export function jiesuanManageBankAccountListAvailableBankCard(params?: object) {
+  return http.get('/jiesuanManage/bankAccount/listAvailableBankCard', params);
+}
+/**
+ * 财务审核-提现列表
+ */
+export function jiesuanManageFinanceCheckList(params: object) {
+  return http.get('/jiesuanManage/financeCheck/list', params);
+}
+/**
+ * 财务审核-公司账号金额详情
+ */
+export function jiesuanManageFinanceCheckGetShanghuAccountInfo(params: object) {
+  return http.get('/jiesuanManage/financeCheck/getShanghuAccountInfo', params);
+}
+
+/**
+ * 财务审核-待审核到审核
+ */
+export function jiesuanManageFinanceCheckCheck(params: object) {
+  return http.post(`/jiesuanManage/financeCheck/check`, params);
+}
+/**
+ * 财务审核-打款
+ */
+export function jiesuanManageFinanceCheckRemit(params: object) {
+  return http.post(`/jiesuanManage/financeCheck/remit`, params);
+}

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

@@ -5,6 +5,7 @@ import MenuItem from './item.vue'
 import menus from './menus.vue'
 import { useUserStore } from '@/stores/modules/user'
 import { Menu } from '@/types/Menu'
+import { tr } from 'element-plus/es/locale'
 
 /**
  * 递归渲染 Menu 节点
@@ -105,9 +106,17 @@ export default defineComponent({
     const userStore = useUserStore()
 
     // 后端的 permissions 返回 undefined,则认为该后端无权限系统
-    const permissions = userStore.getPermissions === undefined ? [] : userStore.getPermissions
+    // 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)
+    }, {
+      immediate: true,
+      deep: true
+    })
 
-    const vnodes = getVNodes(filterMenus(permissionsStore.getMenusFrom(permissions,true)), props.subMenuClass)
     return () => {
       return h(
         menus,
@@ -115,7 +124,7 @@ export default defineComponent({
           class: 'border-none side-menu ' + props.menuClass,
         },
         {
-          default: () => vnodes,
+          default: () => vnodes.value,
         },
       )
     }

+ 31 - 10
src/layout/components/header/index.vue

@@ -85,13 +85,35 @@ const isShowNavData = computed(() => {
   return userStore.getRoles?.some(el => (el?.identify == 'optimizer'))
 })
 const appChange = (e) => {
+  userStore.getUserInfo().then(res => {
+    const {
+      id,
+      username,
+      email,
+      avatar,
+      permissions,
+      roles,
+      rememberToken,
+      status
+    } = res;
+    // set user info
+    userStore.setId(id);
+    userStore.setUsername(username);
+    userStore.setEmail(email);
+    userStore.setRoles(roles);
+    userStore.setRememberToken(rememberToken);
+    userStore.setStatus(status);
+    userStore.setAvatar(avatar);
+    userStore.setPermissions(permissions);
+  })
   console.log(e, 'appChange', userStore.roles, navData.value, 'appChange.valappChangeappChangeue');
   Cache.set('nav_data', JSON.stringify(navData.value));
-  router.push('/')
-  let timer = setTimeout(() => {
-    location.reload()
-    clearTimeout(timer)
-  }, 100)
+
+  // router.push('/')
+  // let timer = setTimeout(() => {
+  //   location.reload()
+  //   clearTimeout(timer)
+  // }, 100)
   searchMenuVisiable.value = false
 }
 
@@ -108,11 +130,10 @@ onMounted(() => {
       navData.value = JSON.parse(Cache.get('nav_data')) || {}
       miniPrograms.value = JSON.parse(Cache.get('nav_data'))?.advertiser?.miniPrograms || []
     } else {
-      // if (miniPrograms.value.length == 1) {
-      //   navData.value.app = miniPrograms.value[0].app_name
-      //   Cache.set('nav_data', JSON.stringify(navData.value));
-      //   location.reload()
-      // }
+      if (miniPrograms.value.length == 1) {
+        navData.value.app = miniPrograms.value[0].app_name
+        Cache.set('nav_data', JSON.stringify(navData.value));
+      }
     }
     clearTimeout(timer)
   }, 300);

+ 0 - 61
src/views/ordersManage/form/userDetail.vue

@@ -1,61 +0,0 @@
-<template>
-	<div>
-		<div> 用户ID:{{userInfo.uid}}<p></p></div>
-		
-	</div>
-	<el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick">
-    <el-tab-pane label="阅读记录" name="watch_record">
-		
-	</el-tab-pane>
-	
-    <el-tab-pane label="充值记录" name="order_list">
-		
-	</el-tab-pane>
-	
-    <el-tab-pane label="消耗记录" name="consume_record">
-		
-	</el-tab-pane>
-   </el-tabs>
-</template>
-
-<script lang="ts" setup>
-import { wechatMinUserInfo } from '@/api/orders/index';
-import {useGetList} from '@/hook/curd/useGetList';
-import { ref } from 'vue'
-import type { TabsPaneContext } from 'element-plus'
-const props = defineProps({
-    uid: String | Number,
-});
-const activeName = ref('watch_record')
-const api = ref('channel/wechat_min_user/watch_record');
-const handleClick = (tab: TabsPaneContext, event: Event) => {
-   console.log(tab, event, tab.props.name)
-}
-
-const userInfo = ref({});
-
-onMounted(() => {
-	console.log('props-------=:',props)
-	// query.value.uid = props.uid;
-	wechatMinUserInfo(props.uid).then(res=>{
-		userInfo.value = res.data;
-		console.log('props-------=:',userInfo)
-	});
-})
-
-</script>
-
-<style lang="scss" scoped>
-::v-deep(.el-input__wrapper) {
-  display: flex;
-  width: 180px;
-  flex: none;
-}
-
-.wrapper {
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  width: 100%;
-}
-</style>

+ 33 - 0
src/views/ordersManage/index.vue

@@ -0,0 +1,33 @@
+<template>
+  <div>
+    <el-card shadow="always" :body-style="{ padding: '20px' }">
+      <el-tabs v-model="activeName" class="demo-tabs" @tab-change="handChange">
+        <el-tab-pane label="充值订单" name="recharge">
+          <rechargeList></rechargeList>
+        </el-tab-pane>
+        <el-tab-pane label="退款订单" name="refund">
+          <refundList></refundList>
+        </el-tab-pane>
+      </el-tabs>
+    </el-card>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { useRouter, useRoute } from 'vue-router'
+import type { TabsPaneContext } from 'element-plus'
+import rechargeList from "./tabs/rechargeList/index.vue"
+import refundList from "./tabs/refundList/index.vue"
+const router = useRouter()
+const route = useRoute()
+const handChange = (tab: TabsPaneContext, event: Event) => {
+  router.push({ path: '/orders/order', query: { tab } })
+  activeName.value = tab
+}
+const activeName = ref('recharge')
+onMounted(() => {
+  activeName.value = route.query.tab || 'recharge'
+});
+</script>
+
+<style scoped lang="scss"></style>

+ 16 - 0
src/views/ordersManage/tabs/rechargeList/excelTitle.ts

@@ -0,0 +1,16 @@
+// 导出中文/字段
+export const titleObj = {
+  所属账户ID: 'advertiser_id',
+  所属账户: 'advertiser_name',
+  订单号: 'order_no',
+  用户ID: 'uid',
+  注册IP: 'user_ranse_ip',
+  注册时间: 'user_ranse_start_at',
+  充值时间: 'order_created_at',
+  充值金额: 'order_price',
+  是否回传: 'filter_type_str',
+  备注: 'filter_reason',
+  回传百分比: 'current_rate',
+  回传配置百分比: 'config_rate',
+  广告计划ID: 'adv_promotion_id'
+};

+ 309 - 0
src/views/ordersManage/tabs/rechargeList/index.vue

@@ -0,0 +1,309 @@
+<template>
+  <div>
+    <Search :search="search" :reset="resetQuery">
+      <template v-slot:body>
+        <el-form-item label="订单号" prop="trade_no">
+          <el-input v-model="query.trade_no" placeholder="请输入订单号" clearable />
+        </el-form-item>
+        <el-form-item label="用户ID" prop="uid">
+          <el-input v-model="query.uid" placeholder="请输入用户ID" clearable />
+        </el-form-item>
+        <el-form-item label="充值类型" prop="order_type">
+          <el-select v-model="query.order_type" filterable clearable placeholder="选择充值类型">
+            <el-option v-for="item in channelOrderTypeList" :key="item.value" :label="item.name" :value="item.value" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="订单状态" prop="status">
+          <el-select v-model="query.status" filterable clearable placeholder="选择订单状态">
+            <el-option v-for="item in channelOrderStatusList " :key="item.value" :label="item.name" :value="item.value" />
+          </el-select>
+        </el-form-item>
+        <!-- :remote-method="remoteMethod($event, 'channelPromotions')"不支持这种写法自定义参数 -->
+        <el-form-item label="推广名称" prop="promotion_id">
+          <el-select v-model="query.promotion_id" filterable remote clearable
+            @change="selectChange($event, 'channelPromotions')"
+            :remote-method="(query) => { remoteMethod(query, 'channelPromotions') }" placeholder="选择推广名称">
+            <el-option v-for="item in channelPromotions" :key="item.promotion_id" :label="item.name"
+              :value="item.promotion_id" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="小程序" v-if="!query.promotion_id" prop="miniprogram_id">
+          <el-select v-model="query.miniprogram_id" filterable remote @change="selectChange($event, 'channelMiniprogram')"
+            :remote-method="(query) => { remoteMethod(query, 'channelMiniprogram') }" clearable placeholder="选择小程序">
+            <el-option v-for="item in channelMiniprogram" :key="item.miniprogram_id" :label="item.name"
+              :value="item.miniprogram_id" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="优化师" v-if="!query.promotion_id" prop="user_id">
+          <el-select v-model="query.user_id" filterable remote clearable
+            @change="selectChange($event, 'channelPromotionsUsers')"
+            :remote-method="(query) => { remoteMethod(query, 'channelPromotionsUsers') }" placeholder="选择优化师">
+            <el-option v-for="item in promotionsUsersList" :key="item.user_id" :label="item.name" :value="item.user_id" />
+          </el-select>
+        </el-form-item>
+        <!-- <el-form-item label="支付时间">
+          <el-date-picker unlink-panels clearable @change="payTimeChange" format="YYYY/MM/DD" value-format="YYYY-MM-DD"
+            v-model="query.payTime" type="daterange" :shortcuts="shortcuts" range-separator="To" start-placeholder="开始时间"
+            end-placeholder="结束时间" />
+        </el-form-item> -->
+        <el-form-item label="订单时间">
+          <el-date-picker unlink-panels clearable @change="orderTimeChange" format="YYYY/MM/DD" value-format="YYYY-MM-DD"
+            v-model="query.orderTime" type="daterange" :shortcuts="shortcuts" range-separator="To"
+            start-placeholder="开始时间" end-placeholder="结束时间" />
+        </el-form-item>
+      </template>
+      <template v-slot:extra_button>
+        <exportExcel api="channel/order_list" sheet_name="订单列表" :title_obj="titleObj"
+          :extro_params="{ is_export: true, ...query }">
+        </exportExcel>
+      </template>
+    </Search>
+    <div class="table-default">
+      <el-table :data="tableData" class="mt-3" v-loading="loading">
+        <el-table-column prop="company_name" label="商户名称" min-width="200px">
+          <template #default="scope">
+            <div>{{ scope.row.company_name }}</div>
+            <div>ID:{{ scope.row.puser_id }}</div>
+          </template>
+        </el-table-column>
+        <el-table-column prop="username" label="优化师" show-overflow-tooltip min-width="200px">
+        </el-table-column>
+        <el-table-column prop="play_name" show-overflow-tooltip label="小程序" min-width="200px">
+        </el-table-column>
+        <el-table-column prop="uid" label="用户ID" show-overflow-tooltip>
+        </el-table-column>
+        <el-table-column prop="trade_no" label="订单号" show-overflow-tooltip min-width="200px">
+        </el-table-column>
+        <el-table-column prop="created_at" label="订单时间" show-overflow-tooltip min-width="200px" />
+        <el-table-column prop="ranse_created_at" label="染色注册时间" show-overflow-tooltip min-width="200px" />
+        <el-table-column prop="total_count" label="累计充值次数" show-overflow-tooltip min-width="150px">
+        </el-table-column>
+        <el-table-column prop="price" label="充值金额" show-overflow-tooltip>
+        </el-table-column>
+        <el-table-column prop="promotion_title" label="推广名称" show-overflow-tooltip min-width="200px">
+        </el-table-column>
+        <el-table-column prop="tip_text" label="充值类型" show-overflow-tooltip min-width="150px">
+        </el-table-column>
+        <el-table-column prop="pay_name" label="支付方式" show-overflow-tooltip min-width="150px">
+        </el-table-column>
+        <el-table-column prop="status_txt" label="订单状态" show-overflow-tooltip min-width="150px">
+          <template #default="scope">
+            <div class="wrapper">
+              <span class="text-lg font-bold content">
+                <el-text class="mx-1" :type="colorType(scope.row)">{{ scope.row.status_txt }}</el-text>
+              </span>
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column label="操作">
+          <template #default="scope">
+            <el-button link type="primary" size="small" @click="openType('userDetailVisible', scope.row)">用户详情</el-button>
+            <br />
+          </template>
+        </el-table-column>
+      </el-table>
+      <Paginate />
+    </div>
+    <Dialog v-model="userDetailVisible" width="50%" title="用户详情" destroy-on-close>
+      <userDetail @close="closeUserDetail" :primary="userDetailData"></userDetail>
+    </Dialog>
+  </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 { titleObj } from "./excelTitle"
+import userDetail from './userDetail/index.vue'
+import {
+  channelOrderList,
+  channelMiniprogramUseList,
+  channelPromotionsOptions,
+  channelPromotionsUsers,
+  channelOrderStatus,
+  channelOrderType,
+} from '@/api/orders/index'
+
+import { callbackJuliangAccountList, callbackJuliangAccountLogCallbackAgain } from '@/api/backConfig/index'
+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 api = 'channel/order_list';
+const router = useRouter()
+const route = useRoute()
+const { data, query, search, reset, loading } = useGetList(api);
+const userDetailVisible = ref(false)
+const userDetailData = ref({})
+const current = ref({})
+const promotionsUsersList = ref([])
+const channelMiniprogram = ref([])
+const channelPromotions = ref([])
+const channelOrderStatusList = ref([])
+const channelOrderTypeList = ref([])
+const rolesIdentify = inject('rolesIdentify')
+
+const colorType = (data: object) => {
+  const type = data.status
+  switch (type) {
+    case 'PAID':
+      return 'success'
+    case 'REFUND':
+      return 'default'
+    case 'UNPAID':
+      return 'danger'
+  }
+}
+
+const closeUserDetail = () => { }
+
+const payTimeChange = (e: object) => {
+  console.log(e, query.value.payTime, 'timeChangetimeChangetimeChange');
+  if (query.value.payTime) {
+    const timeArr = toRaw(e);
+    query.value.pay_end_at_start = timeArr[0]
+    query.value.pay_end_at_end = timeArr[1]
+  } else {
+    delete query.value.pay_end_at_start
+    delete query.value.pay_end_at_end
+  }
+}
+const orderTimeChange = (e: object) => {
+  console.log(e, 'timeChangetimeChangetimeChange');
+  if (query.value.orderTime) {
+    const timeArr = toRaw(e);
+    query.value.created_at_start = timeArr[0]
+    query.value.created_at_end = timeArr[1]
+  } else {
+    delete query.value.created_at_start
+    delete query.value.created_at_end
+  }
+}
+
+const selectChange = (e: object, type: string,) => {
+  console.log(e, 'queryquery', type);
+  if (e) {
+    switch (type) {
+      case 'channelPromotionsUsers':
+        query.value.miniprogram_id = ''
+        query.value.promotion_id = ''
+        initRemoteOption('channelPromotions', { name: '', user_id: e })
+        initRemoteOption('channelMiniprogram', { name: '', user_id: e })
+        break;
+      case 'channelMiniprogram':
+        query.value.user_id = ''
+        query.value.promotion_id = ''
+        initRemoteOption('channelMiniprogram', { name: '' })
+        initRemoteOption('channelPromotionsUsers', { name: '', miniprogram_id: e })
+        initRemoteOption('channelPromotions', { name: '', miniprogram_id: e })
+        break;
+      case 'channelPromotions':
+        // initRemoteOption('channelPromotions', { name: query })
+        break;
+    }
+  }
+}
+const remoteMethod = (query: string, type: string,) => {
+  console.log(query, 'queryquery', type);
+  if (query) {
+    switch (type) {
+      case 'channelPromotionsUsers':
+        initRemoteOption('channelPromotionsUsers', { name: query })
+        break;
+      case 'channelMiniprogram':
+        initRemoteOption('channelMiniprogram', { name: query })
+        break;
+      case 'channelPromotions':
+        initRemoteOption('channelPromotions', { name: query })
+        break;
+    }
+  }
+}
+
+const initRemoteOption = (type: string, params?: object) => {
+  switch (type) {
+    case 'channelPromotionsUsers':
+      channelPromotionsUsers({ limit: 30, ...params }).then(res => {
+        promotionsUsersList.value = res.data
+      })
+      break;
+    case 'channelMiniprogram':
+      channelMiniprogramUseList({ limit: 30, ...params }).then(res => {
+        channelMiniprogram.value = res.data
+      })
+      break;
+    case 'channelPromotions':
+      channelPromotionsOptions({ limit: 30, ...params }).then(res => {
+        channelPromotions.value = res.data
+      })
+      break;
+  }
+}
+
+const init = () => {
+  channelOrderStatus().then(res => {
+    console.log(res);
+    channelOrderStatusList.value = res.data
+  })
+  channelOrderType().then(res => {
+    console.log(res);
+    channelOrderTypeList.value = res.data
+  })
+}
+
+const resetQuery = () => {
+  reset()
+}
+const openType = (type: string, data: object) => {
+  current.value = data;
+  switch (type) {
+    case 'userDetailVisible':
+      userDetailVisible.value = true
+      userDetailData.value = data
+      break;
+    case 'backConfigVisible':
+      break;
+  }
+}
+const tableData = computed(() => data.value?.data);
+
+onMounted(() => {
+  console.log(rolesIdentify, 'rolesIdentifyrolesIdentify');
+  initRemoteOption('channelPromotionsUsers')
+  initRemoteOption('channelMiniprogram')
+  initRemoteOption('channelPromotions')
+  init()
+  // query.value.payTime = [start_date, end_date];
+  // query.value.pay_end_at_start = start_date
+  // query.value.pay_end_at_end = end_date
+  query.value.orderTime = [start_date, end_date];
+  query.value.created_at_start = start_date
+  query.value.created_at_end = end_date
+  search();
+});
+</script>
+
+<style scoped lang="scss">
+.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>

+ 88 - 0
src/views/ordersManage/tabs/rechargeList/userDetail/index.vue

@@ -0,0 +1,88 @@
+<template>
+  <el-card shadow="always" :body-style="{ padding: '20px' }">
+    <div class="wrapper">
+      <div class="row">
+        <div class="item"><span class="label">用户ID:</span><span class="content">{{ userInfo.uid }}</span></div>
+        <div class="item"><span class="label">会员:</span><span class="content">{{ userInfo.vip_text }}</span></div>
+        <div class="item"><span class="label">会员到期时间:</span><span class="content">{{ userInfo.vip_end }}</span></div>
+      </div>
+      <div class="row">
+        <div class="item"><span class="label">小程序:</span><span class="content">{{ userInfo.ju_chang }}</span></div>
+        <div class="item"><span class="label">看剧币:</span><span class="content">{{ userInfo.charge_coin }}</span></div>
+        <div class="item"><span class="label">赠币:</span><span class="content">{{ userInfo.reward_coin }}</span></div>
+      </div>
+      <div class="row">
+        <div class="item"><span class="label">染色注册时间:</span><span class="content">{{ userInfo.ranse_start_at }}</span>
+        </div>
+      </div>
+    </div>
+  </el-card>
+  <el-tabs v-model="activeName" @tab-change="handChange">
+    <el-tab-pane label="阅读记录" name="readLog">
+      <readLogTable v-if="activeName == 'readLog'" :primary="props.primary"></readLogTable>
+    </el-tab-pane>
+
+    <el-tab-pane label="充值记录" name="recharge">
+      <rechargeTable v-if="activeName == 'recharge'" :primary="props.primary"></rechargeTable>
+    </el-tab-pane>
+
+    <el-tab-pane label="消耗记录" name="consume">
+      <consumeTable v-if="activeName == 'consume'" :primary="props.primary"></consumeTable>
+    </el-tab-pane>
+  </el-tabs>
+</template>
+
+<script lang="ts" setup>
+import { wechatMinUserInfo } from '@/api/orders/index';
+import { useGetList } from '@/hook/curd/useGetList';
+import rechargeTable from './tables/recharge.vue'
+import consumeTable from './tables/consume.vue'
+import readLogTable from './tables/readLog.vue'
+import { ref } from 'vue'
+import type { TabsPaneContext } from 'element-plus'
+const props = defineProps({
+  primary: Object,
+});
+const userInfo = ref({});
+
+const activeName = ref('readLog')
+
+const handChange = (tab: TabsPaneContext, event: Event) => {
+  activeName.value = tab
+}
+onMounted(() => {
+  wechatMinUserInfo(props.primary.uid).then(res => {
+    userInfo.value = res.data;
+  });
+})
+
+</script>
+
+<style lang="scss" scoped>
+.wrapper {
+  display: flex;
+  flex-direction: column;
+  align-items: flex-start;
+  justify-content: center;
+  width: 100%;
+
+  .row {
+    width: 100%;
+    display: flex;
+
+    .item {
+      margin: 9px;
+
+      .label {
+        font-size: 16px;
+      }
+
+      .content {
+        font-size: 18px;
+        font-weight: 600;
+      }
+    }
+  }
+
+}
+</style>

+ 40 - 0
src/views/ordersManage/tabs/rechargeList/userDetail/tables/consume.vue

@@ -0,0 +1,40 @@
+<template>
+  <div class="flex flex-col justify-between w-full sm:flex-row" style="width:100%;">
+    <div class="table-default" style="width:100%;">
+      <el-table :data="tableData" class="w-full mt-3" style="width:100%;">
+        <el-table-column prop="updated_at" label="消耗时间" />
+        <el-table-column label="说明">
+          <template #default="scope">
+            <div>短剧:<span>{{ scope.row.video_name }}</span></div>
+            <div>章节名称:<span>{{ scope.row.series_name }}</span></div>
+          </template>
+        </el-table-column>
+        <el-table-column prop="charge_coin_cost" label="看剧币支付" />
+        <el-table-column prop="reward_coin_cost" label="赠币支付" />
+      </el-table>
+      <Paginate />
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { useGetList } from '@/hook/curd/useGetList';
+import { useOpen } from '@/hook/curd/useOpen';
+import { FormInstance } from 'element-plus';
+import { tuiguangPromotionAdd } from '@/api/promotion/index'
+const api = 'channel/wechat_min_user/consume_record';
+const props = defineProps({
+  primary: Object,
+});
+const { data, query, search, reset, loading } = useGetList(api);
+if (props.primary) {
+  query.value.uid = props.primary.uid
+}
+const tableData = computed(() => data.value?.data);
+
+onMounted(() => {
+  search();
+});
+</script>
+
+<style lang="scss" scoped></style>

+ 38 - 0
src/views/ordersManage/tabs/rechargeList/userDetail/tables/readLog.vue

@@ -0,0 +1,38 @@
+<template>
+  <div class="flex flex-col justify-between w-full sm:flex-row" style="width:100%;">
+    <div class="table-default" style="width:100%;">
+      <el-table :data="tableData" class="w-full mt-3" style="width:100%;">
+        <el-table-column prop="watch_at" label="时间" />
+        <el-table-column prop="video_id" label="短剧ID">
+        </el-table-column>
+        <el-table-column prop="video_name" label="短剧名称" />
+        <el-table-column prop="video_series_sequence" label="章节名称" />
+      </el-table>
+      <Paginate />
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { useGetList } from '@/hook/curd/useGetList';
+import { useOpen } from '@/hook/curd/useOpen';
+import { FormInstance } from 'element-plus';
+import { tuiguangPromotionAdd } from '@/api/promotion/index'
+const api = 'channel/wechat_min_user/watch_record';
+const props = defineProps({
+  primary: Object,
+});
+const { data, query, search, reset, loading } = useGetList(api);
+if (props.primary) {
+  query.value.uid = props.primary.uid
+}
+const tableData = computed(() => data.value?.data);
+
+onMounted(() => {
+  search();
+});
+</script>
+
+<style lang="scss" scoped>
+
+</style>

+ 38 - 0
src/views/ordersManage/tabs/rechargeList/userDetail/tables/recharge.vue

@@ -0,0 +1,38 @@
+<template>
+  <div class="flex flex-col justify-between w-full sm:flex-row" style="width:100%;">
+    <div class="table-default" style="width:100%;">
+      <el-table :data="tableData" class="w-full mt-3" style="width:100%;">
+        <el-table-column prop="pay_end_at" label="充值时间" />
+        <el-table-column prop="price" label="充值金额">
+        </el-table-column>
+        <el-table-column prop="rechare_coin" label="看币剧数量" />
+        <el-table-column prop="given" label="赠币数量" />
+        <el-table-column prop="pay_name" label="支付方式" />
+        <el-table-column prop="from_page" label="充值来源" />
+      </el-table>
+      <Paginate />
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { useGetList } from '@/hook/curd/useGetList';
+import { useOpen } from '@/hook/curd/useOpen';
+import { FormInstance } from 'element-plus';
+import { tuiguangPromotionAdd } from '@/api/promotion/index'
+const api = 'channel/wechat_min_user/order_list';
+const props = defineProps({
+  primary: Object,
+});
+const { data, query, search, reset, loading } = useGetList(api);
+if (props.primary) {
+  query.value.uid = props.primary.uid
+}
+const tableData = computed(() => data.value?.data);
+
+onMounted(() => {
+  search();
+});
+</script>
+
+<style lang="scss" scoped></style>

+ 16 - 0
src/views/ordersManage/tabs/refundList/excelTitle.ts

@@ -0,0 +1,16 @@
+// 导出中文/字段
+export const titleObj = {
+  所属账户ID: 'advertiser_id',
+  所属账户: 'advertiser_name',
+  订单号: 'order_no',
+  用户ID: 'uid',
+  注册IP: 'user_ranse_ip',
+  注册时间: 'user_ranse_start_at',
+  充值时间: 'order_created_at',
+  充值金额: 'order_price',
+  是否回传: 'filter_type_str',
+  备注: 'filter_reason',
+  回传百分比: 'current_rate',
+  回传配置百分比: 'config_rate',
+  广告计划ID: 'adv_promotion_id'
+};

+ 370 - 0
src/views/ordersManage/tabs/refundList/index.vue

@@ -0,0 +1,370 @@
+<template>
+  <div>
+    <div class="pl-5">
+      <el-radio-group v-model="query.refund_status" @change="search">
+        <el-radio v-for="item in statusListTop" :label="item.value" :key="item.value">{{ item.name }}</el-radio>
+      </el-radio-group>
+    </div>
+    <div class="flex justify-between">
+      <Search :search="search" :reset="resetQuery">
+        <template v-slot:body>
+          <el-form-item label="订单号" prop="trade_no">
+            <el-input v-model="query.trade_no" placeholder="请输入订单号" clearable />
+          </el-form-item>
+          <el-form-item label="用户ID" prop="uid">
+            <el-input v-model="query.uid" placeholder="请输入用户ID" clearable />
+          </el-form-item>
+          <el-form-item label="充值类型" prop="order_type">
+            <el-select v-model="query.order_type" filterable clearable placeholder="选择充值类型">
+              <el-option v-for="item in channelOrderTypeList" :key="item.value" :label="item.name" :value="item.value" />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="推广名称" prop="promotion_id">
+            <el-select v-model="query.promotion_id" filterable remote clearable
+              @change="selectChange($event, 'channelPromotions')"
+              :remote-method="(query) => { remoteMethod(query, 'channelPromotions') }" placeholder="选择推广名称">
+              <el-option v-for="item in channelPromotions" :key="item.promotion_id" :label="item.name"
+                :value="item.promotion_id" />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="小程序" v-if="!query.promotion_id" prop="miniprogram_id">
+            <el-select v-model="query.miniprogram_id" filterable remote
+              @change="selectChange($event, 'channelMiniprogram')"
+              :remote-method="(query) => { remoteMethod(query, 'channelMiniprogram') }" clearable placeholder="选择小程序">
+              <el-option v-for="item in channelMiniprogram" :key="item.miniprogram_id" :label="item.name"
+                :value="item.miniprogram_id" />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="优化师" v-if="!query.promotion_id" prop="user_id">
+            <el-select v-model="query.user_id" filterable remote clearable
+              @change="selectChange($event, 'channelPromotionsUsers')"
+              :remote-method="(query) => { remoteMethod(query, 'channelPromotionsUsers') }" placeholder="选择优化师">
+              <el-option v-for="item in promotionsUsersList" :key="item.user_id" :label="item.name"
+                :value="item.user_id" />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="订单时间">
+            <el-date-picker unlink-panels clearable @change="orderTimeChange" format="YYYY/MM/DD"
+              value-format="YYYY-MM-DD" v-model="query.orderTime" type="daterange" :shortcuts="shortcuts"
+              range-separator="To" start-placeholder="开始时间" end-placeholder="结束时间" />
+          </el-form-item>
+        </template>
+        <template v-slot:extra_button>
+          <exportExcel api="channel/order_list" sheet_name="订单列表" :title_obj="titleObj"
+            :extro_params="{ is_export: true, ...query }">
+          </exportExcel>
+        </template>
+      </Search>
+    </div>
+    <div class="table-default">
+      <el-table :data="tableData" class="mt-3" v-loading="loading">
+        <el-table-column prop="company_name" label="商户名称" min-width="200px">
+          <template #default="scope">
+            <div>{{ scope.row.company_name }}</div>
+            <div>ID:{{ scope.row.puser_id }}</div>
+          </template>
+        </el-table-column>
+        <el-table-column prop="username" label="优化师" show-overflow-tooltip min-width="200px">
+        </el-table-column>
+        <el-table-column prop="play_name" show-overflow-tooltip label="小程序" min-width="200px">
+        </el-table-column>
+        <el-table-column prop="uid" label="用户ID" show-overflow-tooltip>
+        </el-table-column>
+        <el-table-column prop="trade_no" label="订单号" show-overflow-tooltip min-width="200px">
+        </el-table-column>
+        <el-table-column prop="created_at" label="订单时间" show-overflow-tooltip min-width="200px" />
+        <el-table-column prop="ranse_created_at" label="染色注册时间" show-overflow-tooltip min-width="200px" />
+        <el-table-column prop="refund_price" label="申退金额" show-overflow-tooltip min-width="200px" />
+        <el-table-column prop="price" label="充值金额" show-overflow-tooltip>
+        </el-table-column>
+        <el-table-column prop="promotion_title" label="推广名称" show-overflow-tooltip min-width="200px">
+        </el-table-column>
+        <el-table-column prop="tip_text" label="档位类型" show-overflow-tooltip min-width="150px">
+        </el-table-column>
+        <el-table-column prop="pay_name" label="支付方式" show-overflow-tooltip min-width="150px">
+        </el-table-column>
+        <el-table-column prop="status_txt" label="平台审核" show-overflow-tooltip min-width="150px">
+          <template #default="scope">
+            <div class="wrapper">
+              <span class="text-lg font-bold content">
+                <el-text class="mx-1" :type="colorType(scope.row)">{{ scope.row.pt_verify_status_text }}</el-text>
+              </span>
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column prop="pt_verify_remark" label="平台审核备注" show-overflow-tooltip min-width="150px">
+        </el-table-column>
+        <el-table-column prop="status_txt" label="商户审核" show-overflow-tooltip min-width="150px">
+          <template #default="scope">
+            <div class="wrapper">
+              <span class="text-lg font-bold content">
+                <el-text class="mx-1" :type="colorType(scope.row)">{{ scope.row.sh_verify_status_text }}</el-text>
+              </span>
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column prop="sh_verify_remark" label="商户审核备注" show-overflow-tooltip min-width="150px">
+        </el-table-column>
+        <el-table-column label="操作">
+          <template #default="scope">
+            <el-button link type="primary" size="small"
+              @click="openType('noapprovedVisible', scope.row, '平台审核')">平台审核</el-button>
+            <br />
+            <el-button link type="primary" size="small"
+              @click="openType('noapprovedVisible', scope.row, '商户审核')">商户审核</el-button>
+            <br />
+            <el-button link type="primary" size="small" @click="openType('approvedVisible', scope.row)">确认打款</el-button>
+            <br />
+          </template>
+        </el-table-column>
+      </el-table>
+      <Paginate />
+    </div>
+    <el-dialog width="500px" v-model="noapprovedVisible" :title="titleDialog" destroy-on-close @close="noapprovedClose">
+      <el-form :model="form" label-width="120px">
+        <el-form-item label="审核结果">
+          <el-radio-group v-model="form.status" @change="search">
+            <el-radio v-for="item in statusList" :label="item.value" :key="item.value">{{ item.name }}</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="备注">
+          <el-input v-model="form.remark" :rows="3" type="textarea" placeholder="请输入内容" autocomplete="off" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="noapprovedClose">取消</el-button>
+          <el-button type="primary" @click="noapproveChange">
+            确认
+          </el-button>
+        </span>
+      </template>
+    </el-dialog>
+  </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 { titleObj } from "./excelTitle"
+import {
+  channelOrderList,
+  channelMiniprogramUseList,
+  channelPromotionsOptions,
+  channelPromotionsUsers,
+  channelOrderStatus,
+  channelOrderType,
+} from '@/api/orders/index'
+
+import { orderRefundVerifyPt, orderRefundVerifySh, orderRefundPayToUser } from '@/api/orders/index'
+import moment from 'moment';
+const form = ref({ status: 1 })
+const start_date = moment().startOf('month').format('YYYY-MM-DD')
+const end_date = moment().endOf('month').format('YYYY-MM-DD')
+const statusList = ref([
+  { name: '审核通过', value: 1 },
+  { name: '审核不通过', value: 2 },
+])
+const statusListTop = ref([
+  { name: '待审核', value: 0 },
+  { name: '已退款', value: 1 },
+])
+const api = 'orderRefund/order_list';
+const router = useRouter()
+const route = useRoute()
+const approvedVisible = ref(false)
+const noapprovedVisible = ref(false)
+const { data, query, search, reset, loading } = useGetList(api);
+const titleDialog = ref('')
+const current = ref({})
+const promotionsUsersList = ref([])
+const channelMiniprogram = ref([])
+const channelPromotions = ref([])
+const channelOrderStatusList = ref([])
+const channelOrderTypeList = ref([])
+const rolesIdentify = inject('rolesIdentify')
+
+const colorType = (data: object) => {
+  const type = data.pt_verify_status || data.sh_verify_status
+  switch (type) {
+    case 0:
+      return 'warning'
+    case 1:
+      return 'success'
+    case 2:
+      return 'danger'
+  }
+}
+const noapprovedClose = () => {
+  form.value = { status: 1 };
+  noapprovedVisible.value = false;
+}
+
+const noapproveChange = () => {
+  let api;
+  if (titleDialog.value == '平台审核') {
+    api = orderRefundVerifyPt
+  } else if (titleDialog.value == '商户审核') {
+    api = orderRefundVerifySh
+  }
+  api({ refund_id: current.value.id, ...form.value }).then(res => {
+    console.log(res, 'apiapiapiapi');
+    ElMessage.success(res.message)
+    search()
+  })
+}
+
+const openType = (type: string, data?: object, title?: string) => {
+  current.value = data || {}
+  switch (type) {
+    case 'approvedVisible':
+      ElMessageBox.confirm(
+        '确认打款吗?',
+        '提示',
+        {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning',
+        }
+      )
+        .then(() => {
+          orderRefundPayToUser({ refund_id: current.value.id }).then(res => {
+            ElMessage.success(res.message)
+            search()
+          })
+        })
+        .catch(() => {
+
+        })
+      break;
+    case 'noapprovedVisible':
+      titleDialog.value = title || ''
+      noapprovedVisible.value = true
+      break;
+  }
+}
+
+const orderTimeChange = (e: object) => {
+  console.log(e, 'timeChangetimeChangetimeChange');
+  if (query.value.orderTime) {
+    const timeArr = toRaw(e);
+    query.value.created_at_start = timeArr[0]
+    query.value.created_at_end = timeArr[1]
+  } else {
+    delete query.value.created_at_start
+    delete query.value.created_at_end
+  }
+}
+
+const selectChange = (e: object, type: string,) => {
+  console.log(e, 'queryquery', type);
+  if (e) {
+    switch (type) {
+      case 'channelPromotionsUsers':
+        query.value.miniprogram_id = ''
+        query.value.promotion_id = ''
+        initRemoteOption('channelPromotions', { name: '', user_id: e })
+        initRemoteOption('channelMiniprogram', { name: '', user_id: e })
+        break;
+      case 'channelMiniprogram':
+        query.value.user_id = ''
+        query.value.promotion_id = ''
+        initRemoteOption('channelMiniprogram', { name: '' })
+        initRemoteOption('channelPromotionsUsers', { name: '', miniprogram_id: e })
+        initRemoteOption('channelPromotions', { name: '', miniprogram_id: e })
+        break;
+      case 'channelPromotions':
+        // initRemoteOption('channelPromotions', { name: query })
+        break;
+    }
+  }
+}
+const remoteMethod = (query: string, type: string,) => {
+  console.log(query, 'queryquery', type);
+  if (query) {
+    switch (type) {
+      case 'channelPromotionsUsers':
+        initRemoteOption('channelPromotionsUsers', { name: query })
+        break;
+      case 'channelMiniprogram':
+        initRemoteOption('channelMiniprogram', { name: query })
+        break;
+      case 'channelPromotions':
+        initRemoteOption('channelPromotions', { name: query })
+        break;
+    }
+  }
+}
+
+const initRemoteOption = (type: string, params?: object) => {
+  switch (type) {
+    case 'channelPromotionsUsers':
+      channelPromotionsUsers({ limit: 30, ...params }).then(res => {
+        promotionsUsersList.value = res.data
+      })
+      break;
+    case 'channelMiniprogram':
+      channelMiniprogramUseList({ limit: 30, ...params }).then(res => {
+        channelMiniprogram.value = res.data
+      })
+      break;
+    case 'channelPromotions':
+      channelPromotionsOptions({ limit: 30, ...params }).then(res => {
+        channelPromotions.value = res.data
+      })
+      break;
+  }
+}
+
+const init = () => {
+  channelOrderStatus().then(res => {
+    console.log(res);
+    channelOrderStatusList.value = res.data
+  })
+  channelOrderType().then(res => {
+    console.log(res);
+    channelOrderTypeList.value = res.data
+  })
+}
+
+const resetQuery = () => {
+  query.value = Object.assign({ page: query.value.page, limit: query.value.limit, refund_status: 0 });
+  search()
+}
+const tableData = computed(() => data.value?.data);
+
+onMounted(() => {
+  console.log(rolesIdentify, 'rolesIdentifyrolesIdentify');
+  initRemoteOption('channelPromotionsUsers')
+  initRemoteOption('channelMiniprogram')
+  initRemoteOption('channelPromotions')
+  init()
+  query.value.refund_status = 0;
+  search();
+});
+</script>
+
+<style scoped lang="scss">
+.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>

+ 4 - 4
src/views/promotion/promotionList/index.vue

@@ -54,7 +54,7 @@
                   <div class="flex items-center">
                     <span>推广链接</span>
                     <el-tooltip placement="top">
-                      <template #content>鼠标移动到【复制】文字,进行查看链接,点击移动【复制】文字,进行复制链接</template>
+                      <template #content>鼠标移动到【点击复制】文字,进行查看链接,点击,进行复制链接</template>
                       <el-icon>
                         <InfoFilled />
                       </el-icon>
@@ -67,7 +67,7 @@
                       :content="scope.row.promotion_path">
                       <template #reference>
                         <copy-button :text="scope.row.promotion_path">
-                          <el-link :underline="false">复制</el-link>
+                          <el-link :underline="false">点击复制</el-link>
                         </copy-button>
                       </template>
                     </el-popover>
@@ -79,7 +79,7 @@
                   <div class="flex items-center">
                     <span>监测链接</span>
                     <el-tooltip placement="top">
-                      <template #content>鼠标移动到【复制】文字,进行查看链接,点击移动【复制】文字,进行复制链接</template>
+                      <template #content>鼠标移动到【点击复制】文字,进行查看链接,点击,进行复制链接</template>
                       <el-icon>
                         <InfoFilled />
                       </el-icon>
@@ -92,7 +92,7 @@
                       :content="scope.row.track_url">
                       <template #reference>
                         <copy-button :text="scope.row.track_url">
-                          <el-link :underline="false">复制</el-link>
+                          <el-link :underline="false">点击复制</el-link>
                         </copy-button>
                       </template>
                     </el-popover>

+ 28 - 0
src/views/settleManage/financialControl/index.vue

@@ -0,0 +1,28 @@
+<template>
+  <div>
+    <el-card shadow="always" :body-style="{ padding: '20px' }">
+      <el-tabs v-model="activeName" class="demo-tabs" @tab-change="handChange">
+        <el-tab-pane label="对公审核" name="recharge">
+          <rechargeSettle></rechargeSettle>
+        </el-tab-pane>
+      </el-tabs>
+    </el-card>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { useRouter, useRoute } from 'vue-router'
+import type { TabsPaneContext } from 'element-plus'
+import rechargeSettle from "./tabs/rechargeSettle/index.vue"
+const router = useRouter()
+const route = useRoute()
+const handChange = (tab: TabsPaneContext, event: Event) => {
+  activeName.value = tab
+}
+const activeName = ref('recharge')
+onMounted(() => {
+  activeName.value = route.query.tab || 'recharge'
+});
+</script>
+
+<style scoped lang="scss"></style>

+ 8 - 0
src/views/settleManage/financialControl/tabs/rechargeSettle/excelTitle.ts

@@ -0,0 +1,8 @@
+// 导出中文/字段
+export const titleObj = {
+  时间: 'jiesuan_date',
+  日充值总额: 'charge_money',
+  当日退款: 'tuikuan_money',
+  分成比例: 'share_rate',
+  日结算总额: 'jiesuan_money'
+};

+ 112 - 0
src/views/settleManage/financialControl/tabs/rechargeSettle/form/create.vue

@@ -0,0 +1,112 @@
+<template>
+  <div class="withdraw-popup-warn">
+    提现提示1:工作日14:30点前提现,审核通过之后下一工作日可到账;14:30之后提现将会在下一工作日审核<br />
+    提现提示2:充值收入提现后,请自行到当地税务部门纳税,本平台仅收取10%平台服务费,不承担代扣代缴义务。
+  </div>
+  <el-form :model="formData" label-width="120px" ref="ruleForm" :rules="rules" v-loading="loading" class="pr-4">
+    <div class="flex flex-row justify-between">
+      <div class="w-full">
+        <el-form-item label="可提现金额" prop="name">
+          <el-input v-model="props.primary.yue_money" disabled placeholder="请输入商户名称" />
+        </el-form-item>
+        <el-form-item label="提现金额" prop="tixian_money">
+          <div class="items-center w-full">
+            <el-input style="width:200px;margin:0 5px;" v-model="formData.tixian_money" placeholder="请输入金额">
+              <template #append>元</template>
+            </el-input>
+            <span v-if="Number(props.primary.yue_money) > 0" class="text-blue-400 cursor-pointer"
+              @click="formData.tixian_money = props.primary.yue_money">全部提现</span>
+          </div>
+        </el-form-item>
+        <el-form-item label="提现账户" prop="bank_card_id">
+          <el-select class="w-full" v-model="formData.bank_card_id" filterable clearable placeholder="选择提现账户">
+            <el-option v-for="item in applyBank" :key="item.value" :label="item.label" :value="item.value" />
+          </el-select>
+        </el-form-item>
+      </div>
+    </div>
+    <div class="flex justify-end">
+      <el-button type="primary" @click="submitForm(ruleForm)">{{ $t('system.confirm') }}</el-button>
+    </div>
+  </el-form>
+</template>
+
+<script lang="ts" setup>
+import { useCreate } from '@/hook/curd/useCreate';
+import { useShow } from '@/hook/curd/useShow';
+import type { FormInstance, FormRules } from 'element-plus'
+import { jiesuanManageBankAccountListAvailableBankCard, jiesuanManageJiesuanTixian } from '@/api/settlement/index'
+const ruleForm = ref<FormInstance>()
+import { onMounted, ref } from 'vue';
+const props = defineProps({
+  primary: Object,
+});
+const formData = ref({})
+const rules = reactive({
+  bank_card_id: [{ required: true, message: '请选择提现账户' }],
+  tixian_money: [
+    {
+      required: true,
+      message: '请输入金额',
+      trigger: 'blur'
+    },
+    { pattern: /^\d+(\.\d{1,2})?$/, message: '金额最多只能有两位小数', trigger: 'blur' },
+    { pattern: /^(?!0\d+)\d+(\.\d+)?$/, message: '请输入有效的金额', trigger: 'blur' },
+    {
+      pattern: /^500(\.\d{1,2})?$|^([5-9]\d{2}|[1-9]\d{3,})(\.\d{1,2})?$/,
+      message: '请输入不低于500的金额',
+      // trigger: 'blur'
+    }
+  ],
+});
+const loading = ref(false)
+const applyBank = ref([])
+
+const submitForm = (formEl: FormInstance | undefined) => {
+  console.log(formData.value, 'formData.valueformData.value');
+  if (!formEl) return;
+  formEl
+    .validate(valid => {
+      if (valid) {
+        jiesuanManageJiesuanTixian(formData.value).then(res => {
+          ElMessage.success(res.message)
+          emit('close')
+          loading.value = false;
+        })
+      } else {
+        loading.value = false;
+      }
+    })
+    .then(() => { });
+}
+
+if (props.primary) {
+  console.log(props.primary, 'props.primaryprops.primary');
+}
+
+const emit = defineEmits(['close']);
+onMounted(() => {
+  jiesuanManageBankAccountListAvailableBankCard().then(res => {
+    applyBank.value = res.data;
+    applyBank.value = res.data.map(v => {
+      return {
+        label: `${v.bank_name}(***********${v.card_no.slice(-4)})`,
+        value: v.id,
+      };
+    });;
+  })
+
+});
+</script>
+
+<style lang="scss" scoped>
+.withdraw-popup-warn {
+  padding: 10px;
+  color: red;
+  margin-bottom: 10px;
+  line-height: 1.8;
+  padding-left: 30px;
+  font-size: 12px;
+  background-color: #ffecf4;
+}
+</style>

+ 258 - 0
src/views/settleManage/financialControl/tabs/rechargeSettle/index.vue

@@ -0,0 +1,258 @@
+<template>
+  <div>
+    <el-radio-group v-model="query.status" @change="search">
+      <el-radio v-for="item in statusList" :label="item.value" :key="item.value">{{ item.name }}</el-radio>
+    </el-radio-group>
+    <Search :search="search" :reset="resetQuery">
+      <template v-slot:body>
+        <el-form-item label="所属商务" prop="business_id">
+          <el-select v-model="query.business_id" filterable clearable placeholder="选择所属商务">
+            <el-option v-for="item in businessList" :key="item.id" :label="item.username" :value="item.id" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="提现时间">
+          <el-date-picker unlink-panels clearable @change="createTimeChange" format="YYYY/MM/DD" value-format="YYYY-MM-DD"
+            v-model="query.createTime" type="daterange" :shortcuts="shortcuts" range-separator="To"
+            start-placeholder="开始时间" end-placeholder="结束时间" />
+        </el-form-item>
+      </template>
+    </Search>
+    <div class="table-default">
+      <Operate :show="open" />
+      <el-table :data="tableData" class="mt-3" v-loading="loading">
+        <el-table-column prop="owner_name" label="商户名称" min-width="200px">
+          <template #default="scope">
+            <div>{{ scope.row.owner_name }}</div>
+            <div>ID:{{ scope.row.company_uid }}</div>
+          </template>
+        </el-table-column>
+        <el-table-column prop="business_str" show-overflow-tooltip label="所属商务" min-width="200px">
+        </el-table-column>
+        <el-table-column prop="tixian_money" label="提现金额" show-overflow-tooltip min-width="200px">
+        </el-table-column>
+        <el-table-column prop="tixian_money" label="打款金额" show-overflow-tooltip min-width="200px">
+        </el-table-column>
+        <el-table-column prop="created_at" show-overflow-tooltip label="提现时间" min-width="200px">
+        </el-table-column>
+        <el-table-column prop="card_no" label="提现账户" show-overflow-tooltip>
+        </el-table-column>
+        <el-table-column prop="status_str" label="状态" show-overflow-tooltip min-width="200px">
+          <template #default="scope">
+            <el-text class="mx-1" :type="colorType(scope.row)">{{ scope.row.status_str }}</el-text>
+          </template>
+        </el-table-column>
+        <el-table-column prop="name_of_payee" label="收款人姓名" show-overflow-tooltip min-width="200px">
+        </el-table-column>
+        <el-table-column prop="remark" label="审核备注" show-overflow-tooltip>
+        </el-table-column>
+        <el-table-column label="操作">
+          <template #default="scope">
+            <el-button link type="primary" size="small"
+              @click="openType('withdrawDetailVisible', scope.row)">提现详情</el-button>
+            <br />
+            <el-button link type="primary" size="small" @click="openType('approvedVisible', scope.row)">审核通过</el-button>
+            <br />
+            <el-button link type="primary" size="small"
+              @click="openType('noapprovedVisible', scope.row)">审核不通过</el-button>
+            <br />
+          </template>
+        </el-table-column>
+      </el-table>
+      <Paginate />
+    </div>
+    <Dialog v-model="withdrawDetailVisible" width="80%" title="提现详情" destroy-on-close>
+      <withdrawDetail @close="closeType('withdrawDetailVisible')" :primary="withdrawDetailData"></withdrawDetail>
+    </Dialog>
+    <el-dialog width="500px" v-model="noapprovedVisible" title="审核不通过" destroy-on-close>
+      <el-form :model="form" label-width="120px">
+        <el-form-item label="备注">
+          <el-input v-model="form.status" :rows="3" type="textarea" placeholder="请输入内容" autocomplete="off" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="noapprovedVisible = false">取消</el-button>
+          <el-button type="primary" @click="noapproveChange">
+            确认
+          </el-button>
+        </span>
+      </template>
+    </el-dialog>
+  </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 { useOpen } from '@/hook/curd/useOpen';
+import { jiesuanManageJiesuanAccountInfo, jiesuanManageBankAccountListShangwu, jiesuanManageFinanceCheckCheck } from '@/api/settlement/index'
+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 { open, close, title, visible, id } = useOpen();
+const api = 'jiesuanManage/financeCheck/list';
+const router = useRouter()
+const route = useRoute()
+import withdrawDetail from './withdrawDetail/index.vue'
+const statusList = ref([
+  { name: '待审核', value: 1 },
+  { name: '审核失败', value: 2 },
+  { name: '待打款', value: 3 },
+  { name: '已打款', value: 4 },
+  { name: '打款失败', value: 5 },
+])
+const { data, query, search, reset, loading } = useGetList(api);
+const dialogFormVisible = ref(false)
+const userDetailData = ref({})
+const current = ref({})
+const form = ref({})
+const businessList = ref([])
+const rolesIdentify = inject('rolesIdentify')
+const withdrawDetailVisible = ref(false)
+const withdrawDetailData = ref({})
+const applyData = ref({})
+const approvedVisible = ref(false)
+const noapprovedVisible = ref(false)
+
+const colorType = (data: object) => {
+  const type = data.status
+  switch (type) {
+    case 4:
+      return 'success'
+    case 1:
+      return 'warning'
+    case 3:
+      return 'warning'
+    case 5:
+      return 'danger'
+    case 2:
+      return 'danger'
+  }
+}
+
+const noapproveChange = () => {
+  jiesuanManageFinanceCheckCheck({ id: current.value.id, status: 2 }).then(res => {
+    console.log(res, 'jiesuanManageFinanceCheckCheck');
+    ElMessage.success(res.message)
+    search()
+  })
+}
+
+const createTimeChange = (e: object) => {
+  console.log(e, 'timeChangetimeChangetimeChange');
+  if (query.value.createTime) {
+    const timeArr = toRaw(e);
+    query.value.tixian_start_at = timeArr[0]
+    query.value.tixian_end_at = timeArr[1]
+  } else {
+    delete query.value.tixian_start_at
+    delete query.value.tixian_end_at
+  }
+}
+
+const resetQuery = () => {
+  query.value.status = 1
+  query.value.business_id = ''
+  query.value.createTime = ''
+  delete query.value.tixian_start_at
+  delete query.value.tixian_end_at
+  search()
+}
+const closeType = (type: string) => {
+  switch (type) {
+    case 'withdrawDetailVisible':
+      withdrawDetailVisible.value = false
+      break;
+    case 'approvedVisible':
+      approvedVisible.value = false
+      break;
+    case 'noapprovedVisible':
+      noapprovedVisible.value = false
+      break;
+  }
+  search()
+}
+
+const openType = (type: string, data?: object) => {
+  current.value = data || {}
+  switch (type) {
+    case 'withdrawDetailVisible':
+      withdrawDetailVisible.value = true
+      withdrawDetailData.value = data || {}
+      break;
+    case 'approvedVisible':
+      ElMessageBox.confirm(
+        '确认审核通过吗?',
+        '提示',
+        {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning',
+        }
+      )
+        .then(() => {
+          jiesuanManageFinanceCheckCheck({ id: current.value, status: 3 }).then(res => {
+            console.log(res, 'jiesuanManageFinanceCheckCheck');
+            ElMessage.success(res.message)
+            search()
+          })
+        })
+        .catch(() => {
+
+        })
+      break;
+    case 'noapprovedVisible':
+      noapprovedVisible.value = true
+      break;
+  }
+}
+const tableData = computed(() => data.value?.data);
+
+onMounted(() => {
+  query.value.status = 1
+  jiesuanManageBankAccountListShangwu().then(res => {
+    businessList.value = res.data;
+    console.log(res, 'jiesuanManageJiesuanAccountInfo');
+  })
+  console.log(rolesIdentify, 'rolesIdentifyrolesIdentify');
+  search();
+});
+</script>
+
+<style scoped lang="scss">
+.col {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  flex-direction: column;
+  height: 100px;
+  width: 25%;
+}
+
+.col:last-child {
+  align-items: start;
+}
+
+.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>

+ 108 - 0
src/views/settleManage/financialControl/tabs/rechargeSettle/withdrawDetail/index.vue

@@ -0,0 +1,108 @@
+<template>
+  <el-card shadow="always" :body-style="{ padding: '20px' }">
+    <el-row :gutter="20">
+      <el-col :span="6" class="col">
+        <div class="text-lg text-red-500">
+          ¥{{ applyData.yue_money }}
+        </div>
+        <div class="text-base">
+          账户余额
+        </div>
+      </el-col>
+      <el-col :span="6" class="col">
+        <div class="text-lg text-green-500">
+          ¥{{ applyData.tixian_money }}
+        </div>
+        <div class="text-base">
+          审核中
+        </div>
+      </el-col>
+      <el-col :span="6" class="col">
+        <div class="text-lg text-red-300">
+          ¥{{ applyData.total_dakuan }}
+        </div>
+        <div class="text-base">
+          已打款
+        </div>
+      </el-col>
+    </el-row>
+  </el-card>
+  <div class="p-5">注:每日的结算数据需要在次日统计完成后才能展示</div>
+  <el-tabs v-model="activeName" @tab-change="handChange">
+    <el-tab-pane label="结算明细" name="readLog">
+      <settleInfo :primary="props.primary"></settleInfo>
+    </el-tab-pane>
+    <el-tab-pane label="提现记录" name="recharge">
+      <withdrawalRecord :primary="props.primary"></withdrawalRecord>
+    </el-tab-pane>
+  </el-tabs>
+</template>
+
+<script lang="ts" setup>
+import settleInfo from './tables/settleInfo/index.vue'
+import withdrawalRecord from './tables/withdrawalRecord/index.vue'
+import { jiesuanManageFinanceCheckGetShanghuAccountInfo } from '@/api/settlement/index'
+import { ref } from 'vue'
+import type { TabsPaneContext } from 'element-plus'
+const props = defineProps({
+  primary: Object,
+});
+const activeName = ref('readLog')
+
+const handChange = (tab: TabsPaneContext, event: Event) => {
+  activeName.value = tab
+}
+
+const applyData = ref({})
+
+if (props.primary) {
+  console.log(props.primary.company_uid, 'jiesuanManageFinanceCheckGetShanghuAccountInfojiesuanManageFinanceCheckGetShanghuAccountInfo');
+  jiesuanManageFinanceCheckGetShanghuAccountInfo({ company_uid: props.primary.company_uid }).then(res => {
+    console.log(res, 'applyDataapplyDataapplyData');
+    applyData.value = res.data
+  })
+}
+
+onMounted(() => {
+})
+
+</script>
+
+<style lang="scss" scoped>
+.col {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  flex-direction: column;
+  height: 100px;
+  margin: 0 auto;
+  width: 33.33%;
+}
+
+.wrapper {
+  display: flex;
+  flex-direction: column;
+  align-items: flex-start;
+  justify-content: center;
+  width: 100%;
+
+  .row {
+    width: 100%;
+    display: flex;
+
+    .item {
+      margin: 9px;
+
+      .label {
+        font-size: 16px;
+      }
+
+      .content {
+        font-size: 18px;
+        font-weight: 600;
+      }
+    }
+  }
+
+}
+</style>

+ 11 - 0
src/views/settleManage/financialControl/tabs/rechargeSettle/withdrawDetail/tables/settleInfo/excelTitle.ts

@@ -0,0 +1,11 @@
+// 导出中文/字段
+export const titleObj = {
+  提现时间: 'created_at',
+  提现金额: 'tixian_money',
+  提现账户: 'card_no',
+  收款人姓名: 'name_of_payee',
+  支付通道: 'pay_channel',
+  银行流水: 'pay_no',
+  审核状态: 'status_str',
+  备注: 'remark'
+};

+ 106 - 0
src/views/settleManage/financialControl/tabs/rechargeSettle/withdrawDetail/tables/settleInfo/index.vue

@@ -0,0 +1,106 @@
+<template>
+  <div>
+    <Search :search="search" :reset="resetQuery">
+      <template v-slot:body>
+        <el-form-item label="结算时间">
+          <el-date-picker unlink-panels clearable @change="createTimeChange" format="YYYY/MM/DD" value-format="YYYY-MM-DD"
+            v-model="query.createTime" type="daterange" :shortcuts="shortcuts" range-separator="To"
+            start-placeholder="开始时间" end-placeholder="结束时间" />
+        </el-form-item>
+      </template>
+      <template v-slot:extra_button>
+        <exportExcel api="jiesuanManage/jiesuan/list" sheet_name="结算明细" :title_obj="titleObj"
+          :extro_params="{ is_export: 1, ...query }">
+        </exportExcel>
+      </template>
+    </Search>
+    <div class="table-default">
+      <el-table :data="tableData" class="mt-3" v-loading="loading">
+        <el-table-column prop="jiesuan_date" label="时间" min-width="200px" />
+        <el-table-column prop="charge_money" show-overflow-tooltip label="日充值总额" min-width="200px">
+        </el-table-column>
+        <el-table-column prop="tuikuan_money" label="当日退款" show-overflow-tooltip>
+        </el-table-column>
+        <el-table-column prop="share_rate" label="分成比例" show-overflow-tooltip>
+        </el-table-column>
+        <el-table-column prop="jiesuan_money" label="日结算总额" show-overflow-tooltip min-width="200px">
+        </el-table-column>
+      </el-table>
+      <Paginate />
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { shortcuts } from '@/utils/shortcuts'
+import { useGetList } from '@/hook/curd/useGetList';
+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 api = 'jiesuanManage/jiesuan/list';
+const props = defineProps({
+  primary: Object,
+});
+const { data, query, search, reset, loading } = useGetList(api);
+
+const createTimeChange = (e: object) => {
+  console.log(e, 'timeChangetimeChangetimeChange');
+  if (query.value.createTime) {
+    const timeArr = toRaw(e);
+    query.value.jiesuan_date_start_at = timeArr[0]
+    query.value.jiesuan_date_end_at = timeArr[1]
+  } else {
+    delete query.value.jiesuan_date_start_at
+    delete query.value.jiesuan_date_end_at
+  }
+}
+
+const resetQuery = () => {
+  reset()
+}
+const tableData = computed(() => data.value?.data);
+
+if (props.primary) {
+  console.log(props.primary, 'props.primaryprops.primary');
+  query.value.company_uid = props.primary.company_uid
+}
+onMounted(() => {
+  search();
+});
+</script>
+
+<style scoped lang="scss">
+.col {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  flex-direction: column;
+  height: 100px;
+  width: 25%;
+}
+
+.col:last-child {
+  align-items: start;
+}
+
+.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>

+ 11 - 0
src/views/settleManage/financialControl/tabs/rechargeSettle/withdrawDetail/tables/withdrawalRecord/excelTitle.ts

@@ -0,0 +1,11 @@
+// 导出中文/字段
+export const titleObj = {
+  提现时间: 'created_at',
+  提现金额: 'tixian_money',
+  提现账户: 'card_no',
+  收款人姓名: 'name_of_payee',
+  支付通道: 'pay_channel',
+  银行流水: 'pay_no',
+  审核状态: 'status_str',
+  备注: 'remark'
+};

+ 129 - 0
src/views/settleManage/financialControl/tabs/rechargeSettle/withdrawDetail/tables/withdrawalRecord/index.vue

@@ -0,0 +1,129 @@
+<template>
+  <div>
+    <div class="pl-5">
+      <el-radio-group v-model="query.status" @change="search">
+        <el-radio v-for="item in statusList" :label="item.value" :key="item.value">{{ item.name }}</el-radio>
+      </el-radio-group>
+    </div>
+    <div class="flex justify-between">
+      <Search :search="search" :reset="resetQuery">
+        <template v-slot:body>
+          <el-form-item label="申请时间">
+            <el-date-picker unlink-panels clearable @change="createTimeChange" format="YYYY/MM/DD"
+              value-format="YYYY-MM-DD" v-model="query.createTime" type="daterange" :shortcuts="shortcuts"
+              range-separator="To" start-placeholder="开始时间" end-placeholder="结束时间" />
+          </el-form-item>
+        </template>
+        <template v-slot:extra_button>
+          <exportExcel api="jiesuanManage/jiesuan/listTixian" sheet_name="提现记录" :title_obj="titleObj"
+            :extro_params="{ is_export: 1, ...query }">
+          </exportExcel>
+        </template>
+      </Search>
+    </div>
+    <div class="table-default">
+      <el-table :data="tableData" class="mt-3" v-loading="loading">
+        <el-table-column prop="created_at" label="提现时间" min-width="200px" />
+        <el-table-column prop="tixian_money" label="提现金额" show-overflow-tooltip min-width="200px">
+        </el-table-column>
+        <el-table-column prop="card_no" show-overflow-tooltip label="提现账户" min-width="200px">
+        </el-table-column>
+        <el-table-column prop="name_of_payee" label="收款人姓名" min-width="200px" show-overflow-tooltip>
+        </el-table-column>
+        <el-table-column prop="pay_channel" label="支付通道" show-overflow-tooltip min-width="200px">
+        </el-table-column>
+        <el-table-column prop="pay_no" label="银行流水" show-overflow-tooltip min-width="200px" />
+        <el-table-column prop="status_str" label="审核状态" show-overflow-tooltip min-width="150px">
+          <template #default="scope">
+            <div class="wrapper">
+              <span class="text-lg font-bold content">
+                <el-text class="mx-1" :type="colorType(scope.row)">{{ scope.row.status_str }}</el-text>
+              </span>
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column prop="remark" label="备注" show-overflow-tooltip min-width="150px">
+        </el-table-column>
+      </el-table>
+      <Paginate />
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { InfoFilled } from '@element-plus/icons-vue';
+import { useGetList } from '@/hook/curd/useGetList';
+const api = 'jiesuanManage/jiesuan/listTixian';
+import { titleObj } from "./excelTitle"
+const { data, query, search, reset, loading } = useGetList(api);
+const rolesIdentify = inject('rolesIdentify')
+const props = defineProps({
+  primary: Object,
+});
+const statusList = ref([
+  { name: '全部', value: '' },
+  { name: '待审核', value: 1 },
+  { name: '审核失败', value: 2 },
+  { name: '待打款', value: 3 },
+  { name: '已打款', value: 4 },
+  { name: '打款失败', value: 5 },
+])
+const colorType = (data: object) => {
+  const type = data.status
+  switch (type) {
+    case 4:
+      return 'success'
+    case 3:
+      return 'warning'
+    case 1:
+      return 'warning'
+    case 2:
+      return 'danger'
+    case 5:
+      return 'danger'
+  }
+}
+const createTimeChange = (e: object) => {
+  console.log(e, 'timeChangetimeChangetimeChange');
+  if (query.value.createTime) {
+    const timeArr = toRaw(e);
+    query.value.tixian_start_at = timeArr[0]
+    query.value.tixian_end_at = timeArr[1]
+  } else {
+    delete query.value.tixian_start_at
+    delete query.value.tixian_end_at
+  }
+}
+const resetQuery = () => {
+  reset()
+}
+
+const tableData = computed(() => data.value?.data);
+
+onMounted(() => {
+  search();
+});
+</script>
+
+<style scoped lang="scss">
+.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>

+ 32 - 0
src/views/settleManage/paymentAccountInfo/index.vue

@@ -0,0 +1,32 @@
+<template>
+  <div>
+    <el-card shadow="always" :body-style="{ padding: '20px' }">
+      <el-tabs v-model="activeName" class="demo-tabs" @tab-change="handChange">
+        <el-tab-pane label="收款账户信息" name="payment">
+          <paymentInfo></paymentInfo>
+        </el-tab-pane>
+        <el-tab-pane label="合作信息" name="cooperate">
+          <cooperate></cooperate>
+        </el-tab-pane>
+      </el-tabs>
+    </el-card>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { useRouter, useRoute } from 'vue-router'
+import type { TabsPaneContext } from 'element-plus'
+import paymentInfo from "./tabs/paymentInfo/index.vue"
+import cooperate from "./tabs/cooperate/index.vue"
+const router = useRouter()
+const route = useRoute()
+const handChange = (tab: TabsPaneContext, event: Event) => {
+  activeName.value = tab
+}
+const activeName = ref('payment')
+onMounted(() => {
+  activeName.value = route.query.tab || 'payment'
+});
+</script>
+
+<style scoped lang="scss"></style>

+ 28 - 0
src/views/settleManage/paymentAccountInfo/tabs/cooperate/index.vue

@@ -0,0 +1,28 @@
+<template>
+  <div>
+    <div class="withdraw-popup-warn">
+      分成比例:{{ cooperateInfo.share_rate }}
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { jiesuanManageBankAccountHezuoInfo } from '@/api/settlement/index'
+const cooperateInfo = ref({})
+onMounted(() => {
+  jiesuanManageBankAccountHezuoInfo().then(res => {
+    cooperateInfo.value = res.data;
+  })
+});
+</script>
+
+<style scoped lang="scss">
+.withdraw-popup-warn {
+  padding: 10px;
+  font-weight: 600;
+  margin-bottom: 10px;
+  line-height: 5;
+  padding-left: 30px;
+  font-size: 18px;
+}
+</style>

+ 132 - 0
src/views/settleManage/paymentAccountInfo/tabs/paymentInfo/form/create.vue

@@ -0,0 +1,132 @@
+<template>
+  <div>
+    <div class="mb-3 ml-5">
+      <el-alert title="注:结算金额会打入您预留的银行卡中,请仔细核对账户信息" type="error" :closable="false" effect="dark" />
+    </div>
+    <el-form :model="formData" label-width="120px" ref="ruleForm" :rules="rules" v-loading="loading" class="pr-4">
+      <div class="flex flex-row justify-between">
+        <div class="w-full">
+          <el-form-item label="商户名称" prop="owner_name">
+            <el-input v-model="formData.owner_name" placeholder="请输入商户名称" />
+          </el-form-item>
+          <el-form-item label="收款人" prop="name_of_payee">
+            <el-input v-model="formData.name_of_payee" placeholder="请输入收款人" />
+          </el-form-item>
+          <el-form-item label="银行卡号" prop="card_no">
+            <el-input v-model="formData.card_no" clearable size="large" placeholder="请输入银行卡号" />
+          </el-form-item>
+          <el-form-item label="开户银行" prop="bank_name">
+            <el-select class="w-full" v-model="formData.bank_name" filterable clearable placeholder="选择开户银行">
+              <el-option v-for="item in bankList" :key="item.id" :label="item.name" :value="item.name" />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="开户支行" prop="sub_bank_name">
+            <el-input v-model="formData.sub_bank_name" clearable size="large" placeholder="请输入开户支行" />
+          </el-form-item>
+          <el-form-item label="收款人手机号" prop="phone_of_payee">
+            <el-input v-model="formData.phone_of_payee" clearable size="large" placeholder="请输入收款人手机号" />
+          </el-form-item>
+          <el-form-item label="所属商务" prop="business_id">
+            <el-select v-model="formData.business_id" filterable clearable placeholder="选择所属商务">
+              <el-option v-for="item in businessList" :key="item.id" :label="item.username" :value="item.id" />
+            </el-select>
+          </el-form-item>
+        </div>
+      </div>
+      <div class="flex justify-end">
+        <el-button type="primary" @click="submitForm(ruleForm)">{{ $t('system.confirm') }}</el-button>
+      </div>
+    </el-form>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import type { FormInstance, FormRules } from 'element-plus'
+import { jiesuanManageBankAccountListBank, jiesuanManageBankAccountListShangwu, jiesuanManageBankAccountAddCompanyCard } from '@/api/settlement/index'
+const ruleForm = ref<FormInstance>()
+import { onMounted, ref } from 'vue';
+const props = defineProps({
+  primary: Object,
+});
+const formData = ref({})
+const rules = reactive({
+  bank_name: [{ required: true, message: '请选择开户银行' }],
+  owner_name: [
+    {
+      required: true,
+      message: '请输入商户名称',
+      trigger: 'blur'
+    }
+  ],
+  name_of_payee: [
+    {
+      required: true,
+      message: '请输入收款人',
+      trigger: 'blur'
+    }
+  ],
+  card_no: [
+    {
+      required: true,
+      message: '请输入银行卡号',
+      trigger: 'blur'
+    },
+    { max: 64, message: '至多输入64个字符', trigger: 'blur' }
+  ],
+  phone_of_payee: [
+    {
+      required: true,
+      message: '请输入收款人手机号',
+      trigger: 'blur'
+    },
+    { pattern: /^1[3456789]\d{9}$/, message: '号码格式不正确', trigger: 'blur' }
+  ],
+  business_id: [
+    { required: true, message: '请选择所属商务' }
+  ],
+  sub_bank_name: [
+    {
+      required: true,
+      message: '请输入开户支行',
+      trigger: 'blur'
+    }
+  ]
+});
+const loading = ref(false)
+const businessList = ref([])
+const bankList = ref([])
+
+const init = () => {
+  jiesuanManageBankAccountListShangwu().then(res => {
+    businessList.value = res.data;
+  })
+  jiesuanManageBankAccountListBank().then(res => {
+    bankList.value = res.data;
+  })
+}
+const submitForm = (formEl: FormInstance | undefined) => {
+  console.log(formData.value, 'formData.valueformData.value');
+  if (!formEl) return;
+  formEl
+    .validate(valid => {
+      if (valid) {
+        jiesuanManageBankAccountAddCompanyCard(formData.value).then(res => {
+          ElMessage.success(res.message)
+          emit('close')
+        })
+      } else {
+        loading.value = false;
+      }
+    })
+    .then(() => { });
+}
+
+if (props.primary) {
+
+}
+
+const emit = defineEmits(['close']);
+onMounted(() => {
+  init()
+});
+</script>

+ 160 - 0
src/views/settleManage/paymentAccountInfo/tabs/paymentInfo/index.vue

@@ -0,0 +1,160 @@
+<template>
+  <div>
+    <Search :search="search" :reset="resetQuery">
+      <template v-slot:body>
+        <el-form-item label="所属商务" prop="business_id">
+          <el-select v-model="query.business_id" filterable clearable placeholder="选择所属商务">
+            <el-option v-for="item in businessList" :key="item.id" :label="item.username" :value="item.id" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="申请时间">
+          <el-date-picker unlink-panels clearable @change="orderTimeChange" format="YYYY/MM/DD" value-format="YYYY-MM-DD"
+            v-model="query.createTime" type="daterange" :shortcuts="shortcuts" range-separator="To"
+            start-placeholder="开始时间" end-placeholder="结束时间" />
+        </el-form-item>
+      </template>
+    </Search>
+    <div class="table-default">
+      <Operate :show="open" />
+      <el-table :data="tableData" class="mt-3" v-loading="loading">
+        <el-table-column prop="owner_name" label="所属商务" min-width="200px" />
+        <el-table-column label="收款信息" show-overflow-tooltip min-width="200px">
+          <template #default="scope">
+            <div>收款人:{{ scope.row.name_of_payee }}</div>
+            <div>银行卡号:{{ scope.row.card_no }}</div>
+            <div>开户银行:{{ scope.row.bank_name }}</div>
+            <div>开户支行:{{ scope.row.sub_bank_name }}</div>
+            <div>收款人手机号:{{ scope.row.phone_of_payee }}</div>
+          </template>
+        </el-table-column>
+        <el-table-column prop="created_at" show-overflow-tooltip label="申请时间" min-width="200px">
+        </el-table-column>
+        <el-table-column prop="checked_at" label="审核时间" show-overflow-tooltip>
+        </el-table-column>
+        <el-table-column prop="status_str" label="状态" show-overflow-tooltip min-width="200px">
+          <template #default="scope">
+            <el-text class="mx-1" :type="colorType(scope.row)">{{ scope.row.status_str }}</el-text>
+          </template>
+        </el-table-column>
+        <el-table-column prop="remark" label="备注" show-overflow-tooltip min-width="200px">
+        </el-table-column>
+      </el-table>
+      <Paginate />
+    </div>
+    <Dialog v-model="visible" :title="title" destroy-on-close>
+      <Create @close="close(search)" :primary="id" :api="api" />
+    </Dialog>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import Create from './form/create.vue';
+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 { useOpen } from '@/hook/curd/useOpen';
+import { jiesuanManageJiesuanAccountInfo, jiesuanManageBankAccountListShangwu } from '@/api/settlement/index'
+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 { open, close, title, visible, id } = useOpen();
+const api = 'jiesuanManage/bankAccount/listCompanyCard';
+const router = useRouter()
+const route = useRoute()
+const { data, query, search, reset, loading } = useGetList(api);
+const userDetailVisible = ref(false)
+const userDetailData = ref({})
+const current = ref({})
+const businessList = ref([])
+const rolesIdentify = inject('rolesIdentify')
+
+const colorType = (data: object) => {
+  const type = data.status
+  switch (type) {
+    case 2:
+      return 'success'
+    case 1:
+      return 'warning'
+    case 0:
+      return 'danger'
+    case 3:
+      return 'danger'
+  }
+}
+
+const closeUserDetail = () => { }
+
+const orderTimeChange = (e: object) => {
+  console.log(e, 'timeChangetimeChangetimeChange');
+  if (query.value.createTime) {
+    const timeArr = toRaw(e);
+    query.value.create_start_at = timeArr[0]
+    query.value.create_end_at = timeArr[1]
+  } else {
+    delete query.value.create_start_at
+    delete query.value.create_end_at
+  }
+}
+
+const resetQuery = () => {
+  reset()
+}
+const openType = (type: string, data: object) => {
+  current.value = data;
+  switch (type) {
+    case 'userDetailVisible':
+      userDetailVisible.value = true
+      userDetailData.value = data
+      break;
+    case 'backConfigVisible':
+      break;
+  }
+}
+const tableData = computed(() => data.value?.data);
+
+onMounted(() => {
+  jiesuanManageBankAccountListShangwu().then(res => {
+    businessList.value = res.data;
+    console.log(res, 'jiesuanManageJiesuanAccountInfo');
+  })
+  console.log(rolesIdentify, 'rolesIdentifyrolesIdentify');
+  search();
+});
+</script>
+
+<style scoped lang="scss">
+.col {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  flex-direction: column;
+  height: 100px;
+  width: 25%;
+}
+
+.col:last-child {
+  align-items: start;
+}
+
+.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>

+ 32 - 0
src/views/settleManage/settlementCenter/index.vue

@@ -0,0 +1,32 @@
+<template>
+  <div>
+    <el-card shadow="always" :body-style="{ padding: '20px' }">
+      <el-tabs v-model="activeName" class="demo-tabs" @tab-change="handChange">
+        <el-tab-pane label="充值结算" name="recharge">
+          <rechargeSettle></rechargeSettle>
+        </el-tab-pane>
+        <el-tab-pane label="结算规则" name="refund">
+          <rechargeRules></rechargeRules>
+        </el-tab-pane>
+      </el-tabs>
+    </el-card>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { useRouter, useRoute } from 'vue-router'
+import type { TabsPaneContext } from 'element-plus'
+import rechargeSettle from "./tabs/rechargeSettle/index.vue"
+import rechargeRules from "./tabs/rechargeRules/index.vue"
+const router = useRouter()
+const route = useRoute()
+const handChange = (tab: TabsPaneContext, event: Event) => {
+  activeName.value = tab
+}
+const activeName = ref('recharge')
+onMounted(() => {
+  activeName.value = route.query.tab || 'recharge'
+});
+</script>
+
+<style scoped lang="scss"></style>

+ 24 - 0
src/views/settleManage/settlementCenter/tabs/rechargeRules/index.vue

@@ -0,0 +1,24 @@
+<template>
+  <div class="withdraw-popup-warn">
+    (1):结算功能针对同一账号下的所有小程序<br />
+    (2):分成金额=(充值总额-退款)*分成比例<br />
+    (3):申请提现后自动进入审核流程,审核需要1-5个工作日,节假日顺延,审核成功后自动打款<br />
+    (4):每天最多提现一次<br />
+    (5):账户余额低于500元时无法申请提现<br />
+  </div>
+</template>
+
+<script lang="ts" setup>
+
+</script>
+
+<style scoped lang="scss">
+.withdraw-popup-warn {
+  padding: 10px;
+  font-weight: 600;
+  margin-bottom: 10px;
+  line-height: 5;
+  padding-left: 30px;
+  font-size: 18px;
+}
+</style>

+ 8 - 0
src/views/settleManage/settlementCenter/tabs/rechargeSettle/excelTitle.ts

@@ -0,0 +1,8 @@
+// 导出中文/字段
+export const titleObj = {
+  时间: 'jiesuan_date',
+  日充值总额: 'charge_money',
+  当日退款: 'tuikuan_money',
+  分成比例: 'share_rate',
+  日结算总额: 'jiesuan_money'
+};

+ 112 - 0
src/views/settleManage/settlementCenter/tabs/rechargeSettle/form/create.vue

@@ -0,0 +1,112 @@
+<template>
+  <div class="withdraw-popup-warn">
+    提现提示1:工作日14:30点前提现,审核通过之后下一工作日可到账;14:30之后提现将会在下一工作日审核<br />
+    提现提示2:充值收入提现后,请自行到当地税务部门纳税,本平台仅收取10%平台服务费,不承担代扣代缴义务。
+  </div>
+  <el-form :model="formData" label-width="120px" ref="ruleForm" :rules="rules" v-loading="loading" class="pr-4">
+    <div class="flex flex-row justify-between">
+      <div class="w-full">
+        <el-form-item label="可提现金额" prop="name">
+          <el-input v-model="props.primary.yue_money" disabled placeholder="请输入商户名称" />
+        </el-form-item>
+        <el-form-item label="提现金额" prop="tixian_money">
+          <div class="items-center w-full">
+            <el-input style="width:200px;margin:0 5px;" v-model="formData.tixian_money" placeholder="请输入金额">
+              <template #append>元</template>
+            </el-input>
+            <span v-if="Number(props.primary.yue_money) > 0" class="text-blue-400 cursor-pointer"
+              @click="formData.tixian_money = props.primary.yue_money">全部提现</span>
+          </div>
+        </el-form-item>
+        <el-form-item label="提现账户" prop="bank_card_id">
+          <el-select class="w-full" v-model="formData.bank_card_id" filterable clearable placeholder="选择提现账户">
+            <el-option v-for="item in applyBank" :key="item.value" :label="item.label" :value="item.value" />
+          </el-select>
+        </el-form-item>
+      </div>
+    </div>
+    <div class="flex justify-end">
+      <el-button type="primary" @click="submitForm(ruleForm)">{{ $t('system.confirm') }}</el-button>
+    </div>
+  </el-form>
+</template>
+
+<script lang="ts" setup>
+import { useCreate } from '@/hook/curd/useCreate';
+import { useShow } from '@/hook/curd/useShow';
+import type { FormInstance, FormRules } from 'element-plus'
+import { jiesuanManageBankAccountListAvailableBankCard, jiesuanManageJiesuanTixian } from '@/api/settlement/index'
+const ruleForm = ref<FormInstance>()
+import { onMounted, ref } from 'vue';
+const props = defineProps({
+  primary: Object,
+});
+const formData = ref({})
+const rules = reactive({
+  bank_card_id: [{ required: true, message: '请选择提现账户' }],
+  tixian_money: [
+    {
+      required: true,
+      message: '请输入金额',
+      trigger: 'blur'
+    },
+    { pattern: /^\d+(\.\d{1,2})?$/, message: '金额最多只能有两位小数', trigger: 'blur' },
+    { pattern: /^(?!0\d+)\d+(\.\d+)?$/, message: '请输入有效的金额', trigger: 'blur' },
+    {
+      pattern: /^500(\.\d{1,2})?$|^([5-9]\d{2}|[1-9]\d{3,})(\.\d{1,2})?$/,
+      message: '请输入不低于500的金额',
+      // trigger: 'blur'
+    }
+  ],
+});
+const loading = ref(false)
+const applyBank = ref([])
+
+const submitForm = (formEl: FormInstance | undefined) => {
+  console.log(formData.value, 'formData.valueformData.value');
+  if (!formEl) return;
+  formEl
+    .validate(valid => {
+      if (valid) {
+        jiesuanManageJiesuanTixian(formData.value).then(res => {
+          ElMessage.success(res.message)
+          emit('close')
+          loading.value = false;
+        })
+      } else {
+        loading.value = false;
+      }
+    })
+    .then(() => { });
+}
+
+if (props.primary) {
+  console.log(props.primary, 'props.primaryprops.primary');
+}
+
+const emit = defineEmits(['close']);
+onMounted(() => {
+  jiesuanManageBankAccountListAvailableBankCard().then(res => {
+    applyBank.value = res.data;
+    applyBank.value = res.data.map(v => {
+      return {
+        label: `${v.bank_name}(***********${v.card_no.slice(-4)})`,
+        value: v.id,
+      };
+    });;
+  })
+
+});
+</script>
+
+<style lang="scss" scoped>
+.withdraw-popup-warn {
+  padding: 10px;
+  color: red;
+  margin-bottom: 10px;
+  line-height: 1.8;
+  padding-left: 30px;
+  font-size: 12px;
+  background-color: #ffecf4;
+}
+</style>

+ 212 - 0
src/views/settleManage/settlementCenter/tabs/rechargeSettle/index.vue

@@ -0,0 +1,212 @@
+<template>
+  <div>
+    <el-card shadow="always" :body-style="{ padding: '20px' }">
+      <el-row :gutter="20">
+        <el-col :span="6" class="col">
+          <div class="text-lg text-red-500">
+            ¥{{ applyData.yue_money }}
+          </div>
+          <div class="text-base">
+            账户余额
+          </div>
+        </el-col>
+        <el-col :span="6" class="col">
+          <div class="text-lg text-green-500">
+            ¥{{ applyData.tixian_money }}
+          </div>
+          <div class="text-base">
+            审核中
+          </div>
+        </el-col>
+        <el-col :span="6" class="col">
+          <div class="text-lg text-red-300">
+            ¥{{ applyData.total_dakuan }}
+          </div>
+          <div class="text-base">
+            已打款
+          </div>
+        </el-col>
+        <el-col :span="6" class="col">
+          <div class="flex mb-4 text-lg text-red-500">
+            <el-button type="primary" :disabled="applyBank.length <= 0" size="default"
+              @click="openType('applyVisible', applyData)">申请提现</el-button>
+            <div v-if="applyBank.length <= 0" class="ml-3">未配置收款账户,<span
+                @click="router.push('/jiesuanManage/bankAccount')" class="text-blue-400 cursor-pointer">去配置</span></div>
+          </div>
+          <div class="text-base">
+            <el-button size="default" @click="openType('applyListVisible')">提现记录</el-button>
+          </div>
+        </el-col>
+      </el-row>
+    </el-card>
+    <div class="p-5">注:每日的结算数据需要在次日统计完成后才能展示</div>
+    <Search :search="search" :reset="resetQuery">
+      <template v-slot:body>
+        <el-form-item label="结算时间">
+          <el-date-picker unlink-panels clearable @change="applyTimeChange" format="YYYY/MM/DD" value-format="YYYY-MM-DD"
+            v-model="query.applyTime" type="daterange" :shortcuts="shortcuts" range-separator="To"
+            start-placeholder="开始时间" end-placeholder="结束时间" />
+        </el-form-item>
+      </template>
+      <template v-slot:extra_button>
+        <exportExcel api="jiesuanManage/jiesuan/list" sheet_name="结算中心" :title_obj="titleObj"
+          :extro_params="{ is_export: 1, ...query }">
+        </exportExcel>
+      </template>
+    </Search>
+    <div class="table-default">
+      <el-table :data="tableData" class="mt-3" v-loading="loading">
+        <el-table-column prop="jiesuan_date" label="时间" min-width="200px" />
+        <el-table-column prop="charge_money" label="日充值总额" show-overflow-tooltip min-width="200px">
+        </el-table-column>
+        <el-table-column prop="tuikuan_money" show-overflow-tooltip label="当日退款" min-width="200px">
+        </el-table-column>
+        <el-table-column prop="share_rate" label="分成比例" show-overflow-tooltip>
+        </el-table-column>
+        <el-table-column prop="jiesuan_money" label="日结算总额" show-overflow-tooltip min-width="200px">
+        </el-table-column>
+        <el-table-column label="操作">
+          <template #default="scope">
+            <el-button link type="primary" size="small"
+              @click="openType('orderDetailVisible', scope.row)">查看订单详情</el-button>
+            <br />
+          </template>
+        </el-table-column>
+      </el-table>
+      <Paginate />
+    </div>
+    <Dialog v-model="orderDetailVisible" width="80%" title="订单详情" destroy-on-close>
+      <orderDetail @close="closeType('orderDetailVisible')" :primary="orderDetailData"></orderDetail>
+    </Dialog>
+    <Dialog v-model="applyVisible" width="50%" title="申请提现" destroy-on-close>
+      <create @close="closeType('applyVisible')" :primary="applyData"></create>
+    </Dialog>
+    <Dialog v-model="applyListVisible" width="80%" title="提现记录" destroy-on-close>
+      <withdrawalRecord @close="closeType('applyListVisible')"></withdrawalRecord>
+    </Dialog>
+  </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 { titleObj } from "./excelTitle"
+import { jiesuanManageJiesuanAccountInfo, jiesuanManageBankAccountListAvailableBankCard } from '@/api/settlement/index'
+import orderDetail from './orderDetail/index.vue'
+import create from './form/create.vue'
+import withdrawalRecord from './withdrawalRecord/index.vue'
+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 api = 'jiesuanManage/jiesuan/list';
+const router = useRouter()
+const route = useRoute()
+const { data, query, search, reset, loading } = useGetList(api);
+const orderDetailVisible = ref(false)
+const orderDetailData = ref({})
+const applyData = ref({})
+const applyVisible = ref(false)
+const applyListVisible = ref(false)
+const rolesIdentify = inject('rolesIdentify')
+const applyBank = ref([])
+const closeType = (type: string) => {
+  switch (type) {
+    case 'orderDetailVisible':
+      orderDetailVisible.value = false
+      break;
+    case 'applyVisible':
+      applyVisible.value = false
+      init()
+      break;
+    case 'applyListVisible':
+      applyListVisible.value = false
+      break;
+  }
+  search()
+}
+
+const openType = (type: string, data?: object) => {
+  switch (type) {
+    case 'orderDetailVisible':
+      orderDetailVisible.value = true
+      orderDetailData.value = data || {}
+      break;
+    case 'applyVisible':
+      applyVisible.value = true
+      break;
+    case 'applyListVisible':
+      applyListVisible.value = true
+      break;
+  }
+}
+const applyTimeChange = (e: object) => {
+  console.log(e, 'timeChangetimeChangetimeChange');
+  if (query.value.applyTime) {
+    const timeArr = toRaw(e);
+    query.value.jiesuan_date_start_at = timeArr[0]
+    query.value.jiesuan_date_end_at = timeArr[1]
+  } else {
+    delete query.value.jiesuan_date_start_at
+    delete query.value.jiesuan_date_end_at
+  }
+}
+
+const resetQuery = () => {
+  reset()
+}
+
+const tableData = computed(() => data.value?.data);
+
+
+const init = () => {
+  jiesuanManageBankAccountListAvailableBankCard().then(res => {
+    applyBank.value = res.data;
+  })
+  jiesuanManageJiesuanAccountInfo().then(res => {
+    applyData.value = res.data
+  })
+}
+onMounted(() => {
+  init()
+  search();
+});
+</script>
+
+<style scoped lang="scss">
+.col {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  flex-direction: column;
+  height: 100px;
+  width: 25%;
+}
+
+.col:last-child {
+  align-items: start;
+}
+
+.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>

+ 30 - 0
src/views/settleManage/settlementCenter/tabs/rechargeSettle/orderDetail/index.vue

@@ -0,0 +1,30 @@
+<template>
+  <div>
+    <el-tabs v-model="activeName" class="demo-tabs" @tab-change="handChange">
+      <el-tab-pane label="充值订单" name="recharge">
+        <rechargeList></rechargeList>
+      </el-tab-pane>
+      <el-tab-pane label="退款订单" name="refund">
+        <refundList></refundList>
+      </el-tab-pane>
+    </el-tabs>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { useRouter, useRoute } from 'vue-router'
+import type { TabsPaneContext } from 'element-plus'
+import rechargeList from "./tabs/rechargeList/index.vue"
+import refundList from "./tabs/refundList/index.vue"
+const router = useRouter()
+const route = useRoute()
+const handChange = (tab: TabsPaneContext, event: Event) => {
+  activeName.value = tab
+}
+const activeName = ref('recharge')
+onMounted(() => {
+  activeName.value = route.query.tab || 'recharge'
+});
+</script>
+
+<style scoped lang="scss"></style>

+ 16 - 0
src/views/settleManage/settlementCenter/tabs/rechargeSettle/orderDetail/tabs/rechargeList/excelTitle.ts

@@ -0,0 +1,16 @@
+// 导出中文/字段
+export const titleObj = {
+  所属账户ID: 'advertiser_id',
+  所属账户: 'advertiser_name',
+  订单号: 'order_no',
+  用户ID: 'uid',
+  注册IP: 'user_ranse_ip',
+  注册时间: 'user_ranse_start_at',
+  充值时间: 'order_created_at',
+  充值金额: 'order_price',
+  是否回传: 'filter_type_str',
+  备注: 'filter_reason',
+  回传百分比: 'current_rate',
+  回传配置百分比: 'config_rate',
+  广告计划ID: 'adv_promotion_id'
+};

+ 60 - 0
src/views/settleManage/settlementCenter/tabs/rechargeSettle/orderDetail/tabs/rechargeList/index.vue

@@ -0,0 +1,60 @@
+<template>
+  <div>
+    <div class="table-default">
+      <el-table :data="tableData" class="mt-3" v-loading="loading">
+        <el-table-column prop="created_at" label="时间" min-width="200px" />
+        <el-table-column prop="play_name" show-overflow-tooltip label="小程序" min-width="200px">
+        </el-table-column>
+        <el-table-column prop="username" label="优化师" show-overflow-tooltip min-width="200px">
+        </el-table-column>
+        <el-table-column prop="trade_no" label="交易单号" show-overflow-tooltip min-width="200px">
+        </el-table-column>
+        <el-table-column prop="price" label="充值金额" show-overflow-tooltip>
+        </el-table-column>
+        <el-table-column prop="uid" label="用户ID" show-overflow-tooltip>
+        </el-table-column>
+      </el-table>
+      <Paginate />
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { useGetList } from '@/hook/curd/useGetList';
+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 api = 'channel/order_list';
+const { data, query, search, reset, loading } = useGetList(api);
+
+const tableData = computed(() => data.value?.data);
+
+onMounted(() => {
+  search();
+});
+</script>
+
+<style scoped lang="scss">
+.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>

+ 16 - 0
src/views/settleManage/settlementCenter/tabs/rechargeSettle/orderDetail/tabs/refundList/excelTitle.ts

@@ -0,0 +1,16 @@
+// 导出中文/字段
+export const titleObj = {
+  所属账户ID: 'advertiser_id',
+  所属账户: 'advertiser_name',
+  订单号: 'order_no',
+  用户ID: 'uid',
+  注册IP: 'user_ranse_ip',
+  注册时间: 'user_ranse_start_at',
+  充值时间: 'order_created_at',
+  充值金额: 'order_price',
+  是否回传: 'filter_type_str',
+  备注: 'filter_reason',
+  回传百分比: 'current_rate',
+  回传配置百分比: 'config_rate',
+  广告计划ID: 'adv_promotion_id'
+};

+ 60 - 0
src/views/settleManage/settlementCenter/tabs/rechargeSettle/orderDetail/tabs/refundList/index.vue

@@ -0,0 +1,60 @@
+<template>
+  <div>
+    <div class="table-default">
+      <el-table :data="tableData" class="mt-3" v-loading="loading">
+        <el-table-column prop="created_at" label="时间" min-width="200px" />
+        <el-table-column prop="play_name" show-overflow-tooltip label="小程序" min-width="200px">
+        </el-table-column>
+        <el-table-column prop="username" label="优化师" show-overflow-tooltip min-width="200px">
+        </el-table-column>
+        <el-table-column prop="trade_no" label="交易单号" show-overflow-tooltip min-width="200px">
+        </el-table-column>
+        <el-table-column prop="price" label="充值金额" show-overflow-tooltip>
+        </el-table-column>
+        <el-table-column prop="uid" label="用户ID" show-overflow-tooltip>
+        </el-table-column>
+      </el-table>
+      <Paginate />
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { useGetList } from '@/hook/curd/useGetList';
+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 api = 'channel/order_list';
+const { data, query, search, reset, loading } = useGetList(api);
+
+const tableData = computed(() => data.value?.data);
+
+onMounted(() => {
+  search();
+});
+</script>
+
+<style scoped lang="scss">
+.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>

+ 11 - 0
src/views/settleManage/settlementCenter/tabs/rechargeSettle/withdrawalRecord/excelTitle.ts

@@ -0,0 +1,11 @@
+// 导出中文/字段
+export const titleObj = {
+  提现时间: 'created_at',
+  提现金额: 'tixian_money',
+  提现账户: 'card_no',
+  收款人姓名: 'name_of_payee',
+  支付通道: 'pay_channel',
+  银行流水: 'pay_no',
+  审核状态: 'status_str',
+  备注: 'remark'
+};

+ 126 - 0
src/views/settleManage/settlementCenter/tabs/rechargeSettle/withdrawalRecord/index.vue

@@ -0,0 +1,126 @@
+<template>
+  <div>
+    <div class="pl-5">
+      <el-radio-group v-model="query.status" @change="search">
+        <el-radio v-for="item in statusList" :label="item.value" :key="item.value">{{ item.name }}</el-radio>
+      </el-radio-group>
+    </div>
+    <div class="flex justify-between">
+      <Search :search="search" :reset="resetQuery">
+        <template v-slot:body>
+          <el-form-item label="申请时间">
+            <el-date-picker unlink-panels clearable @change="createTimeChange" format="YYYY/MM/DD"
+              value-format="YYYY-MM-DD" v-model="query.createTime" type="daterange" :shortcuts="shortcuts"
+              range-separator="To" start-placeholder="开始时间" end-placeholder="结束时间" />
+          </el-form-item>
+        </template>
+        <template v-slot:extra_button>
+          <exportExcel api="jiesuanManage/jiesuan/listTixian" sheet_name="提现记录" :title_obj="titleObj"
+            :extro_params="{ is_export: 1, ...query }">
+          </exportExcel>
+        </template>
+      </Search>
+    </div>
+    <div class="table-default">
+      <el-table :data="tableData" class="mt-3" v-loading="loading">
+        <el-table-column prop="created_at" label="提现时间" min-width="200px" />
+        <el-table-column prop="tixian_money" label="提现金额" show-overflow-tooltip min-width="200px">
+        </el-table-column>
+        <el-table-column prop="card_no" show-overflow-tooltip label="提现账户" min-width="200px">
+        </el-table-column>
+        <el-table-column prop="name_of_payee" label="收款人姓名" min-width="200px" show-overflow-tooltip>
+        </el-table-column>
+        <el-table-column prop="pay_channel" label="支付通道" show-overflow-tooltip min-width="200px">
+        </el-table-column>
+        <el-table-column prop="pay_no" label="银行流水" show-overflow-tooltip min-width="200px" />
+        <el-table-column prop="status_str" label="审核状态" show-overflow-tooltip min-width="150px">
+          <template #default="scope">
+            <div class="wrapper">
+              <span class="text-lg font-bold content">
+                <el-text class="mx-1" :type="colorType(scope.row)">{{ scope.row.status_str }}</el-text>
+              </span>
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column prop="remark" label="备注" show-overflow-tooltip min-width="150px">
+        </el-table-column>
+      </el-table>
+      <Paginate />
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { InfoFilled } from '@element-plus/icons-vue';
+import { useGetList } from '@/hook/curd/useGetList';
+const api = 'jiesuanManage/jiesuan/listTixian';
+import { titleObj } from "./excelTitle"
+const { data, query, search, reset, loading } = useGetList(api);
+const rolesIdentify = inject('rolesIdentify')
+const statusList = ref([
+  { name: '全部', value: '' },
+  { name: '待审核', value: 1 },
+  { name: '审核失败', value: 2 },
+  { name: '待打款', value: 3 },
+  { name: '已打款', value: 4 },
+  { name: '打款失败', value: 5 },
+])
+const colorType = (data: object) => {
+  const type = data.status
+  switch (type) {
+    case 4:
+      return 'success'
+    case 3:
+      return 'warning'
+    case 1:
+      return 'warning'
+    case 2:
+      return 'danger'
+    case 5:
+      return 'danger'
+  }
+}
+const createTimeChange = (e: object) => {
+  console.log(e, 'timeChangetimeChangetimeChange');
+  if (query.value.createTime) {
+    const timeArr = toRaw(e);
+    query.value.tixian_start_at = timeArr[0]
+    query.value.tixian_end_at = timeArr[1]
+  } else {
+    delete query.value.tixian_start_at
+    delete query.value.tixian_end_at
+  }
+}
+const resetQuery = () => {
+  reset()
+}
+
+const tableData = computed(() => data.value?.data);
+
+onMounted(() => {
+  search();
+});
+</script>
+
+<style scoped lang="scss">
+.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>