소스 검색

Merge remote-tracking branch 'origin/development' into development

congxuesong 4 주 전
부모
커밋
75535a2fe4

BIN
src/assets/financial/zfb-icon.png


+ 370 - 0
src/views/financialManagement/cashApply.vue

@@ -0,0 +1,370 @@
+<template>
+  <div class="cash-apply-page">
+    <!-- 头部 -->
+    <div class="header">
+      <el-button class="back-btn" @click="goBack"> 返回 </el-button>
+      <h2 class="title">提现申请</h2>
+    </div>
+
+    <!-- 内容区域 -->
+    <div class="content">
+      <!-- 可提现金额 -->
+      <div class="section">
+        <div class="section-title">可提现金额</div>
+        <div class="available-amount">¥{{ formatCurrency(availableAmount) }}</div>
+      </div>
+
+      <!-- 提现金额输入 -->
+      <div class="section">
+        <div class="section-title">提现金额</div>
+        <div class="amount-input-wrapper">
+          <el-input
+            v-model="withdrawAmount"
+            placeholder="请输入提现金额"
+            class="amount-input"
+            type="number"
+            :min="0.01"
+            :max="availableAmount"
+            @input="handleAmountInput"
+          />
+          <el-button type="primary" class="withdraw-all-btn" @click="handleWithdrawAll"> 全部提现 </el-button>
+        </div>
+        <div class="min-amount-tip">最低提现金额为0.01元</div>
+      </div>
+
+      <!-- 提现账户 -->
+      <div class="section">
+        <div class="section-title">提现账户</div>
+        <div class="account-list">
+          <div
+            v-for="account in accountList"
+            :key="account.id"
+            class="account-item"
+            :class="{ active: selectedAccountId === account.id }"
+            @click="selectAccount(account.id)"
+          >
+            <div class="account-left">
+              <img :src="account.icon" alt="" class="account-icon" />
+              <div class="account-info">
+                <div class="account-name">
+                  {{ account.name }}
+                </div>
+                <div class="account-number">
+                  {{ account.accountNumber }}
+                </div>
+              </div>
+            </div>
+            <div class="account-right">
+              <div v-if="selectedAccountId === account.id" class="selected-indicator" />
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+
+    <!-- 底部按钮 -->
+    <div class="footer">
+      <el-button class="cancel-btn" @click="goBack"> 取消 </el-button>
+      <el-button type="primary" class="submit-btn" @click="handleSubmit"> 提交申请 </el-button>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { ref, onMounted } from "vue";
+import { useRouter } from "vue-router";
+import { ElMessage } from "element-plus";
+import { getAccountBalance } from "@/api/modules/homeEntry";
+import zfbIcon from "@/assets/financial/zfb-icon.png";
+
+const router = useRouter();
+
+// 可提现金额
+const availableAmount = ref<number>(586);
+
+// 提现金额
+const withdrawAmount = ref<string>("");
+
+// 账户列表
+const accountList = ref([
+  {
+    id: 1,
+    name: "支付宝",
+    accountNumber: "130****1234",
+    icon: zfbIcon
+  }
+]);
+
+// 选中的账户ID
+const selectedAccountId = ref<number>(1);
+
+// 返回
+const goBack = () => {
+  router.back();
+};
+
+// 格式化金额
+const formatCurrency = (value: number) => {
+  return value.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 });
+};
+
+// 全部提现
+const handleWithdrawAll = () => {
+  withdrawAmount.value = availableAmount.value.toString();
+};
+
+// 金额输入处理
+const handleAmountInput = (value: string) => {
+  const numValue = parseFloat(value);
+  if (isNaN(numValue) || numValue < 0) {
+    withdrawAmount.value = "";
+    return;
+  }
+  if (numValue > availableAmount.value) {
+    withdrawAmount.value = availableAmount.value.toString();
+    ElMessage.warning("提现金额不能超过可提现金额");
+  }
+};
+
+// 选择账户
+const selectAccount = (id: number) => {
+  selectedAccountId.value = id;
+};
+
+// 提交申请
+const handleSubmit = () => {
+  const amount = parseFloat(withdrawAmount.value);
+
+  // 验证提现金额
+  if (!withdrawAmount.value || isNaN(amount) || amount <= 0) {
+    ElMessage.warning("请输入提现金额");
+    return;
+  }
+
+  if (amount < 0.01) {
+    ElMessage.warning("最低提现金额为0.01元");
+    return;
+  }
+
+  if (amount > availableAmount.value) {
+    ElMessage.warning("提现金额不能超过可提现金额");
+    return;
+  }
+
+  // 验证账户
+  if (!selectedAccountId.value) {
+    ElMessage.warning("请选择提现账户");
+    return;
+  }
+
+  // TODO: 调用提现API
+  ElMessage.success("提现申请提交成功");
+  // 提交成功后返回上一页
+  setTimeout(() => {
+    goBack();
+  }, 1500);
+};
+
+// 获取可提现金额
+const fetchAccountBalance = async () => {
+  try {
+    let param = {
+      storeId: 138
+    };
+    const res: any = await getAccountBalance(param as any);
+    if (res.code == 200 && res.data) {
+      // 根据实际API返回的数据结构更新
+      // availableAmount.value = res.data.availableAmount || res.data.amount || 586;
+    }
+  } catch (error) {
+    console.error("获取可提现金额失败:", error);
+  }
+};
+
+onMounted(() => {
+  fetchAccountBalance();
+});
+</script>
+
+<style scoped lang="scss">
+.cash-apply-page {
+  display: flex;
+  flex-direction: column;
+  width: 100%;
+  min-height: 100vh;
+  background-color: #ffffff;
+}
+.header {
+  position: relative;
+  display: flex;
+  align-items: center;
+  padding: 20px;
+  border-bottom: 1px solid #e4e7ed;
+  .back-btn {
+    padding: 8px 16px;
+    font-size: 14px;
+    color: #606266;
+    background-color: #f5f7fa;
+    border: 1px solid #dcdfe6;
+    border-radius: 4px;
+    &:hover {
+      color: #409eff;
+      background-color: #ecf5ff;
+      border-color: #b3d8ff;
+    }
+  }
+  .title {
+    position: absolute;
+    left: 50%;
+    margin: 0;
+    font-size: 18px;
+    font-weight: bold;
+    color: #333333;
+    transform: translateX(-50%);
+  }
+}
+.content {
+  display: flex;
+  flex: 1;
+  flex-direction: column;
+  gap: 32px;
+  padding: 24px 20px;
+}
+.section {
+  display: flex;
+  flex-direction: column;
+  gap: 12px;
+  .section-title {
+    font-size: 16px;
+    font-weight: 500;
+    color: #333333;
+  }
+}
+.available-amount {
+  margin-top: 8px;
+  font-size: 36px;
+  font-weight: 600;
+  color: #333333;
+}
+.amount-input-wrapper {
+  display: flex;
+  gap: 12px;
+  align-items: center;
+  .amount-input {
+    flex: 1;
+    :deep(.el-input__wrapper) {
+      padding: 12px 16px;
+      border-radius: 4px;
+    }
+  }
+  .withdraw-all-btn {
+    padding: 12px 20px;
+    white-space: nowrap;
+    background-color: #409eff;
+    border: none;
+    border-radius: 4px;
+  }
+}
+.min-amount-tip {
+  margin-top: 4px;
+  font-size: 12px;
+  color: #909399;
+}
+.account-list {
+  display: flex;
+  flex-direction: column;
+  gap: 12px;
+  margin-top: 8px;
+}
+.account-item {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  padding: 16px;
+  cursor: pointer;
+  background-color: #ffffff;
+  border: 1px solid #dcdfe6;
+  border-radius: 8px;
+  transition: all 0.3s;
+  &:hover {
+    border-color: #409eff;
+  }
+  &.active {
+    background-color: #ecf5ff;
+    border-color: #409eff;
+  }
+  .account-left {
+    display: flex;
+    flex: 1;
+    gap: 12px;
+    align-items: center;
+    .account-icon {
+      width: 40px;
+      height: 40px;
+      object-fit: contain;
+    }
+    .account-info {
+      display: flex;
+      flex-direction: column;
+      gap: 4px;
+      .account-name {
+        font-size: 16px;
+        font-weight: 500;
+        color: #333333;
+      }
+      .account-number {
+        font-size: 14px;
+        color: #909399;
+      }
+    }
+  }
+  .account-right {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    width: 24px;
+    height: 24px;
+    .selected-indicator {
+      width: 16px;
+      height: 16px;
+      background-color: #409eff;
+      border: 3px solid #ffffff;
+      border-radius: 50%;
+      box-shadow: 0 0 0 2px #409eff;
+    }
+  }
+}
+.footer {
+  display: flex;
+  gap: 12px;
+  padding: 20px;
+  background-color: #ffffff;
+  border-top: 1px solid #e4e7ed;
+  .cancel-btn {
+    flex: 1;
+    padding: 12px;
+    font-size: 16px;
+    color: #606266;
+    background-color: #f5f7fa;
+    border: 1px solid #dcdfe6;
+    border-radius: 4px;
+    &:hover {
+      color: #409eff;
+      background-color: #ecf5ff;
+      border-color: #b3d8ff;
+    }
+  }
+  .submit-btn {
+    flex: 1;
+    padding: 12px;
+    font-size: 16px;
+    color: #ffffff;
+    background-color: #409eff;
+    border: none;
+    border-radius: 4px;
+    &:hover {
+      background-color: #66b1ff;
+    }
+  }
+}
+</style>

