Explorar el Código

Merge remote-tracking branch 'origin/main'

吴sir hace 4 meses
padre
commit
f5ffc47def

+ 8 - 0
src/App.vue

@@ -91,4 +91,12 @@ body {
     transform: rotate(360deg);
   }
 }
+
+// 文字主题色加重色
+.boldTxt{
+  color: rgb(@blue_0);
+}
+.txtPointer{
+  cursor: pointer;
+}
 </style>

+ 1 - 1
src/api/axios.js

@@ -5,7 +5,7 @@ import { useSystemStore } from "@/store/modules/systemStore";
 
 import { fn_logout } from "@/utils";
 
-// console.log(import.meta.env.BASE_URL)
+console.log(import.meta.env.BASE_URL)
 const axiosInstance = axios.create({
   // baseURL: `${import.meta.env.PROD ? import.meta.env.VITE_PRO_PATH : ''}/api`,
   baseURL: import.meta.env.BASE_URL + "api",

+ 55 - 0
src/api/finance.js

@@ -0,0 +1,55 @@
+import service from './axios'
+
+// 查询充值记录
+export function getTopUpRecordList(data) {
+    return service({
+        url: '/admin/platform/topUpRecord',
+        method: 'post',
+        data
+    })
+}
+// 充值
+export function topUpAs(data) {
+    return service({
+        url: '/admin/platform/topUp',
+        method: 'post',
+        data
+    })
+}
+// 获取客户列表
+export function getCustomerList(data) {
+    return service({
+        url: '/admin/platform/customerList',
+        method: 'post',
+        data
+    })
+}
+// 客户流量消耗明细
+export function getSimConsumptionDetailsList(data) {
+    return service({
+        url: '/admin/platform/simConsumptionDetails',
+        method: 'post',
+        data
+    })
+}
+// 客户流量消耗明细-详情
+export function getUserSimInfo(params) {
+    return service({
+        url: '/admin/platform/userSimInfo',
+        method: 'get',
+        params
+    })
+}
+// 客户端-账户余额卡片
+export function getWalletCard(params) {
+    return service({
+        url: '/admin/client/walletCard',
+        method: 'get',
+        params
+    })
+}
+
+// 客户详情
+export  function  deleteMessUser(params){
+    return service.get('admin/platform/customerInfo', {params})
+}

+ 39 - 10
src/components/upload/index.vue

@@ -1,7 +1,7 @@
 <template>
   <a-upload :show-file-list="true" :custom-request="handelUpload == null ? customRequest : handelUpload"
     :list-type="listType" :file-list="fileList" :limit="minx" @before-remove="beforeRemove" :show-remove-button="showRemoveButton" :show-cancel-button="false"
-    :image-preview="imagePreview" :accept="accept" />
+    :image-preview="imagePreview" :accept="accept" @before-upload="beforeUpload" />
 </template>
 
 <script setup>
@@ -9,6 +9,7 @@ import { toRef, ref, watch, watchEffect, onMounted } from 'vue';
 import { useSystemStore } from '@/store/modules/systemStore';
 import { Modal } from "@arco-design/web-vue";
 import { useI18n } from 'vue-i18n';
+import { Message } from "@arco-design/web-vue";
 
 const systemStore = useSystemStore();
 const { t } = useI18n();
@@ -43,7 +44,7 @@ const customRequest = async (option) => {
 const props = defineProps({
   modelValue: {
     type: [String, Array],
-    default: '',
+    default: "",
   },
   minx: {
     type: Number,
@@ -68,7 +69,11 @@ const props = defineProps({
   showRemoveButton:{
     type: Boolean,
     default: true  // 是否显示删除按钮
-  }
+  },
+  beforeUpload: {
+    type: Boolean,
+    default: false,
+  },
 });
 
 // 使用 toRef 确保对 props 的访问是响应式的
@@ -78,7 +83,7 @@ const listType = toRef(props, 'listType');
 const imagePreview = toRef(props, 'imagePreview');
 const handelUpload = toRef(props, 'handelUpload');
 // 定义 emit,用于向外抛出事件
-const emit = defineEmits(['update:modelValue']);
+const emit = defineEmits(["update:modelValue"]);
 
 // 用于存储文件列表,初始化时显示传递给子组件的值
 const fileList = ref([]);
@@ -88,18 +93,24 @@ const fileList = ref([]);
 const beforeRemove = (file) => {
   return new Promise((resolve, reject) => {
     Modal.confirm({
-      title: $t('customer.confirmRemoveUpload'),
+      title: $t("customer.confirmRemoveUpload"),
       onOk: () => {
         // 更新 fileList 和 modelValue,移除删除的文件
-        fileList.value = fileList.value.filter(item => item.url !== file.url);
+        fileList.value = fileList.value.filter((item) => item.url !== file.url);
         if (minx.value === 1) {
-          emit('update:modelValue', fileList.value.length > 0 ? fileList.value[0].url : '');
+          emit(
+            "update:modelValue",
+            fileList.value.length > 0 ? fileList.value[0].url : ""
+          );
         } else {
-          emit('update:modelValue', fileList.value.map(res => res.url).join(','));
+          emit(
+            "update:modelValue",
+            fileList.value.map((res) => res.url).join(",")
+          );
         }
-        resolve(true);  // 确认删除
+        resolve(true); // 确认删除
       },
-      onCancel: () => reject('cancel') // 取消删除
+      onCancel: () => reject("cancel"), // 取消删除
     });
   });
 };
@@ -122,6 +133,24 @@ watchEffect(() => {
 onMounted(() => {
 
 })
+
+// 上传前校验
+const beforeUpload = (rawFile) => {
+  if(!props.beforeUpload) return true
+  const isAllowType =
+    rawFile.type === "image/png" ||
+    rawFile.type === "image/jpg" ||
+    rawFile.type === "image/jpeg";
+  if (!isAllowType) {
+    Message.error("图片仅支持jpg或png");
+    return false;
+  } else if (rawFile.size / 1024 / 1024 > 2) {
+    Message.error("图片不能大于2M");
+    return false;
+  }
+  return true;
+};
+
 </script>
 
 <style scoped>

+ 32 - 0
src/i18n/zh/financialManagement.js

@@ -0,0 +1,32 @@
+// 财务模块
+export default {
+    searchForm: {
+        name: '客户名称',
+        placeholder: '请输入客户名称',
+    },
+    recharge: '充值',
+    rechargeType: '充值类型',
+    lenovoInput: '联想输入',
+    rechargeAmount: '充值金额',
+    rechargeAmountPlace: '请输入充值金额',
+    remarks: '备注',
+    remarksPlace: '请输入',
+    voucher: '凭证',
+    uploadTip1: '建议上传尺寸为360*240px的图片',
+    uploadTip2: '图片仅支持jpg或png格式',
+    uploadTip3: '图片不得大于2M',
+    orderNumber: '序号',
+    customerId: '客户编号',
+    customerName: '客户名称',
+    customerAccount: '客户账号',
+    rechargeAmountTab: '充值金额(元)',
+    availableAmountTab: '账户可用余额(元)',
+    updatedAt: '更新时间',
+    offset: '抵充',
+    deduct: '消费扣除',
+    rulesa: {
+        status: '请选择充值类型',
+        userId: '请输入客户名称',
+        amount: '请输入充值金额',
+    }
+}

+ 3 - 1
src/i18n/zh/index.js

@@ -9,6 +9,7 @@ import customerPackage from './customerPackage'
 import lotCard from './lotCard'
 import tariffManagement from './tariffManagement'
 import flowPool from './flowPool'
+import financialManagement from './financialManagement'
 
 export default {
   login,
@@ -21,5 +22,6 @@ export default {
   customerPackage,
   lotCard,
   tariffManagement,
-  flowPool
+  flowPool,
+  financialManagement,
 }

+ 446 - 390
src/views/financialManagement/accountBalance/index.vue

@@ -1,465 +1,521 @@
 <!-- 账户余额-总览界面 -->
 <template>
-    <div class="customer-top-up">
-        <div class="item-box">
-            <div class="item-title">总览</div>
-            <div class="item-grid-box">
-                <div class="grid-item" v-for="item in 5" :key="item">
-                    <div class="grid-item-title">客户消费总金额/人名币</div>
-                    <div class="grid-item-num">
-                        <div class="item-num">48000</div>
-                        <div class="item-dw">元</div>
-                    </div>
-                </div>
-            </div>
+  <div class="customer-top-up">
+    <div class="item-box">
+      <div class="item-title">总览</div>
+      <div class="item-grid-box">
+        <div class="grid-item" v-for="(item, index) in cardList" :key="index">
+          <div class="grid-item-title">{{ item.name }}</div>
+          <div class="grid-item-num">
+            <div class="item-num">{{ item.value }}</div>
+            <div class="item-dw">{{ item.unit }}</div>
+          </div>
         </div>
-        <div class="item-box">
-            <div class="item-title">账单明细</div>
-            <!-- 搜索条件区 -->
-            <div class="search-section">
-                <a-form :model="searchForm" layout="inline">
-                    <a-form-item field="startTime" label="开始时间">
-                        <a-date-picker style="width: 220px; margin: 0 24px 24px 0;" show-time
-                            v-model="searchForm.startTime" :time-picker-props="{ defaultValue: '09:09:06' }"
-                            format="YYYY-MM-DD HH:mm:ss" @ok="onOkStart" />
-                    </a-form-item>
-                    <a-form-item field="endTime" label="结束时间">
-                        <a-date-picker style="width: 220px; margin: 0 24px 24px 0;" show-time
-                            v-model="searchForm.endTime" :time-picker-props="{ defaultValue: '09:09:06' }"
-                            format="YYYY-MM-DD HH:mm:ss" @ok="onOkEnd" />
-                    </a-form-item>
-                    <a-form-item>
-                        <a-space>
-                            <a-button type="primary" @click="handleSearch">搜索</a-button>
-                            <a-button @click="resetSearch">重置</a-button>
-                        </a-space>
-                    </a-form-item>
-                </a-form>
+      </div>
+    </div>
+    <div class="item-box">
+      <div class="item-title">账单明细</div>
+      <!-- 搜索条件区 -->
+      <div class="search-section">
+        <a-form :model="searchForm" layout="inline">
+          <a-form-item field="startTime" label="开始时间">
+            <a-date-picker
+              style="width: 220px; margin: 0 24px 24px 0"
+              show-time
+              v-model="searchForm.startTime"
+              :time-picker-props="{ defaultValue: '09:09:06' }"
+              format="YYYY-MM-DD HH:mm:ss"
+              @ok="onOkStart"
+            />
+          </a-form-item>
+          <a-form-item field="endTime" label="结束时间">
+            <a-date-picker
+              style="width: 220px; margin: 0 24px 24px 0"
+              show-time
+              v-model="searchForm.endTime"
+              :time-picker-props="{ defaultValue: '09:09:06' }"
+              format="YYYY-MM-DD HH:mm:ss"
+              @ok="onOkEnd"
+            />
+          </a-form-item>
+          <a-form-item>
+            <a-space>
+              <a-button type="primary" @click="handleSearch">搜索</a-button>
+              <a-button @click="resetSearch">重置</a-button>
+            </a-space>
+          </a-form-item>
+        </a-form>
+      </div>
+      <!-- 数据表格 -->
+      <a-table
+        row-key="customerName"
+        :columns="columns"
+        :data="tableData"
+        :pagination="pagination"
+      >
+        <template #detail="{ record }">
+          <a-button @click="openDetail(record)" type="text">查看</a-button>
+          <a-button @click="openTopsUp(record)" type="text">结算</a-button>
+        </template>
+        <template #status="{ record }">
+          <div
+            v-if="record.status == 1"
+            class="status-table"
+            style="color: rgba(43, 164, 113, 1)"
+          >
+            <div
+              class="status-icon"
+              style="background-color: rgba(43, 164, 113, 1)"
+            ></div>
+            已出账
+          </div>
+          <div v-if="record.status == 2" class="status-table">
+            <div class="status-icon"></div>
+            欠费中
+          </div>
+        </template>
+      </a-table>
+    </div>
+    <a-modal
+      v-model:visible="showAdd"
+      title="结算"
+      @cancel="showAdd = false"
+      @before-ok="submitAdd"
+      okText="确定"
+      width="800px"
+      cancelText="关闭"
+    >
+      <a-form :model="formAdd" auto-label-width>
+        <a-form-item field="customerName" label="客户名称">
+          <!-- <a-input v-model="formAdd.customerName" placeholder="请输入客户" /> -->
+          泰国栗
+        </a-form-item>
+        <a-form-item field="money" label="当前帐单应收金额">
+          <!-- <a-input-number v-model="formAdd.money" placeholder="请输入金额" class="input-demo" :min="10"
+                        :max="100" /> -->
+          1242113.00元
+        </a-form-item>
+        <a-form-item field="topsUpOpinion" label="结算金额">
+          <!-- <a-textarea placeholder="请输入" v-model="formAdd.topsUpOpinion" allow-clear /> -->
+          123111.00元
+        </a-form-item>
+        <a-form-item field="fileList" label="打款凭证">
+          <a-upload
+            action="/"
+            :default-file-list="formAdd.fileList"
+            style="width: auto; max-width: 400px"
+          />
+          <div class="text-box">
+            <div class="text">1.请上传客户银行转账等同等性质的支付凭证文件</div>
+            <div class="text">2.图片仅支持jpg或png格式</div>
+            <div class="text">3.图片不得大于2M</div>
+          </div>
+        </a-form-item>
+      </a-form>
+    </a-modal>
+    <a-modal
+      v-model:visible="showDetail"
+      width="1000px"
+      title="订单详情"
+      :hide-cancel="true"
+      @cancel="detailCancel"
+    >
+      <div class="detail">
+        <div class="detail-box">
+          <div class="detail-title">账单信息(泰国李总)</div>
+          <div class="detail-item-box">
+            <div class="detail-item">
+              <div class="item-label">订单状态</div>
+              <div class="item-content" style="color: rgba(253, 63, 90, 1)">
+                欠款中
+              </div>
             </div>
-            <div class="audit-btn">
-                <a-button @click="openTopsUp" type="text">
-                    <template #icon>
-                        <icon-plus-circle />
-                    </template>
-                    <template #default>充值</template>
-                </a-button>
+            <div class="detail-item">
+              <div class="item-label">账单单号</div>
+              <div class="item-content">1223423422435343</div>
             </div>
-            <!-- 数据表格 -->
-            <a-table row-key="customerName" v-model:selectedKeys="selectedKeys" :row-selection="rowSelection"
-                :columns="columns" :data="tableData" :pagination="pagination" :scroll="{ x: '100%', y: '400px' }">
-                <template #detail="{ record }">
-                    <a-button @click="openDetail(record)" type="text">查看</a-button>
-                    <a-button @click="openTopsUp(record)" type="text">结算</a-button>
-                </template>
-                <template #status="{ record }">
-                    <div v-if="record.status == 1" class="status-table" style="color:rgba(43, 164, 113, 1);">
-                        <div class="status-icon" style="background-color: rgba(43, 164, 113, 1);"></div>
-                        已出账
-                    </div>
-                    <div v-if="record.status == 2" class="status-table">
-                        <div class="status-icon"></div>
-                        欠费中
-                    </div>
-                </template>
-            </a-table>
-        </div>
-        <a-modal v-model:visible="showAdd" title="结算" @cancel="showAdd = false" @before-ok="submitAdd" okText="确定"
-            width="800px" cancelText="关闭">
-            <a-form :model="formAdd" auto-label-width>
-                <a-form-item field="customerName" label="客户名称">
-                    <!-- <a-input v-model="formAdd.customerName" placeholder="请输入客户" /> -->
-                    泰国栗
-                </a-form-item>
-                <a-form-item field="money" label="当前帐单应收金额">
-                    <!-- <a-input-number v-model="formAdd.money" placeholder="请输入金额" class="input-demo" :min="10"
-                        :max="100" /> -->
-                    1242113.00元
-                </a-form-item>
-                <a-form-item field="topsUpOpinion" label="结算金额">
-                    <!-- <a-textarea placeholder="请输入" v-model="formAdd.topsUpOpinion" allow-clear /> -->
-                    123111.00元
-                </a-form-item>
-                <a-form-item field="fileList" label="打款凭证">
-                    <a-upload action="/" :default-file-list="formAdd.fileList" style="width: auto;max-width: 400px;" />
-                    <div class="text-box">
-                        <div class="text">
-                            1.请上传客户银行转账等同等性质的支付凭证文件
-                        </div>
-                        <div class="text">
-                            2.图片仅支持jpg或png格式
-                        </div>
-                        <div class="text">
-                            3.图片不得大于2M
-                        </div>
-                    </div>
-                </a-form-item>
-            </a-form>
-        </a-modal>
-        <a-modal v-model:visible="showDetail" width="1000px" title="订单详情" :hide-cancel="true" @cancel="detailCancel">
-            <div class="detail">
-                <div class="detail-box">
-                    <div class="detail-title">账单信息(泰国李总)</div>
-                    <div class="detail-item-box">
-                        <div class="detail-item">
-                            <div class="item-label">订单状态</div>
-                            <div class="item-content" style="color:rgba(253, 63, 90, 1);">欠款中</div>
-                        </div>
-                        <div class="detail-item">
-                            <div class="item-label">账单单号</div>
-                            <div class="item-content">1223423422435343</div>
-                        </div>
-                    </div>
-                    <div class="detail-item-box">
-                        <div class="detail-item">
-                            <div class="item-label">订单结算周期</div>
-                            <div class="item-content">2024-10-24~2025-10-23</div>
-                        </div>
-                        <div class="detail-item">
-                            <div class="item-label">出账日期</div>
-                            <div class="item-content">2024-10-24</div>
-                        </div>
-                    </div>
-                    <div class="detail-item-box">
-                        <div class="detail-item">
-                            <div class="item-label">结算时间</div>
-                            <div class="item-content">2024-10-24</div>
-                        </div>
-                        <div class="detail-item">
-                            <div class="item-label">账单结算金额</div>
-                            <div class="item-content">103849美金</div>
-                        </div>
-                    </div>
-                    <div class="detail-title">结算详情</div>
-                    <div class="js-detail" v-for="item in 4" :key="item">
-                        <div class="detail-item-box">
-                            <div class="detail-item">
-                                <div class="item-label">运营商</div>
-                                <div class="item-content" style="color:rgba(43, 164, 113, 1);">泰国AIS</div>
-                            </div>
-                        </div>
-                        <div class="detail-item-box">
-                            <div class="detail-item">
-                                <div class="item-label">套餐流量消耗</div>
-                                <div class="item-content">7129.76G</div>
-                            </div>
-                            <div class="detail-item">
-                                <div class="item-label">套餐流量计费方式</div>
-                                <div class="item-content">按单流量消耗计费</div>
-                            </div>
-                        </div>
-                        <div class="detail-item-box">
-                            <div class="detail-item">
-                                <div class="item-label">套餐流量价格</div>
-                                <div class="item-content">0.65美金/G</div>
-                            </div>
-                            <div class="detail-item">
-                                <div class="item-label">结算周期</div>
-                                <div class="item-content">月</div>
-                            </div>
-                        </div>
-                        <div class="detail-item-box">
-                            <div class="detail-item">
-                                <div class="item-label">叠加流量消耗</div>
-                                <div class="item-content">11244G</div>
-                            </div>
-                            <div class="detail-item">
-                                <div class="item-label">叠加流量计费方式</div>
-                                <div class="item-content">按周期计算</div>
-                            </div>
-                        </div>
-                        <div class="detail-item-box">
-                            <div class="detail-item">
-                                <div class="item-label">叠加流量价格</div>
-                                <div class="item-content">0.8美金/月</div>
-                            </div>
-                            <div class="detail-item">
-                                <div class="item-label">结算周期</div>
-                                <div class="item-content">月</div>
-                            </div>
-                        </div>
-                    </div>
-                </div>
-                <div class="detail-table">
-                    <a-table :columns="columnsDetail" :data="dataDetail" />
+          </div>
+          <div class="detail-item-box">
+            <div class="detail-item">
+              <div class="item-label">订单结算周期</div>
+              <div class="item-content">2024-10-24~2025-10-23</div>
+            </div>
+            <div class="detail-item">
+              <div class="item-label">出账日期</div>
+              <div class="item-content">2024-10-24</div>
+            </div>
+          </div>
+          <div class="detail-item-box">
+            <div class="detail-item">
+              <div class="item-label">结算时间</div>
+              <div class="item-content">2024-10-24</div>
+            </div>
+            <div class="detail-item">
+              <div class="item-label">账单结算金额</div>
+              <div class="item-content">103849美金</div>
+            </div>
+          </div>
+          <div class="detail-title">结算详情</div>
+          <div class="js-detail" v-for="item in 4" :key="item">
+            <div class="detail-item-box">
+              <div class="detail-item">
+                <div class="item-label">运营商</div>
+                <div class="item-content" style="color: rgba(43, 164, 113, 1)">
+                  泰国AIS
                 </div>
+              </div>
             </div>
-        </a-modal>
-    </div>
+            <div class="detail-item-box">
+              <div class="detail-item">
+                <div class="item-label">套餐流量消耗</div>
+                <div class="item-content">7129.76G</div>
+              </div>
+              <div class="detail-item">
+                <div class="item-label">套餐流量计费方式</div>
+                <div class="item-content">按单流量消耗计费</div>
+              </div>
+            </div>
+            <div class="detail-item-box">
+              <div class="detail-item">
+                <div class="item-label">套餐流量价格</div>
+                <div class="item-content">0.65美金/G</div>
+              </div>
+              <div class="detail-item">
+                <div class="item-label">结算周期</div>
+                <div class="item-content">月</div>
+              </div>
+            </div>
+            <div class="detail-item-box">
+              <div class="detail-item">
+                <div class="item-label">叠加流量消耗</div>
+                <div class="item-content">11244G</div>
+              </div>
+              <div class="detail-item">
+                <div class="item-label">叠加流量计费方式</div>
+                <div class="item-content">按周期计算</div>
+              </div>
+            </div>
+            <div class="detail-item-box">
+              <div class="detail-item">
+                <div class="item-label">叠加流量价格</div>
+                <div class="item-content">0.8美金/月</div>
+              </div>
+              <div class="detail-item">
+                <div class="item-label">结算周期</div>
+                <div class="item-content">月</div>
+              </div>
+            </div>
+          </div>
+          <div class="detail-title">入账订单列表</div>
+          <div class="detail-table">
+            <a-table
+              :columns="columnsDetail"
+              :data="dataDetail"
+              :pagination="pagination"
+            />
+          </div>
+        </div>
+      </div>
+    </a-modal>
+  </div>
 </template>
 <script setup>
-import { ref, reactive } from 'vue';
-import { Message } from '@arco-design/web-vue';
-const selectedKeys = ref([]);
-const rowSelection = reactive({
-    type: 'checkbox',
-    showCheckedAll: true,
-    onlyCurrent: false,
+import { ref, reactive, onMounted } from "vue";
+import { Message } from "@arco-design/web-vue";
+import { getWalletCard } from "@/api/finance.js";
+
+onMounted(() => {
+  getWalletCardFc();
 });
+
+const cardList = ref([
+  { name: "客户消费总金额/人民币", value: 0, unit: "元" },
+  { name: "本月应收金额/人民币", value: 0, unit: "元" },
+  { name: "客户总欠款金额/人民币", value: 0, unit: "元" },
+  { name: "本月消耗流量", value: 0, unit: "G" },
+  { name: "总消耗流量", value: 0, unit: "G" },
+]);
+
 const searchForm = reactive({
-    startTime: '',
-    endTime: ''
+  startTime: "",
+  endTime: "",
 });
 
 const columns = [
-    { title: '序号', dataIndex: 'index', align: 'center', render: ({ rowIndex }) => rowIndex + 1 },
-    {
-        title: '账单号', dataIndex: 'accountNumber', ellipsis: true,
-        tooltip: true,
-        width: 100
-    },
-    { title: '客户名称', dataIndex: 'customerName' },
-    { title: '结算金额(元)', dataIndex: 'money' },
-    { title: '消耗流量', dataIndex: 'deplete' },
-    { title: '账单生成时间', dataIndex: 'createTime' },
-    { title: '结算周期时间段', dataIndex: 'createTime' },
-    { title: '状态', slotName: 'status' },
-    { title: '详情', slotName: 'detail', align: 'center' },
+  {
+    title: "序号",
+    dataIndex: "index",
+    align: "center",
+    render: ({ rowIndex }) => rowIndex + 1,
+  },
+  {
+    title: "账单号",
+    dataIndex: "accountNumber",
+    ellipsis: true,
+    tooltip: true,
+    width: 100,
+  },
+  { title: "客户名称", dataIndex: "customerName" },
+  { title: "账单生成时间", dataIndex: "createTime" },
+  { title: "结算周期时间段", dataIndex: "createTime" },
+  { title: "结算金额", dataIndex: "money" },
+  { title: "消耗流量", dataIndex: "deplete" },
+  { title: "状态", slotName: "status" },
+  { title: "操作", slotName: "detail", align: "center" },
 ];
 const tableData = ref([
-    {
-        accountNumber: '13800138000',
-        customerName: '张三',
-        status: '1',
-        customerAccountNumber: 'jhl001',
-        money: '100美金',
-        deplete: '100G',
-        createTime: '2024-10-11'
-        // operate:'上传合同'
-    },
-    {
-        accountNumber: '13800138000',
-        customerName: '李四',
-        status: '2',
-        customerAccountNumber: 'jhl001',
-        money: '100美金',
-        deplete: '100G',
-        createTime: '2024-10-11'
-        // operate:'上传合同'
-    },
-    {
-        accountNumber: '13800138000',
-        customerName: '王五',
-        status: '2',
-        customerAccountNumber: 'jhl001',
-        money: '100美金',
-        deplete: '100G',
-        createTime: '2024-10-11'
-        // operate:'上传合同'
-    },
-    {
-        accountNumber: '13800138000',
-        customerName: '赵六',
-        status: '1',
-        customerAccountNumber: 'jhl001',
-        money: '100美金',
-        deplete: '100G',
-        createTime: '2024-10-11'
-        // operate:'上传合同'
-    },
-
+  {
+    accountNumber: "13800138000",
+    customerName: "张三",
+    status: "1",
+    customerAccountNumber: "jhl001",
+    money: "100美金",
+    deplete: "100G",
+    createTime: "2024-10-11",
+    // operate:'上传合同'
+  },
+  {
+    accountNumber: "13800138000",
+    customerName: "李四",
+    status: "2",
+    customerAccountNumber: "jhl001",
+    money: "100美金",
+    deplete: "100G",
+    createTime: "2024-10-11",
+    // operate:'上传合同'
+  },
+  {
+    accountNumber: "13800138000",
+    customerName: "王五",
+    status: "2",
+    customerAccountNumber: "jhl001",
+    money: "100美金",
+    deplete: "100G",
+    createTime: "2024-10-11",
+    // operate:'上传合同'
+  },
+  {
+    accountNumber: "13800138000",
+    customerName: "赵六",
+    status: "1",
+    customerAccountNumber: "jhl001",
+    money: "100美金",
+    deplete: "100G",
+    createTime: "2024-10-11",
+    // operate:'上传合同'
+  },
 ]);
 const pagination = reactive({
-    total: tableData.value.length,
-    current: 1,
-    pageSize: 10,
+  total: tableData.value.length,
+  current: 1,
+  pageSize: 10,
 });
 const handleSearch = () => {
-    console.log('Search form data:', searchForm);
-    Message.success('执行搜索操作');
+  console.log("Search form data:", searchForm);
+  Message.success("执行搜索操作");
 };
 
 const resetSearch = () => {
-    Object.keys(searchForm).forEach(key => {
-        if (Array.isArray(searchForm[key])) {
-            searchForm[key] = [];
-        } else {
-            searchForm[key] = null;
-        }
-    });
-    Message.success('搜索条件已重置');
+  Object.keys(searchForm).forEach((key) => {
+    if (Array.isArray(searchForm[key])) {
+      searchForm[key] = [];
+    } else {
+      searchForm[key] = null;
+    }
+  });
+  Message.success("搜索条件已重置");
 };
 const options = [
-    { label: '充值', value: '1' },
-    { label: '抵充', value: '2' },
-    { label: '消费扣除', value: '3' },
+  { label: "充值", value: "1" },
+  { label: "抵充", value: "2" },
+  { label: "消费扣除", value: "3" },
 ];
 const openTopsUp = () => {
-    showAdd.value = true;
-}
+  showAdd.value = true;
+};
 const showAdd = ref(false);
 const formAdd = reactive({
-    customerName: '',
-    cardType: '',
-    money: '',
-    status: '',
-    topsUpOpinion: '',
-    fileList: []
-})
+  customerName: "",
+  cardType: "",
+  money: "",
+  status: "",
+  topsUpOpinion: "",
+  fileList: [],
+});
 const submitAdd = () => {
-    window.setTimeout(() => {
-        showAdd.value = false;
-    }, 1000)
-}
+  window.setTimeout(() => {
+    showAdd.value = false;
+  }, 1000);
+};
 // 选择时间
 const onOkStart = () => {
-    console.log(searchForm.startTime, '开始时间')
+  console.log(searchForm.startTime, "开始时间");
 };
 const onOkEnd = () => {
-    console.log(searchForm.endTime, '结束时间')
+  console.log(searchForm.endTime, "结束时间");
 };
 const showDetail = ref(false);
 const openDetail = () => {
-    showDetail.value = true;
-}
-const detailCancel = () => {
-}
+  showDetail.value = true;
+};
+const detailCancel = () => {};
+
+const getWalletCardFc = async () => {
+  const { data } = await getWalletCard();
+  cardList.value[0].value = data.rechargeAmount;
+  cardList.value[1].value = data.availableAmount;
+  cardList.value[2].value = data.oweAmount;
+  cardList.value[3].value = data.dataUsage;
+};
 </script>
 <style scoped lang="less">
 .customer-top-up {
-    padding: 20px;
+  padding: 20px;
 
-    .search-section {
-        margin-bottom: 20px;
-    }
+  .search-section {
+    margin-bottom: 20px;
+  }
 
-    .audit-btn {
-        margin-bottom: 10px;
-    }
+  .audit-btn {
+    margin-bottom: 10px;
+  }
 }
 
 .text-box {
-    width: 100%;
-    margin-left: 10px;
+  width: 100%;
+  margin-left: 10px;
 
-    .text {
-        font-family: PingFang SC;
-        font-size: 12px;
-        font-weight: 400;
-        line-height: 19px;
-        color: rgba(153, 153, 153, 1);
-        text-align: left;
-    }
+  .text {
+    font-family: PingFang SC;
+    font-size: 12px;
+    font-weight: 400;
+    line-height: 19px;
+    color: rgba(153, 153, 153, 1);
+    text-align: left;
+  }
 }
 
 .item-box {
-    margin-bottom: 20px;
+  margin-bottom: 20px;
 
-    .item-title {
-        font-family: PingFang SC;
-        font-size: 20px;
-        font-weight: 400;
-        line-height: 28px;
-        color: rgba(0, 0, 0, 0.9);
-        margin-bottom: 10px;
-    }
+  .item-title {
+    font-family: PingFang SC;
+    font-size: 20px;
+    font-weight: 400;
+    line-height: 28px;
+    color: rgba(0, 0, 0, 0.9);
+    margin-bottom: 10px;
+  }
 
-    .item-grid-box {
-        display: grid;
-        grid-template-columns: repeat(auto-fill, minmax(400px, 1fr));
-        grid-gap: 20px;
+  .item-grid-box {
+    display: grid;
+    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
+    grid-gap: 20px;
 
-        .grid-item {
-            background: rgba(247, 247, 247, 1);
-            padding: 20px;
-            box-sizing: border-box;
-            border-radius: 6px;
-            box-shadow: 0px 1px 2px 0px rgba(0, 0, 0, 0.1);
+    .grid-item {
+      background: rgba(247, 247, 247, 1);
+      padding: 20px;
+      box-sizing: border-box;
+      border-radius: 6px;
+      box-shadow: 0px 1px 2px 0px rgba(0, 0, 0, 0.1);
 
-            .grid-item-title {
-                font-family: PingFang SC;
-                font-size: 14px;
-                font-weight: 400;
-                line-height: 22px;
-                text-align: left;
-                color: rgba(0, 0, 0, 0.6);
-            }
+      .grid-item-title {
+        font-family: PingFang SC;
+        font-size: 14px;
+        font-weight: 400;
+        line-height: 22px;
+        text-align: left;
+        color: rgba(0, 0, 0, 0.6);
+      }
 
-            .grid-item-num {
-                display: flex;
-                justify-content: space-between;
-                align-items: center;
-                font-family: PingFang SC;
-                font-size: 28px;
-                font-weight: 400;
-                line-height: 36px;
-                color: rgba(0, 0, 0, 0.9);
+      .grid-item-num {
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        font-family: PingFang SC;
+        font-size: 28px;
+        font-weight: 400;
+        line-height: 36px;
+        color: rgba(0, 0, 0, 0.9);
 
-                .item-num {}
+        .item-num {
+        }
 
-                .item-dw {}
-            }
+        .item-dw {
         }
+      }
     }
+  }
 }
 
 .status-table {
-    display: flex;
-    align-items: center;
-    //styleName: Body/Medium;
-    font-family: PingFang SC;
-    font-size: 14px;
-    font-weight: 400;
-    line-height: 22px;
-    text-align: left;
-    color: rgba(253, 63, 90, 1);
+  display: flex;
+  align-items: center;
+  //styleName: Body/Medium;
+  font-family: PingFang SC;
+  font-size: 14px;
+  font-weight: 400;
+  line-height: 22px;
+  text-align: left;
+  color: rgba(253, 63, 90, 1);
 
-    .status-icon {
-        width: 6px;
-        height: 6px;
-        border-radius: 50%;
-        margin-right: 5px;
-        background: rgba(253, 63, 90, 1);
-    }
+  .status-icon {
+    width: 6px;
+    height: 6px;
+    border-radius: 50%;
+    margin-right: 5px;
+    background: rgba(253, 63, 90, 1);
+  }
 }
 
 .detail {
-    height: 600px;
-    overflow-y: auto;
+  height: 600px;
+  overflow-y: auto;
 
-    .detail-box {
-        .detail-title {
-            font-family: PingFang SC;
-            font-size: 20px;
-            font-weight: 400;
-            line-height: 28px;
-            text-align: left;
-            color: rgba(0, 0, 0, 0.9);
-            margin-bottom: 20px;
-        }
+  .detail-box {
+    .detail-title {
+      font-family: PingFang SC;
+      font-size: 20px;
+      font-weight: 400;
+      line-height: 28px;
+      text-align: left;
+      color: rgba(0, 0, 0, 0.9);
+      margin-bottom: 20px;
+    }
 
-        .detail-item-box {
-            display: flex;
-            justify-content: space-between;
-            align-items: center;
-            margin-bottom: 20px;
+    .detail-item-box {
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      margin-bottom: 20px;
 
-            .detail-item {
-                //styleName: Body/Medium;
-                font-family: PingFang SC;
-                font-size: 14px;
-                font-weight: 400;
-                line-height: 22px;
-                text-align: left;
-                display: flex;
-                align-items: center;
-                min-width: 350px;
+      .detail-item {
+        //styleName: Body/Medium;
+        font-family: PingFang SC;
+        font-size: 14px;
+        font-weight: 400;
+        line-height: 22px;
+        text-align: left;
+        display: flex;
+        align-items: center;
+        min-width: 350px;
 
-                .item-label {
-                    color: rgba(0, 0, 0, 0.4);
-                    width: 120px;
-                    text-align: right;
-                    margin-right: 10px;
-                }
+        .item-label {
+          color: rgba(0, 0, 0, 0.4);
+          width: 120px;
+          text-align: right;
+          margin-right: 10px;
+        }
 
-                .item-content {
-                    color: rgba(51, 51, 51, 1);
-                }
-            }
+        .item-content {
+          color: rgba(51, 51, 51, 1);
         }
+      }
     }
+  }
 
-    .detail-table {
-        margin-top: 20px;
-    }
+  .detail-table {
+    margin-top: 20px;
+  }
 }
 </style>

+ 341 - 170
src/views/financialManagement/customerTopsUp/index.vue

@@ -1,205 +1,376 @@
 <!-- 客户充值界面 -->
 <template>
-    <div class="customer-top-up">
-        <!-- 搜索条件区 -->
-        <div class="search-section">
-            <a-form :model="searchForm" layout="inline">
-                <a-form-item field="customerName" label="客户名称">
-                    <a-input v-model="searchForm.customerName" placeholder="请输入客户名称" allow-clear />
-                </a-form-item>
-                <a-form-item>
-                    <a-space>
-                        <a-button type="primary" @click="handleSearch">搜索</a-button>
-                        <a-button @click="resetSearch">重置</a-button>
-                    </a-space>
-                </a-form-item>
-            </a-form>
-        </div>
-        <div class="audit-btn">
-            <a-button @click="openTopsUp" type="text">
-                <template #icon>
-                    <icon-plus-circle />
-                </template>
-                <template #default>充值</template>
-            </a-button>
-        </div>
-        <!-- 数据表格 -->
-        <a-table row-key="customerName" v-model:selectedKeys="selectedKeys" :row-selection="rowSelection"
-            :columns="columns" :data="tableData" :pagination="pagination" :scroll="{ x: '100%', y: '400px' }">
-        </a-table>
-        <a-modal v-model:visible="showAdd" title="新增" @cancel="showAdd = false" @before-ok="submitAdd" okText="确定"
-            width="800px" cancelText="关闭">
-            <a-form :model="formAdd" auto-label-width>
-                <a-form-item field="topsUpStatus" label="充值类型">
-                    <a-radio-group v-model="formAdd.topsUpStatus" :options="options" />
-                </a-form-item>
-                <a-form-item field="customerName" label="客户名称">
-                    <a-input v-model="formAdd.customerName" placeholder="请输入客户" />
-                </a-form-item>
-                <a-form-item field="money" label="充值金额">
-                    <!-- <a-input v-model="formAdd.money" placeholder="请输入金额" /> -->
-                    <a-input-number v-model="formAdd.money" placeholder="请输入金额" class="input-demo" :min="10"
-                        :max="100" />
-                </a-form-item>
-                <a-form-item field="topsUpOpinion" label="备注">
-                    <a-textarea placeholder="请输入" v-model="formAdd.topsUpOpinion" allow-clear />
-                </a-form-item>
-                <a-form-item field="fileList" label="凭证">
-                    <a-upload action="/" :default-file-list="formAdd.fileList" style="width: auto;max-width: 400px;" />
-                    <div class="text-box">
-                        <div class="text">
-                            1.建议上传尺寸为360*240px的图片
-                        </div>
-                        <div class="text">
-                            2.图片仅支持jpg或png格式
-                        </div>
-                        <div class="text">
-                            3.图片不得大于2M
-                        </div>
-                    </div>
-                </a-form-item>
-            </a-form>
-        </a-modal>
+  <div class="customer-top-up">
+    <!-- 搜索条件区 -->
+    <div class="search-section">
+      <a-form ref="formRef" :model="searchForm" layout="inline">
+        <a-form-item
+          field="name"
+          :label="$t('financialManagement.searchForm.name')"
+        >
+          <a-input
+            v-model="searchForm.name"
+            :placeholder="$t('financialManagement.searchForm.placeholder')"
+            allow-clear
+          />
+        </a-form-item>
+        <a-form-item>
+          <a-space>
+            <a-button type="primary" @click="handleSearch">搜索</a-button>
+            <a-button @click="resetSearch">重置</a-button>
+          </a-space>
+        </a-form-item>
+      </a-form>
     </div>
+    <div class="audit-btn">
+      <a-button @click="openTopsUp" type="text">
+        <template #icon>
+          <icon-plus-circle />
+        </template>
+        <template #default>{{ $t("financialManagement.recharge") }}</template>
+      </a-button>
+    </div>
+    <!-- 数据表格 -->
+    <a-table
+      row-key="id"
+      :columns="columns"
+      :data="tableData"
+      :pagination="pagination"
+      @page-change="onPageChange"
+      @page-size-change="onPageSizeChange"
+      :filter-icon-align-left="true"
+    >
+      <template #name="{ record }">
+        <div class="boldTxt">{{ record.name }}</div>
+      </template>
+      <template #status="{ record }">
+        <div>{{ handleStatusTxt(record.status) }}</div>
+      </template>
+    </a-table>
+    <a-modal
+      :visible="showAdd"
+      :title="$t('financialManagement.recharge')"
+      @cancel="showAdd = false"
+      @ok="submitAdd"
+      okText="确定"
+      width="800px"
+      cancelText="关闭"
+      :mask-closable="false"
+      :loading="okLoading"
+      unmount-on-close
+    >
+      <a-form ref="addFormRef" :rules="rules" :model="formAdd" auto-label-width>
+        <a-form-item
+          field="status"
+          :label="$t('financialManagement.rechargeType')"
+        >
+          <a-radio-group v-model="formAdd.status" :options="statusOptions" />
+        </a-form-item>
+        <a-form-item
+          field="userId"
+          :label="$t('financialManagement.searchForm.name')"
+        >
+          <a-select
+            :options="customerOptions"
+            :style="{ width: '320px' }"
+            :loading="customerLoading"
+            :placeholder="$t('financialManagement.lenovoInput')"
+            @search="customerSearch"
+            :field-names="fieldNames"
+            allow-search
+            allow-clear
+            @change="customerChange"
+          />
+        </a-form-item>
+        <a-form-item
+          field="amount"
+          :label="$t('financialManagement.rechargeAmount')"
+        >
+          <a-input-number
+            v-model="formAdd.amount"
+            :placeholder="$t('financialManagement.rechargeAmountPlace')"
+            class="input-demo"
+            :min="10"
+            :max="100"
+            :style="{ width: '320px' }"
+          />
+        </a-form-item>
+        <a-form-item field="remarks" :label="$t('financialManagement.remarks')">
+          <a-textarea
+            :placeholder="$t('financialManagement.remarksPlace')"
+            v-model="formAdd.remarks"
+            allow-clear
+            :style="{ width: '320px' }"
+          />
+        </a-form-item>
+        <a-form-item
+          field="certificateImg"
+          :label="$t('financialManagement.voucher')"
+        >
+          <Upload
+            v-model:modelValue="formAdd.certificateImg"
+            :style="{ width: 'auto' }"
+            beforeUpload
+          />
+          <div class="text-box">
+            <div class="text">1.{{ $t("financialManagement.uploadTip1") }}</div>
+            <div class="text">2.{{ $t("financialManagement.uploadTip2") }}</div>
+            <div class="text">3.{{ $t("financialManagement.uploadTip3") }}</div>
+          </div>
+        </a-form-item>
+      </a-form>
+    </a-modal>
+  </div>
 </template>
 <script setup>
-import { ref, reactive } from 'vue';
-import { Message } from '@arco-design/web-vue';
-const selectedKeys = ref([]);
-const rowSelection = reactive({
-    type: 'checkbox',
-    showCheckedAll: true,
-    onlyCurrent: false,
-});
-const searchForm = reactive({
-    customerName: '',
-});
+import { ref, reactive, onMounted } from "vue";
+import { Message } from "@arco-design/web-vue";
+import { getTopUpRecordList, getCustomerList, topUpAs } from "@/api/finance.js";
+import Upload from "@/components/upload/index.vue";
 
-const columns = [
-    { title: '序号', dataIndex: 'index', align: 'center', render: ({ rowIndex }) => rowIndex + 1 },
+const rules = {
+  status: [
     {
-        title: '客户编号', dataIndex: 'customerNumber', ellipsis: true,
-        tooltip: true,
-        width: 100
+      required: true,
+      message: window.$t("financialManagement.rulesa.status"),
+      trigger: "change",
     },
-    { title: '客户名称', dataIndex: 'customerName' },
-    { title: '客户账号', dataIndex: 'customerAccountNumber' },
-    { title: '充值金额(元)', dataIndex: 'topsUpMoney' },
-    { title: '账户可用余额(元)', dataIndex: 'balance' },
-    { title: '充值类型', dataIndex: 'topsUpStatus' },
-    { title: '更新时间', dataIndex: 'updateTime' },
-    { title: '详情', slotName: 'detail', align: 'center' },
-];
-const tableData = ref([
+  ],
+  userId: [
     {
-        customerNumber: '13800138000',
-        customerName: '张三',
-        topsUpStatus: '1',
-        customerAccountNumber: 'jhl001',
-        topsUpMoney: '100',
-        balance: '100',
-        updateTime: '2024-10-11'
-        // operate:'上传合同'
+      required: true,
+      message: window.$t("financialManagement.rulesa.userId"),
+      trigger: "change",
     },
+  ],
+  amount: [
     {
-        customerNumber: '13800138000',
-        customerName: '李四',
-        topsUpStatus: '2',
-        customerAccountNumber: 'jhl001',
-        topsUpMoney: '100',
-        balance: '100',
-        updateTime: '2024-10-11'
-        // operate:'上传合同'
-    },
-    {
-        customerNumber: '13800138000',
-        customerName: '王五',
-        topsUpStatus: '3',
-        customerAccountNumber: 'jhl001',
-        topsUpMoney: '100',
-        balance: '100',
-        updateTime: '2024-10-11'
-        // operate:'上传合同'
-    },
-    {
-        customerNumber: '13800138000',
-        customerName: '赵六',
-        topsUpStatus: '1',
-        customerAccountNumber: 'jhl001',
-        topsUpMoney: '100',
-        balance: '100',
-        updateTime: '2024-10-11'
-        // operate:'上传合同'
+      required: true,
+      message: window.$t("financialManagement.rulesa.amount"),
+      trigger: "change",
     },
+  ],
+};
 
-]);
-const pagination = reactive({
-    total: tableData.value.length,
-    current: 1,
-    pageSize: 10,
+onMounted(() => {
+  getTopUpRecordListFc();
+});
+
+const initPage = {
+  total: 0,
+  current: 1,
+  pageSize: 10,
+};
+
+const formRef = ref();
+const searchForm = ref({
+  name: "",
+});
+
+const columns = [
+  {
+    title: window.$t("financialManagement.orderNumber"),
+    dataIndex: "index",
+    align: "center",
+    render: ({ rowIndex }) => rowIndex + 1,
+    width: 60,
+  },
+  {
+    title: window.$t("financialManagement.customerId"),
+    dataIndex: "id",
+    ellipsis: true,
+    tooltip: true,
+    width: 180,
+    align: "center",
+  },
+  {
+    title: window.$t("financialManagement.customerName"),
+    dataIndex: "name",
+    align: "center",
+    slotName: "name",
+  },
+  {
+    title: window.$t("financialManagement.customerAccount"),
+    dataIndex: "username",
+    align: "center",
+  },
+  {
+    title: window.$t("financialManagement.rechargeAmountTab"),
+    dataIndex: "rechargeAmount",
+    align: "center",
+  },
+  {
+    title: window.$t("financialManagement.availableAmountTab"),
+    dataIndex: "availableAmount",
+    width: 140,
+    align: "center",
+  },
+  {
+    title: window.$t("financialManagement.rechargeType"),
+    dataIndex: "status",
+    align: "center",
+    slotName: "status",
+    filterable: {
+      filters: [
+        {
+          text: window.$t("financialManagement.recharge"),
+          value: "1",
+        },
+        {
+          text: window.$t("financialManagement.offset"),
+          value: "2",
+        },
+        {
+          text: window.$t("financialManagement.deduct"),
+          value: "3",
+        },
+      ],
+      filter: (value, record) => {
+        return record.status === value[0];
+      },
+      multiple: true,
+    },
+  },
+  {
+    title: window.$t("financialManagement.updatedAt"),
+    dataIndex: "updatedAt",
+    width: 180,
+    align: "center",
+  },
+];
+const handleStatusTxt = (status) => {
+  const obj = {
+    1: window.$t("financialManagement.recharge"),
+    2: window.$t("financialManagement.offset"),
+    3: window.$t("financialManagement.deduct"),
+  };
+  return obj[status];
+};
+const tableData = ref([]);
+const pagination = ref({
+  ...initPage,
+  showTotal: true,
+  showJumper: true,
+  showPageSize: true,
 });
+
+const onPageChange = (page) => {
+  pagination.value.current = page;
+  getTopUpRecordListFc();
+};
+const onPageSizeChange = (pageSize) => {
+  pagination.value.pageSize = pageSize;
+  getTopUpRecordListFc();
+};
+
 const handleSearch = () => {
-    console.log('Search form data:', searchForm);
-    Message.success('执行搜索操作');
+  pagination.value = { ...initPage };
+  getTopUpRecordListFc();
 };
 
 const resetSearch = () => {
-    Object.keys(searchForm).forEach(key => {
-        if (Array.isArray(searchForm[key])) {
-            searchForm[key] = [];
-        } else {
-            searchForm[key] = null;
-        }
-    });
-    Message.success('搜索条件已重置');
+  formRef.value.resetFields();
+  handleSearch();
 };
-const options = [
-    { label: '充值', value: '1' },
-    { label: '抵充', value: '2' },
-    { label: '消费扣除', value: '3' },
+
+// 新增弹窗
+const addFormRef = ref();
+const statusOptions = [
+  { label: window.$t("financialManagement.recharge"), value: "1" },
+  { label: window.$t("financialManagement.offset"), value: "2" },
+  { label: window.$t("financialManagement.deduct"), value: "3" },
 ];
 const openTopsUp = () => {
-    showAdd.value = true;
-}
+  getCustomerListFc();
+  showAdd.value = true;
+};
 const showAdd = ref(false);
-const formAdd = reactive({
-    customerName: '',
-    cardType: '',
-    money: null,
-    topsUpStatus: '',
-    topsUpOpinion: '',
-    fileList: []
-})
+const formAdd = ref({
+  status: "",
+  userId: "",
+  amount: null,
+  remarks: "",
+  certificateImg: "",
+});
+const okLoading = ref(false);
 const submitAdd = () => {
-    window.setTimeout(() => {
+  addFormRef.value.validate((err) => {
+    okLoading.value = true;
+    if (!err) {
+      const params = {
+        ...formAdd.value,
+      };
+      topUpAs(params).then((res) => {
+        okLoading.value = false;
         showAdd.value = false;
-    }, 1000)
-}
+        Message.success("充值成功!");
+        getTopUpRecordListFc();
+      });
+    }
+  });
+};
+
+const getTopUpRecordListFc = async () => {
+  const param = {
+    current: pagination.value.current,
+    size: pagination.value.pageSize,
+    ...searchForm.value,
+  };
+  const { data } = await getTopUpRecordList(param);
+  tableData.value = data?.records || [];
+  pagination.value.total = data.total;
+};
+
+// 客户选择
+const customerOptions = ref([]);
+const customerLoading = ref(false);
+const fieldNames = { value: "id", label: "name" };
+const customerSearch = (value) => {
+  if (value) {
+    customerLoading.value = true;
+    getCustomerListFc(value);
+  } else {
+    getCustomerListFc();
+  }
+};
+const customerChange = (val) => {
+  formAdd.value.userId = val;
+};
+const getCustomerListFc = async (value) => {
+  const param = {
+    current: 1,
+    size: 10,
+    name: value,
+  };
+  const { data } = await getCustomerList(param);
+  customerOptions.value = data?.records || [];
+  customerLoading.value = false;
+};
 </script>
 <style scoped lang="less">
 .customer-top-up {
-    padding: 20px !important;
+  padding: 20px !important;
 
-    .search-section {
-        margin-bottom: 20px;
-    }
+  .search-section {
+    margin-bottom: 20px;
+  }
 
-    .audit-btn {
-        margin-bottom: 10px;
-    }
+  .audit-btn {
+    margin-bottom: 10px;
+  }
 }
 
 .text-box {
-    width: 100%;
-    margin-left: 10px;
+  width: 100%;
+  margin-left: 10px;
 
-    .text {
-        font-family: PingFang SC;
-        font-size: 12px;
-        font-weight: 400;
-        line-height: 19px;
-        color: rgba(153, 153, 153, 1);
-        text-align: left;
-    }
+  .text {
+    font-family: PingFang SC;
+    font-size: 12px;
+    font-weight: 400;
+    line-height: 19px;
+    color: rgba(153, 153, 153, 1);
+    text-align: left;
+  }
 }
 </style>

+ 262 - 195
src/views/financialManagement/trafficDetails/index.vue

@@ -1,228 +1,295 @@
 <!-- 流量明细 客户充值界面 -->
 <template>
-    <div class="customer-top-up">
-        <!-- 搜索条件区 -->
-        <div class="search-section">
-            <a-form :model="searchForm" layout="inline">
-                <a-form-item field="ICCID" label="ICCID">
-                    <a-input v-model="searchForm.ICCID" placeholder="请输入ICCID" allow-clear />
-                </a-form-item>
-                <a-form-item field="exportTime" label="卡导入时间">
-                    <a-range-picker v-model="searchForm.exportTime" style="width: 254px; marginBottom: 20px;" />
-                </a-form-item>
-                <a-form-item>
-                    <a-space>
-                        <a-button type="primary" @click="handleSearch">搜索</a-button>
-                        <a-button @click="resetSearch">重置</a-button>
-                    </a-space>
-                </a-form-item>
-            </a-form>
-        </div>
-        <!-- 数据表格 -->
-        <a-table row-key="customerName" v-model:selectedKeys="selectedKeys" :row-selection="rowSelection"
-            :columns="columns" :data="tableData" :pagination="pagination" :scroll="{ x: '100%', y: '400px' }">
-            <template #detail="{ record }">
-                <a-button @click="openDetail(record)" type="text">查看</a-button>
-            </template>
-        </a-table>
-        <a-modal v-model:visible="showDetail" title="流量消耗明细" @cancel="showDetail = false" @before-ok="submitDetail"
-            okText="确定" width="1000px" cancelText="关闭">
-            <a-table row-key="ICCID" v-model:selectedKeys="selectedKeysDetail" :row-selection="rowSelectionDetail"
-                :columns="columnsDetail" :data="tableDataDetail" :pagination="paginationDetail"
-                :scroll="{ x: '100%', y: '400px' }">
-            </a-table>
-        </a-modal>
+  <div class="customer-top-up">
+    <!-- 搜索条件区 -->
+    <div class="search-section">
+      <a-form ref="formRef" :model="searchForm" layout="inline">
+        <a-form-item field="name" label="客户名称">
+          <a-input
+            v-model="searchForm.name"
+            placeholder="请输入客户名称"
+            allow-clear
+          />
+        </a-form-item>
+        <!-- <a-form-item field="exportTime" label="卡导入时间">
+          <a-range-picker
+            v-model="searchForm.exportTime"
+            style="width: 254px; marginbottom: 20px"
+          />
+        </a-form-item> -->
+        <a-form-item>
+          <a-space>
+            <a-button type="primary" @click="handleSearch">搜索</a-button>
+            <a-button @click="resetSearch">重置</a-button>
+          </a-space>
+        </a-form-item>
+      </a-form>
     </div>
+    <!-- 数据表格 -->
+    <a-table
+      row-key="userId"
+      :columns="columns"
+      :data="tableData"
+      :pagination="pagination"
+      @page-change="onPageChange"
+      @page-size-change="onPageSizeChange"
+    >
+      <template #dataUsage="{ record }">
+        <div class="boldTxt txtPointer" @click="openDetail(record)">
+          {{ record.dataUsage }}M
+        </div>
+      </template>
+    </a-table>
+    <a-modal
+      v-model:visible="showDetail"
+      title="流量消耗明细"
+      @cancel="showDetail = false"
+      @before-ok="submitDetail"
+      okText="确定"
+      width="1000px"
+      cancelText="关闭"
+    >
+      <a-table
+        row-key="ICCID"
+        :columns="columnsDetail"
+        :data="tableDataDetail"
+        :pagination="paginationDetail"
+        :scroll="{
+          x: '130%',
+          y: '100%',
+        }"
+        @page-change="onDetailPageChange"
+        @page-size-change="onDetailPageSizeChange"
+      >
+        <template #dataUsage="{ record }">
+          <div>{{ record.dataUsage }}M/{{ record.dataTotal }}M</div>
+        </template>
+        <template #userName="{ record }">
+          <div>{{ record.userName }}/{{ record.userId }}</div>
+        </template>
+      </a-table>
+    </a-modal>
+  </div>
 </template>
 <script setup>
-import { ref, reactive } from 'vue';
-import { Message } from '@arco-design/web-vue';
-const selectedKeys = ref([]);
-const rowSelection = reactive({
-    type: 'checkbox',
-    showCheckedAll: true,
-    onlyCurrent: false,
-});
-const selectedKeysDetail = ref([]);
-const rowSelectionDetail = reactive({
-    type: 'checkbox',
-    showCheckedAll: true,
-    onlyCurrent: false,
+import { ref, reactive, onMounted } from "vue";
+import { Message } from "@arco-design/web-vue";
+import { getSimConsumptionDetailsList, getUserSimInfo } from "@/api/finance.js";
+
+onMounted(() => {
+  getSimConsumptionDetailsListFc();
 });
-const searchForm = reactive({
-    exportTime: '',
-    ICCID: ''
+
+const initPage = {
+  total: 0,
+  current: 1,
+  pageSize: 10,
+};
+
+const formRef = ref();
+const searchForm = ref({
+  name: "",
 });
 
 const columns = [
-    { title: '序号', dataIndex: 'index', align: 'center', render: ({ rowIndex }) => rowIndex + 1 },
-    { title: '客户', dataIndex: 'customerName' },
-    { title: '运营商', dataIndex: 'operators' },
-    { title: '统计时间', dataIndex: 'updateTime' },
-    { title: '卡套餐', dataIndex: 'cardPackages' },
-    { title: '已用流量套餐', dataIndex: 'usedData' },
-    { title: '已用加油包流量', dataIndex: 'fuelPacketUsed' },
-    { title: '计算周期', dataIndex: 'updateTime' },
-    { title: '详情', slotName: 'detail', align: 'center' },
+  {
+    title: "序号",
+    dataIndex: "index",
+    align: "center",
+    render: ({ rowIndex }) => rowIndex + 1,
+    width: 60,
+  },
+  { title: "客户", dataIndex: "username" },
+  { title: "运营商", dataIndex: "source" },
+  { title: "统计时间", dataIndex: "statisticalTime" },
+  { title: "卡套餐", dataIndex: "cardPackageName" },
+  { title: "已用流量套餐", dataIndex: "dataUsage", slotName: "dataUsage",  },
+//   { title: "已用加油包流量", dataIndex: "dataUsage" },
+  { title: "计算周期", dataIndex: "billingCycle" },
 ];
 const columnsDetail = [
-    { title: '序号', dataIndex: 'index', align: 'center', render: ({ rowIndex }) => rowIndex + 1 },
-    { title: 'ICCID/MSISDN', dataIndex: 'ICCID' },
-    { title: '客户', dataIndex: 'customerName' },
-    { title: '运营商', dataIndex: 'operators' },
-    { title: '统计时间', dataIndex: 'updateTime' },
-    { title: '用户名称/编号', dataIndex: 'userName' },
-    { title: '卡套餐', dataIndex: 'cardPackages' },
-    { title: '已用/可用(套餐流量)', dataIndex: 'usedData' },
-    { title: '已用/可用(加油包流量)', dataIndex: 'fuelPacketUsed' },
+  {
+    title: "序号",
+    dataIndex: "index",
+    align: "center",
+    render: ({ rowIndex }) => rowIndex + 1,
+    width: 60,
+  },
+  { title: "ICCID/MSISDN", dataIndex: "iccid" },
+  { title: "客户", dataIndex: "userName" },
+  { title: "运营商", dataIndex: "source", width: 120, },
+  { title: "统计时间", dataIndex: "updatedAt", width: 180, },
+  { title: "用户名称/编号", dataIndex: "userName", slotName: "userName" },
+  { title: "卡套餐", dataIndex: "productName" },
+  {
+    title: "已用/可用(套餐流量)",
+    dataIndex: "usedData",
+    dataIndex: "dataUsage",
+    slotName: "dataUsage",
+  },
+//   { title: "已用/可用(加油包流量)", dataIndex: "fuelPacketUsed" },
 ];
-const tableData = ref([
-    {
-        customerNumber: '13800138000',
-        customerName: '张三',
-        fuelPacketUsed: '1',
-        operators: 'jhl001',
-        cardPackages: '100',
-        usedData: '100',
-        updateTime: '2024-10-11'
-        // operate:'上传合同'
-    },
-    {
-        customerNumber: '13800138000',
-        customerName: '李四',
-        fuelPacketUsed: '2',
-        operators: 'jhl001',
-        cardPackages: '100',
-        usedData: '100',
-        updateTime: '2024-10-11'
-        // operate:'上传合同'
-    },
-    {
-        customerNumber: '13800138000',
-        customerName: '王五',
-        fuelPacketUsed: '3',
-        operators: 'jhl001',
-        cardPackages: '100',
-        usedData: '100',
-        updateTime: '2024-10-11'
-        // operate:'上传合同'
-    },
-    {
-        customerNumber: '13800138000',
-        customerName: '赵六',
-        fuelPacketUsed: '1',
-        operators: 'jhl001',
-        cardPackages: '100',
-        usedData: '100',
-        updateTime: '2024-10-11'
-        // operate:'上传合同'
-    },
-
+const tableData = ref([]);
+const tableDataDetail = ref([
+  {
+    ICCID: "1210938748329018",
+    customerName: "泰国李总",
+    operators: "泰国AIS",
+    updateTime: "2024-10-24 08:10:34",
+    userName: "Jay/010211",
+    cardPackages: "100M每月",
+    usedData: "28M/100M",
+    fuelPacketUsed: "28M/30M",
+  },
+  {
+    ICCID: "1210938748329019",
+    customerName: "泰国李总",
+    operators: "泰国AIS",
+    updateTime: "2024-10-24 08:10:34",
+    userName: "Jay/010211",
+    cardPackages: "100M每月",
+    usedData: "28M/100M",
+    fuelPacketUsed: "28M/30M",
+  },
+  {
+    ICCID: "12109387483290110",
+    customerName: "泰国李总",
+    operators: "泰国AIS",
+    updateTime: "2024-10-24 08:10:34",
+    userName: "Jay/010211",
+    cardPackages: "100M每月",
+    usedData: "28M/100M",
+    fuelPacketUsed: "28M/30M",
+  },
+  {
+    ICCID: "12109387483290111",
+    customerName: "泰国李总",
+    operators: "泰国AIS",
+    updateTime: "2024-10-24 08:10:34",
+    userName: "Jay/010211",
+    cardPackages: "100M每月",
+    usedData: "28M/100M",
+    fuelPacketUsed: "28M/30M",
+  },
+  {
+    ICCID: "12109387483290112",
+    customerName: "泰国李总",
+    operators: "泰国AIS",
+    updateTime: "2024-10-24 08:10:34",
+    userName: "Jay/010211",
+    cardPackages: "100M每月",
+    usedData: "28M/100M",
+    fuelPacketUsed: "28M/30M",
+  },
 ]);
-const tableDataDetail = ref([{
-    ICCID: '1210938748329018',
-    customerName: '泰国李总',
-    operators: '泰国AIS',
-    updateTime: '2024-10-24 08:10:34',
-    userName: 'Jay/010211',
-    cardPackages: '100M每月',
-    usedData: '28M/100M',
-    fuelPacketUsed: '28M/30M'
-},
-{
-    ICCID: '1210938748329019',
-    customerName: '泰国李总',
-    operators: '泰国AIS',
-    updateTime: '2024-10-24 08:10:34',
-    userName: 'Jay/010211',
-    cardPackages: '100M每月',
-    usedData: '28M/100M',
-    fuelPacketUsed: '28M/30M'
-},
-{
-    ICCID: '12109387483290110',
-    customerName: '泰国李总',
-    operators: '泰国AIS',
-    updateTime: '2024-10-24 08:10:34',
-    userName: 'Jay/010211',
-    cardPackages: '100M每月',
-    usedData: '28M/100M',
-    fuelPacketUsed: '28M/30M'
-},
-{
-    ICCID: '12109387483290111',
-    customerName: '泰国李总',
-    operators: '泰国AIS',
-    updateTime: '2024-10-24 08:10:34',
-    userName: 'Jay/010211',
-    cardPackages: '100M每月',
-    usedData: '28M/100M',
-    fuelPacketUsed: '28M/30M'
-},
-{
-    ICCID: '12109387483290112',
-    customerName: '泰国李总',
-    operators: '泰国AIS',
-    updateTime: '2024-10-24 08:10:34',
-    userName: 'Jay/010211',
-    cardPackages: '100M每月',
-    usedData: '28M/100M',
-    fuelPacketUsed: '28M/30M'
-},])
-const pagination = reactive({
-    total: tableData.value.length,
-    current: 1,
-    pageSize: 10,
+const pagination = ref({
+  ...initPage,
+  showTotal: true,
+  showJumper: true,
+  showPageSize: true,
+});
+const paginationDetail = ref({
+  ...initPage,
+  showTotal: true,
+  showJumper: true,
+  showPageSize: true,
 });
+
+const onPageChange = (page) => {
+  pagination.value.current = page;
+  getSimConsumptionDetailsListFc();
+};
+const onPageSizeChange = (pageSize) => {
+  pagination.value.pageSize = pageSize;
+  getSimConsumptionDetailsListFc();
+};
+const onDetailPageChange = (page) => {
+  pagination.value.current = page;
+  getUserSimInfoFc();
+};
+const onDetailPageSizeChange = (pageSize) => {
+  pagination.value.pageSize = pageSize;
+  getUserSimInfoFc();
+};
+
 const handleSearch = () => {
-    console.log('Search form data:', searchForm);
-    Message.success('执行搜索操作');
+  pagination.value = { ...initPage };
+  getSimConsumptionDetailsListFc();
 };
 
 const resetSearch = () => {
-    Object.keys(searchForm).forEach(key => {
-        if (Array.isArray(searchForm[key])) {
-            searchForm[key] = [];
-        } else {
-            searchForm[key] = null;
-        }
-    });
-    Message.success('搜索条件已重置');
+  formRef.value.resetFields();
+  handleSearch();
 };
 const showDetail = ref(false);
 const submitDetail = () => {
-    window.setTimeout(() => {
-        showDetail.value = false;
-    }, 1000)
-}
-const openDetail = () => {
+  window.setTimeout(() => {
+    showDetail.value = false;
+  }, 1000);
+};
+
+const curUserId = ref(null);
+const openDetail = (record) => {
+  curUserId.value = record.userId;
+  getUserSimInfoFc(() => {
     showDetail.value = true;
-}
+  });
+};
+
+const getSimConsumptionDetailsListFc = async () => {
+  const param = {
+    current: pagination.value.current,
+    size: pagination.value.pageSize,
+    ...searchForm.value,
+  };
+  const { data } = await getSimConsumptionDetailsList(param);
+  tableData.value = data?.records || [];
+  pagination.value.total = data.total;
+};
+const getUserSimInfoFc = async (cb) => {
+  const param = {
+    current: paginationDetail.value.current,
+    size: paginationDetail.value.pageSize,
+    id: curUserId.value,
+  };
+  const { data } = await getUserSimInfo(param);
+  tableDataDetail.value =
+    data.map((v) => {
+      const obj =
+        v?.dataPackage && v.dataPackage.length > 0 ? v.dataPackage[0] : {};
+      return {
+        ...obj,
+        ...v,
+      };
+    }) || [];
+  paginationDetail.value.total = data.length;
+  cb && cb();
+};
 </script>
 <style scoped lang="less">
 .customer-top-up {
-    padding: 20px;
+  padding: 20px !important;
 
-    .search-section {
-        margin-bottom: 20px;
-    }
+  .search-section {
+    margin-bottom: 20px;
+  }
 
-    .audit-btn {
-        margin-bottom: 10px;
-    }
+  .audit-btn {
+    margin-bottom: 10px;
+  }
 }
 
 .text-box {
-    width: 100%;
-    margin-left: 10px;
+  width: 100%;
+  margin-left: 10px;
 
-    .text {
-        font-family: PingFang SC;
-        font-size: 12px;
-        font-weight: 400;
-        line-height: 19px;
-        color: rgba(153, 153, 153, 1);
-        text-align: left;
-    }
+  .text {
+    font-family: PingFang SC;
+    font-size: 12px;
+    font-weight: 400;
+    line-height: 19px;
+    color: rgba(153, 153, 153, 1);
+    text-align: left;
+  }
 }
 </style>

+ 2 - 0
src/views/tariffManagement/customer/NewCustomerForm.vue

@@ -331,7 +331,9 @@ const rules = {
 
 const handleSubmit = () => {
   formRef.value.validate(async (errors) => {
+    console.log('输出',formData.value);
     if (!errors) {
+      return;
       let response;
       formData.value.password = encryptByDES(formData.value.password);
       if (props.editMode) {