+ 111 - 28
src/views/financialManagement/index.vue

@@ -4,18 +4,21 @@
     <el-card class="summary-card" shadow="hover">
       <div class="card-img">
         <div class="summary-header">
-          <span class="title">今日收益1</span>
-          <el-tooltip content="今日收益为今天入账的金额" placement="top">
+          <span class="title">今日收益</span>
+          <el-tooltip content="今日收益=今日已核销到账金额-技术服务费" placement="top">
             <el-icon class="question-icon">
               <QuestionFilled />
             </el-icon>
           </el-tooltip>
+          <el-icon class="right-icon" @click="handleTodayIncomeList">
+            <ArrowRight />
+          </el-icon>
         </div>
         <div class="summary-body">
           <el-image :src="gold" class="gold" />
           <div class="summary-amount">
             <span class="currency">¥</span>
-            <span class="amount">{{ formatCurrency(summaryData.todayIncome) }}</span>
+            <span class="amount">{{ todayIncome }}</span>
             <span class="unit">元</span>
           </div>
         </div>
@@ -34,7 +37,7 @@
           </el-tooltip>
         </div>
         <div class="stat-amount">
-          {{ formatCurrency(stat.amount) }}
+          {{ stat.amount }}
         </div>
         <el-button type="primary" class="stat-btn" @click="handleAction(stat.key)">
           {{ stat.buttonText }}
@@ -45,46 +48,120 @@
 </template>
 
 <script setup lang="ts">
-import { ref, reactive, watch, onMounted } from "vue";
-import { QuestionFilled } from "@element-plus/icons-vue";
+import { ref, reactive, watch, onMounted, nextTick } from "vue";
+import { QuestionFilled, ArrowRight } from "@element-plus/icons-vue";
 import gold from "../../assets/financial/gold.png";
-import { getAccountBalance } from "@/api/modules/homeEntry";
+import { getAccountBalance, getTodayIncome, getPaymentCycle, checkPayPassword } from "@/api/modules/homeEntry";
 import { localGet } from "@/utils/index";
 import { useRouter } from "vue-router";
+import { ElMessage } from "element-plus";
+import en from "@/languages/modules/en";
+import { pa } from "element-plus/es/locale";
 const router = useRouter();
+const userInfo = localGet("geeker-user")?.userInfo || {};
 onMounted(() => {
+  fetchGetTodayIncome();
   fetchAccountBalance();
+  fetchGetPaymentCycle0();
+  fetchGetPaymentCycle1();
 });
+
+const stats = reactive([
+  {
+    key: "withdraw",
+    title: "可提现金额",
+    amount: "",
+    buttonText: "提现",
+    tooltip: "收益产生后3天可提现,28天自动付收益产生日期+3个自然日可提现,若未提现,则按收益产生日期+28个自然日自动付"
+  },
+  { key: "settled", title: "已到账期金额", amount: "", buttonText: "查看明细", tooltip: "已到达可提现时间的金额总额" },
+  {
+    key: "pending",
+    title: "未到账期金额",
+    amount: "",
+    buttonText: "查看明细",
+    tooltip: "未到达可提现时间的账单,您需要等待账单到达结算周期后发起提现"
+  }
+]);
+const handleTodayIncomeList = async () => {
+  router.push({ path: "/financialManagement/todayIncomeList" });
+};
+//已到账/未到账金额
+const fetchGetPaymentCycle0 = async () => {
+  let param = {
+    storeId: userInfo.storeId,
+    startTime: null,
+    endTime: null,
+    paymentType: 0,
+    incomeType: 0,
+    pageNum: 1,
+    pageSize: 999999
+  };
+  const res: any = await getPaymentCycle(param as any);
+  if (res.code == 200) {
+    nextTick(() => {
+      stats[1].amount = res.data.money;
+    });
+  }
+};
+const fetchGetPaymentCycle1 = async () => {
+  let param = {
+    storeId: userInfo.storeId,
+    startTime: null,
+    endTime: null,
+    paymentType: 1,
+    incomeType: 1,
+    pageNum: 1,
+    pageSize: 999999
+  };
+  const res: any = await getPaymentCycle(param as any);
+  if (res.code == 200) {
+    nextTick(() => {
+      stats[2].amount = res.data.money;
+    });
+  }
+};
 //可提现金额
 const fetchAccountBalance = async () => {
   let param = {
-    storeId: 138
+    storeId: userInfo.storeId
   };
   const res: any = await getAccountBalance(param as any);
   if (res.code == 200) {
+    nextTick(() => {
+      stats[0].amount = res.data.balance;
+    });
   }
 };
-const summaryData = {
-  todayIncome: 65411
-};
-
-const stats = [
-  { key: "withdraw", title: "可提现金额", amount: 932110, buttonText: "提现", tooltip: "可用于提现的金额" },
-  { key: "settled", title: "已到账期金额", amount: 932110, buttonText: "查看明细", tooltip: "已结算到账的金额" },
-  { key: "pending", title: "未到账期金额", amount: 932110, buttonText: "查看明细", tooltip: "正在结算中的金额" }
-];
-
-const formatCurrency = (value: number) => {
-  return value.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 });
+//今日收益
+const todayIncome = ref("");
+const fetchGetTodayIncome = async () => {
+  let param = {
+    storeId: userInfo.storeId
+  };
+  const res: any = await getTodayIncome(param as any);
+  if (res.code == 200) {
+    todayIncome.value = res.data;
+  }
 };
 
-const handleAction = (key: string) => {
-  switch (key) {
-    case "withdraw":
-      router.push("/financialManagement/realName");
-      break;
-    default:
-      console.log("查看明细");
+const handleAction = async (key: string) => {
+  console.log(key);
+  if (key == "withdraw") {
+    let param = {
+      storeUserId: userInfo.id
+    };
+    const res: any = await checkPayPassword(param as any);
+    if (res.code == 200) {
+      ElMessage.error(res.data.message);
+      router.push({ path: "/financialManagement/realName" });
+    }
+  }
+  if (key == "settled") {
+    router.push({ path: "/financialManagement/reconciled" });
+  }
+  if (key == "pending") {
+    router.push({ path: "/financialManagement/unposted" });
   }
 };
 </script>
@@ -117,7 +194,13 @@ const handleAction = (key: string) => {
     font-size: 16px;
     color: #333333;
     .question-icon {
-      color: #9aa4c2;
+      color: #7293f8;
+      cursor: pointer;
+    }
+    .right-icon {
+      margin-left: 30px;
+      font-weight: bold;
+      color: #7293f8;
       cursor: pointer;
     }
   }

+ 279 - 116
src/views/financialManagement/realName.vue

@@ -24,16 +24,41 @@
 
     <!-- 实名认证 -->
     <div class="content-section" v-if="activeTab === 'realName'">
-      <div class="content-wrapper">
-        <el-button type="primary" class="auth-button" @click="handleGoAuth"> 去实名认证 </el-button>
+      <div class="content-wrapper-realName">
+        <div class="goAuthBtn" v-if="goAuth">
+          <el-button type="primary" class="auth-button" @click="handleGoAuth">
+            <el-icon><CirclePlus /></el-icon> &nbsp;去实名认证
+          </el-button>
+        </div>
+        <div class="auth-div" v-if="!goAuth">
+          <el-row class="auth-row">
+            <el-col :span="2"> 姓名 </el-col>
+            <el-col :span="12"> 王* </el-col>
+          </el-row>
+          <el-row class="auth-row">
+            <el-col :span="2"> 身份证号 </el-col>
+            <el-col :span="12"> 2315************9966 </el-col>
+          </el-row>
+          <el-row class="auth-row">
+            <el-col :span="2"> 认证时间 </el-col>
+            <el-col :span="12"> 2025/11/19 </el-col>
+          </el-row>
+        </div>
       </div>
     </div>
 
     <!-- 提现密码 -->
     <div class="content-section" v-if="activeTab === 'withdrawPassword'">
       <div class="content-wrapper">
-        <!-- <div class="password-form-wrapper">
-          <el-form ref="passwordFormRef" :model="passwordForm" :rules="passwordRules" label-width="120px" label-position="left">
+        <div class="password-form-wrapper" v-if="withdrawPass">
+          <el-form
+            ref="passwordFormRef"
+            :model="passwordForm"
+            :rules="passwordRules"
+            label-width="120px"
+            label-position="left"
+            class="form-wrapper"
+          >
             <el-form-item label="设置提现密码" prop="password">
               <el-input
                 v-model="passwordForm.password"
@@ -62,8 +87,9 @@
               </el-button>
             </el-form-item>
           </el-form>
-        </div> -->
-        <div class="password-form-wrapper-step">
+        </div>
+        <!---第二次进入此页面--->
+        <div class="password-form-wrapper-step" v-if="twoEnterPage">
           <el-steps :active="currentStep" style="max-width: 600px">
             <el-step v-for="(item, index) in passList" :key="index">
               <template #title>
@@ -80,6 +106,7 @@
             label-width="100px"
             label-position="left"
             class="form-wrapper"
+            v-if="currentStep == 1"
           >
             <el-form-item label="验证原密码" prop="password">
               <el-input
@@ -92,8 +119,65 @@
                 class="password-input"
               />
             </el-form-item>
+            <div class="forget-password">忘记密码</div>
+            <el-button type="primary" class="submit-button" @click="nextStept"> 下一步 </el-button>
+          </el-form>
+          <el-form
+            ref="passwordFormRef"
+            :model="passwordForm"
+            :rules="passwordRules"
+            label-width="120px"
+            label-position="left"
+            class="form-wrapper"
+            v-if="currentStep == 2"
+          >
+            <el-form-item label="设置提现密码" prop="password">
+              <el-input
+                v-model="passwordForm.password"
+                type="password"
+                placeholder="请输入6位提现密码"
+                clearable
+                maxlength="6"
+                show-password
+                class="password-input"
+              />
+            </el-form-item>
+            <el-form-item label="请确认密码" prop="confirmPassword">
+              <el-input
+                v-model="passwordForm.confirmPassword"
+                type="password"
+                placeholder="请输入6位提现密码"
+                clearable
+                maxlength="6"
+                show-password
+                class="password-input"
+              />
+            </el-form-item>
+            <el-form-item>
+              <el-button type="primary" class="submit-button" :loading="passwordLoading" @click="handlePasswordSubmit">
+                确认
+              </el-button>
+            </el-form-item>
           </el-form>
-          <div class="forget-password">忘记密码</div>
+        </div>
+      </div>
+    </div>
+    <!--收款账户-->
+    <div class="content-section" v-if="activeTab === 'receivingAccount'">
+      <div class="content-wrapper">
+        <!-- <el-button type="primary" class="auth-button" @click="handleGoZFB"> 添加支付宝账号 </el-button> -->
+        <div class="zfb-wrapper">
+          <div class="zfb-left">
+            <el-image :src="zfbIcon" class="zfbIcon" />
+            <div>
+              <div>支付宝</div>
+              <div>130******111</div>
+            </div>
+          </div>
+          <div class="operate">
+            <div @click="getEditZfb">编辑</div>
+            <div @click="getDelZfb">删除</div>
+          </div>
         </div>
       </div>
     </div>
@@ -149,68 +233,48 @@
         </span>
       </template>
     </el-dialog>
+
+    <!--添加支付宝账号--->
+    <el-dialog v-model="dialogVisibleZFB" title="添加支付宝账号" width="500px" :close-on-click-modal="false">
+      <el-form ref="authFormRef" :model="authForm" :rules="authRules" label-width="100px" label-position="left">
+        <el-form-item label="支付宝账号" prop="name">
+          <el-input v-model="authForm.zfbName" placeholder="请输入支付宝账号" clearable />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="handleCancel">取消</el-button>
+          <el-button type="primary" :loading="loading" @click="handleConfirmZFB">确认</el-button>
+        </span>
+      </template>
+    </el-dialog>
   </div>
 </template>
 
 <script setup lang="ts">
-import { ref, reactive } from "vue";
+import { ref, reactive, computed } from "vue";
 import { useRouter } from "vue-router";
 import { ElMessage, type FormInstance, type FormRules } from "element-plus";
 import { localGet } from "@/utils/index";
 import homeIcon from "../../assets/images/home-icon.png";
+import zfbIcon from "../../assets/financial/zfb-icon.png";
 
 const router = useRouter();
 const activeTab = ref("realName");
 const dialogVisible = ref(false);
 const loading = ref(false);
+//实名认证
+const goAuth = ref(true);
 const authFormRef = ref<FormInstance>();
-const passwordFormRef = ref<FormInstance>();
-const passwordLoading = ref(false);
-const currentStep = ref(0);
-const forgotPasswordVisible = ref(false);
-const forgotPasswordFormRef = ref<FormInstance>();
-const forgotPasswordForm = reactive({
-  verificationCode: "",
-  newPassword: ""
-});
-// 忘记密码表单验证规则
-const forgotPasswordRules: FormRules = {
-  verificationCode: [{ required: true, message: "请输入验证码", trigger: "blur" }]
-};
-const passList = [
-  {
-    title: "验证原密码"
-  },
-  {
-    title: "设置新密码"
-  }
-];
-// 获取用户手机号
-const userPhone = computed(() => {
-  return localGet("iphone") || localGet("geeker-user")?.userInfo?.phone || "";
-});
-// 掩码显示手机号
-const maskedPhone = computed(() => {
-  if (!userPhone.value || userPhone.value.length !== 11) {
-    return "";
-  }
-  return userPhone.value.replace(/(\d{3})\d{4}(\d{4})/, "$1****$2");
-});
-// 实名认证表单数据
 const authForm = reactive({
   name: "",
-  idCard: ""
+  idCard: "",
+  zfbName: ""
 });
-
-// 提现密码表单数据
-const passwordForm = reactive({
-  password: "",
-  confirmPassword: ""
-});
-
 // 实名认证表单验证规则
 const authRules = reactive<FormRules>({
   name: [{ required: true, message: "请输入姓名", trigger: "blur" }],
+  zfbName: [{ required: true, message: "请输入支付宝账号", trigger: "blur" }],
   idCard: [
     { required: true, message: "请输入身份证号码", trigger: "blur" },
     {
@@ -220,7 +284,36 @@ const authRules = reactive<FormRules>({
     }
   ]
 });
+//实名认证 确认
+const handleConfirm = async () => {
+  if (!authFormRef.value) return;
+
+  // 表单验证
+  await authFormRef.value.validate(valid => {
+    if (valid) {
+      loading.value = true;
+      // 这里可以调用API提交实名认证信息
+      // 模拟API调用
+      setTimeout(() => {
+        loading.value = false;
+        ElMessage.success("实名认证提交成功");
+        dialogVisible.value = false;
+        goAuth.value = false;
+        // 重置表单
+        authFormRef.value?.resetFields();
+        // 这里可以更新认证状态或刷新页面数据
+      }, 1000);
+    }
+  });
+};
 
+//提现密码
+const withdrawPass = ref(true);
+const passwordFormRef = ref<FormInstance>();
+const passwordForm = reactive({
+  password: "",
+  confirmPassword: ""
+});
 // 提现密码表单验证规则
 const passwordRules = reactive<FormRules>({
   password: [
@@ -245,6 +338,75 @@ const passwordRules = reactive<FormRules>({
     }
   ]
 });
+//提现密码 确认
+const handlePasswordSubmit = async () => {
+  if (!passwordFormRef.value) return;
+
+  // 表单验证
+  await passwordFormRef.value.validate(valid => {
+    if (valid) {
+      passwordLoading.value = true;
+      // 这里可以调用API设置提现密码
+      // 模拟API调用
+      setTimeout(() => {
+        passwordLoading.value = false;
+        ElMessage.success("提现密码设置成功");
+        // 重置表单
+        passwordFormRef.value?.resetFields();
+      }, 1000);
+    }
+  });
+};
+//二次进入显示
+const twoEnterPage = ref(false);
+//提现密码    验证原密码
+const currentStep = ref(1);
+const passList = [
+  {
+    title: "验证原密码"
+  },
+  {
+    title: "设置新密码"
+  }
+];
+//下一步
+const nextStept = async () => {
+  currentStep.value = 2;
+};
+
+//收款账户
+const dialogVisibleZFB = ref(false);
+const handleGoZFB = async () => {
+  dialogVisibleZFB.value = true;
+};
+const handleConfirmZFB = async () => {
+  dialogVisibleZFB.value = false;
+};
+const getEditZfb = async () => {};
+const getDelZfb = async () => {};
+
+const passwordLoading = ref(false);
+const forgotPasswordVisible = ref(false);
+const forgotPasswordFormRef = ref<FormInstance>();
+const forgotPasswordForm = reactive({
+  verificationCode: "",
+  newPassword: ""
+});
+// 忘记密码表单验证规则
+const forgotPasswordRules: FormRules = {
+  verificationCode: [{ required: true, message: "请输入验证码", trigger: "blur" }]
+};
+// 获取用户手机号
+const userPhone = computed(() => {
+  return localGet("iphone") || localGet("geeker-user")?.userInfo?.phone || "";
+});
+// 掩码显示手机号
+const maskedPhone = computed(() => {
+  if (!userPhone.value || userPhone.value.length !== 11) {
+    return "";
+  }
+  return userPhone.value.replace(/(\d{3})\d{4}(\d{4})/, "$1****$2");
+});
 
 const handleTabClick = (tab: any) => {
   // 根据不同的标签页可以跳转到不同的页面或显示不同的内容
@@ -268,46 +430,6 @@ const handleCancel = () => {
     authFormRef.value.resetFields();
   }
 };
-
-const handleConfirm = async () => {
-  if (!authFormRef.value) return;
-
-  // 表单验证
-  await authFormRef.value.validate(valid => {
-    if (valid) {
-      loading.value = true;
-      // 这里可以调用API提交实名认证信息
-      // 模拟API调用
-      setTimeout(() => {
-        loading.value = false;
-        ElMessage.success("实名认证提交成功");
-        dialogVisible.value = false;
-        // 重置表单
-        authFormRef.value?.resetFields();
-        // 这里可以更新认证状态或刷新页面数据
-      }, 1000);
-    }
-  });
-};
-
-const handlePasswordSubmit = async () => {
-  if (!passwordFormRef.value) return;
-
-  // 表单验证
-  await passwordFormRef.value.validate(valid => {
-    if (valid) {
-      passwordLoading.value = true;
-      // 这里可以调用API设置提现密码
-      // 模拟API调用
-      setTimeout(() => {
-        passwordLoading.value = false;
-        ElMessage.success("提现密码设置成功");
-        // 重置表单
-        passwordFormRef.value?.resetFields();
-      }, 1000);
-    }
-  });
-};
 </script>
 
 <style scoped lang="scss">
@@ -414,62 +536,103 @@ const handlePasswordSubmit = async () => {
     }
   }
 }
+.auth-button {
+  padding: 22px 35px;
+  font-size: 16px;
+  font-weight: 500;
+  background-color: #6c8ff8;
+  border: none;
+  border-radius: 6px;
+  transition: all 0.3s;
+}
 
 // 主内容区
 .content-section {
   display: flex;
   flex: 1;
-
-  // align-items: center;
   justify-content: center;
   min-height: 400px;
   background-color: #ffffff;
+  .content-wrapper-realName {
+    width: 100%;
+    border: 1px solid red;
+    .goAuthBtn {
+      display: flex;
+      justify-content: center;
+      padding: 180px 0 0;
+    }
+    .auth-div {
+      padding-top: 10px;
+      padding-left: 41px;
+      border: 1px solid red;
+      .auth-row {
+        padding: 10px 0;
+      }
+    }
+  }
   .content-wrapper {
     display: flex;
-
-    // align-items: center;
     justify-content: center;
     width: 100%;
     padding: 40px 24px;
-    .auth-button {
-      padding: 22px 35px;
-      font-size: 16px;
-      font-weight: 500;
-      background-color: #6c8ff8;
-      border: none;
-      border-radius: 6px;
-      transition: all 0.3s;
+    .zfb-wrapper {
+      display: flex;
+      justify-content: space-between;
+      width: 800px;
+      height: 80px;
+      padding: 0 20px;
+      border: 1px solid #aaaaaa;
+      border-radius: 8px;
+      .operate {
+        display: flex;
+        align-items: center;
+        color: #6c8ff8;
+        div {
+          margin-left: 20px;
+        }
+      }
+      .zfb-left {
+        display: flex;
+        align-items: center;
+      }
+      .zfbIcon {
+        width: 60px;
+        height: 60px;
+        margin-right: 10px;
+      }
     }
   }
   .password-form-wrapper {
     width: 100%;
-    max-width: 500px;
-    padding: 40px;
+    padding-left: 15px;
     background-color: #ffffff;
-    border: 1px solid red;
     border-radius: 8px;
+    .form-wrapper {
+      width: 400px;
+      margin: 30px auto;
+    }
     .password-input {
       width: 100%;
     }
-    .submit-button {
-      width: 100%;
-      padding: 12px;
-      margin-top: 20px;
-      font-size: 16px;
-      font-weight: 500;
-      background-color: #6c8ff8;
-      border: none;
-      border-radius: 6px;
-    }
     :deep(.el-form-item__label) {
       font-weight: 500;
       color: #303133;
     }
   }
+  .submit-button {
+    width: 100%;
+    padding: 22px 35px;
+    margin-top: 20px;
+    font-size: 16px;
+    font-weight: 500;
+    background-color: #6c8ff8;
+    border: none;
+    border-radius: 6px;
+  }
   .password-form-wrapper-step {
-    width: 600px;
+    width: 480px;
     .form-wrapper {
-      width: 600px;
+      width: 400px;
       margin-top: 40px;
     }
     .forget-password {

+ 152 - 0
src/views/financialManagement/reconciled.vue

@@ -0,0 +1,152 @@
+<template>
+  <div class="table-box">
+    <ProTable ref="proTable" :columns="columns" :request-api="getTableList" :init-param="initParam" :data-callback="dataCallback">
+      <!-- 表格操作 -->
+      <template #operation="scope">
+        <el-button type="primary" link @click="toDetail(scope.row)"> 查看详情 </el-button>
+      </template>
+    </ProTable>
+    <el-dialog v-model="dialogVisible" title="详情" width="500px">
+      <h3>火锅一人惨</h3>
+      <el-row>
+        <el-col :span="12"> 实际收益:+138.32 </el-col>
+        <el-col :span="12"> 技术服务费(3%):-138.32 </el-col>
+      </el-row>
+      <el-row>
+        <el-col :span="12"> 售价:+138.32 </el-col>
+      </el-row>
+      <h3>订单信息</h3>
+      <div>
+        <div>券码:</div>
+        <div>下单时间:</div>
+        <div>验券时间:</div>
+        <div>入账时间:</div>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup lang="tsx" name="voucherManagement">
+import { onActivated, onMounted, reactive, ref } from "vue";
+import ProTable from "@/components/ProTable/index.vue";
+import { ColumnProps, ProTableInstance } from "@/components/ProTable/interface";
+import { getPaymentCycle } from "@/api/modules/homeEntry";
+import { localGet } from "@/utils";
+const dialogVisible = ref(true);
+const toDetail = (row: any) => {
+  dialogVisible.value = true;
+};
+// ProTable 实例(需要在使用它的地方之前定义)
+const proTable = ref<ProTableInstance>();
+
+// 表格配置项
+const columns = reactive<ColumnProps<any>[]>([
+  {
+    prop: "name",
+    label: "商品名称",
+    search: {
+      el: "input"
+    }
+  },
+  {
+    prop: "price",
+    label: "券码",
+    render: (scope: any) => {
+      return scope.row.price ? `¥${scope.row.price}` : "--";
+    }
+  },
+  {
+    prop: "saleNum",
+    label: "入账时间",
+    render: scope => {
+      return scope.row.saleNum === null || !scope.row.saleNum ? "--" : scope.row.saleNum;
+    }
+  },
+  { prop: "operation", label: "操作", fixed: "right", width: 330 }
+]);
+
+// 如果表格需要初始化请求参数,直接定义传给 ProTable (之后每次请求都会自动带上该参数,此参数更改之后也会一直带上,改变此参数会自动刷新表格数据)
+const initParam = reactive({
+  storeId: localGet("createdId"),
+  incomeType: 0,
+  paymentType: 1,
+  startTime: null,
+  endTime: null
+});
+// 页面加载时触发查询
+onMounted(async () => {
+  proTable.value?.getTableList();
+});
+
+// 从其他页面返回时触发查询
+onActivated(() => {
+  proTable.value?.getTableList();
+});
+
+// dataCallback 是对于返回的表格数据做处理,如果你后台返回的数据不是 list && total 这些字段,可以在这里进行处理成这些字段
+// 或者直接去 hooks/useTable.ts 文件中把字段改为你后端对应的就行
+const dataCallback = (data: any) => {
+  return {
+    list: data.records,
+    total: data.total
+  };
+};
+
+// 如果你想在请求之前对当前请求参数做一些操作,可以自定义如下函数:params 为当前所有的请求参数(包括分页),最后返回请求列表接口
+// 默认不做操作就直接在 ProTable 组件上绑定	:requestApi="getUserList"
+const getTableList = (params: any) => {
+  let newParams = JSON.parse(JSON.stringify(params));
+  return getPaymentCycle(newParams);
+};
+</script>
+
+<style lang="scss" scoped>
+// 在组件样式中添加
+.date-range {
+  display: block; // 确保换行生效
+  padding: 0 8px; // 可选:增加内边距
+  word-wrap: break-word; // 长单词内换行
+  white-space: normal; // 允许自然换行
+}
+.table-header-btn {
+  .button {
+    margin-bottom: 10px;
+  }
+  .tabs {
+    :deep(.el-tabs__nav-wrap::after) {
+      height: 0;
+    }
+  }
+}
+.reject-reason-content {
+  padding: 20px 0;
+  .reject-reason-item {
+    display: flex;
+    margin-bottom: 20px;
+    &:last-child {
+      margin-bottom: 0;
+    }
+    .reject-reason-label {
+      flex-shrink: 0;
+      min-width: 100px;
+      font-size: 14px;
+      font-weight: 500;
+      color: #606266;
+    }
+    .reject-reason-value {
+      flex: 1;
+      font-size: 14px;
+      color: #303133;
+      word-break: break-word;
+      &.reject-reason-text {
+        min-height: 80px;
+        padding: 12px;
+        line-height: 1.6;
+        white-space: pre-wrap;
+        background-color: #f5f7fa;
+        border-radius: 4px;
+      }
+    }
+  }
+}
+</style>

+ 153 - 0
src/views/financialManagement/unposted.vue

@@ -0,0 +1,153 @@
+<template>
+  <div class="table-box">
+    <ProTable ref="proTable" :columns="columns" :request-api="getTableList" :init-param="initParam" :data-callback="dataCallback">
+      <!-- 表格操作 -->
+      <template #operation="scope">
+        <el-button type="primary" link @click="toDetail(scope.row)"> 查看详情 </el-button>
+      </template>
+    </ProTable>
+    <el-dialog v-model="dialogVisible" title="详情" width="500px">
+      <h3>火锅一人惨</h3>
+      <el-row>
+        <el-col :span="12"> 实际收益:+138.32 </el-col>
+        <el-col :span="12"> 技术服务费(3%):-138.32 </el-col>
+      </el-row>
+      <el-row>
+        <el-col :span="12"> 售价:+138.32 </el-col>
+      </el-row>
+      <h3>订单信息</h3>
+      <div>
+        <div>券码:</div>
+        <div>下单时间:</div>
+        <div>验券时间:</div>
+        <div>入账时间:</div>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup lang="tsx" name="voucherManagement">
+import { computed, onActivated, onMounted, reactive, ref, watch } from "vue";
+import { useRouter } from "vue-router";
+import type { FormInstance, FormRules } from "element-plus";
+import { ElMessage } from "element-plus";
+import ProTable from "@/components/ProTable/index.vue";
+import { ColumnProps, ProTableInstance } from "@/components/ProTable/interface";
+import { getPaymentCycle } from "@/api/modules/homeEntry";
+import { ElMessageBox } from "element-plus/es";
+import { localGet } from "@/utils";
+const dialogVisible = ref(true);
+// ProTable 实例(需要在使用它的地方之前定义)
+const proTable = ref<ProTableInstance>();
+
+// 表格配置项
+const columns = reactive<ColumnProps<any>[]>([
+  {
+    prop: "name",
+    label: "商品名称",
+    search: {
+      el: "input"
+    }
+  },
+  {
+    prop: "price",
+    label: "券码",
+    render: (scope: any) => {
+      return scope.row.price ? `¥${scope.row.price}` : "--";
+    }
+  },
+  {
+    prop: "saleNum",
+    label: "入账时间",
+    render: scope => {
+      return scope.row.saleNum === null || !scope.row.saleNum ? "--" : scope.row.saleNum;
+    }
+  },
+  { prop: "operation", label: "操作", fixed: "right", width: 330 }
+]);
+
+// 如果表格需要初始化请求参数,直接定义传给 ProTable (之后每次请求都会自动带上该参数,此参数更改之后也会一直带上,改变此参数会自动刷新表格数据)
+const initParam = reactive({
+  storeId: localGet("createdId"),
+  incomeType: 0,
+  paymentType: 0,
+  startTime: null,
+  endTime: null
+});
+// 页面加载时触发查询
+onMounted(async () => {
+  proTable.value?.getTableList();
+});
+
+// 从其他页面返回时触发查询
+onActivated(() => {
+  proTable.value?.getTableList();
+});
+
+// dataCallback 是对于返回的表格数据做处理,如果你后台返回的数据不是 list && total 这些字段,可以在这里进行处理成这些字段
+// 或者直接去 hooks/useTable.ts 文件中把字段改为你后端对应的就行
+const dataCallback = (data: any) => {
+  return {
+    list: data.records,
+    total: data.total
+  };
+};
+
+// 如果你想在请求之前对当前请求参数做一些操作,可以自定义如下函数:params 为当前所有的请求参数(包括分页),最后返回请求列表接口
+// 默认不做操作就直接在 ProTable 组件上绑定	:requestApi="getUserList"
+const getTableList = (params: any) => {
+  let newParams = JSON.parse(JSON.stringify(params));
+  return getPaymentCycle(newParams);
+};
+</script>
+
+<style lang="scss" scoped>
+// 在组件样式中添加
+.date-range {
+  display: block; // 确保换行生效
+  padding: 0 8px; // 可选:增加内边距
+  word-wrap: break-word; // 长单词内换行
+  white-space: normal; // 允许自然换行
+}
+.table-header-btn {
+  .button {
+    margin-bottom: 10px;
+  }
+  .tabs {
+    :deep(.el-tabs__nav-wrap::after) {
+      height: 0;
+    }
+  }
+}
+.reject-reason-content {
+  padding: 20px 0;
+  .reject-reason-item {
+    display: flex;
+    margin-bottom: 20px;
+    &:last-child {
+      margin-bottom: 0;
+    }
+    .reject-reason-label {
+      flex-shrink: 0;
+      min-width: 100px;
+      font-size: 14px;
+      font-weight: 500;
+      color: #606266;
+    }
+    .reject-reason-value {
+      flex: 1;
+      font-size: 14px;
+      color: #303133;
+      word-break: break-word;
+      &.reject-reason-text {
+        min-height: 80px;
+        padding: 12px;
+        line-height: 1.6;
+        white-space: pre-wrap;
+        background-color: #f5f7fa;
+        border-radius: 4px;
+      }
+    }
+  }
+}
+</style>