Bläddra i källkod

手机端-其他页面以及充值管理-添加授信金额

dujingxian 4 år sedan
förälder
incheckning
5962376674

+ 41 - 7
src/pages/phoneIndex.vue

@@ -7,9 +7,17 @@
             椰子充值后台管理系统
           </div>
           <div class="hdBottom">
-            <div>
-              <i :class="isCollapse ? 'el-icon-s-fold'  : 'el-icon-s-unfold'" @click="isCollapse=!isCollapse"></i>
-              <!-- 首页 -->
+            <div @click="isCollapse=!isCollapse">
+              <i :class="isCollapse ? 'el-icon-s-fold'  : 'el-icon-s-unfold'" style="margin-right:10px"></i>
+              <template v-if="phoneCurPath == 'phoneHome'">首页</template>
+              <template v-if="phoneCurPath == 'phoneOrder'">订单管理</template>
+              <template v-if="phoneCurPath == 'phoneMessage'">账户日志</template>
+              <template v-if="phoneCurPath == 'phoneOilCard'">油卡充值</template>
+              <template v-if="phoneCurPath == 'phoneMobileCard'">手机卡充值</template>
+              <template v-if="phoneCurPath == 'phoneBalance'">充值管理</template>
+              <template v-if="phoneCurPath == 'phoneReconciliation'">对账管理</template>
+              <template v-if="phoneCurPath == 'phoneView'">设置</template>
+              <template v-if="phoneCurPath == 'phoneInterfaceDoc'">接口文档</template>
             </div>
             <div>
               <el-dropdown @command="onUserEdit" trigger="click">
@@ -26,7 +34,7 @@
           </div>
         </el-header>
         <el-container style="height:100%;padding-bottom: 120px">
-          <el-aside :width="isCollapse ? '100px' : '0px'" style="position: absolute;z-index: 999;height:100%">
+          <el-aside :width="isCollapse ? '115px' : '0px'" style="position: absolute;z-index: 999;height:100%">
             <el-menu :router="true" class="el-menu" background-color="#757E83" text-color="#fff"
               active-text-color="#ffd04b"
               :default-active="phoneCurPath"
@@ -37,10 +45,38 @@
                 <i class="el-icon-house"></i>
                 <span style="font-size: 14px;" slot="title">首页</span>
               </el-menu-item>
+              <el-menu-item index="phoneOrder" route="phoneOrder" style="padding: 0 5px">
+                <i class="el-icon-edit-outline"></i>
+                <span style="font-size: 14px;" slot="title">订单管理</span>
+              </el-menu-item>
+              <el-menu-item index="phoneMessage" route="phoneMessage" style="padding: 0 5px">
+                <i class="el-icon-message"></i>
+                <span style="font-size: 14px;" slot="title">账户日志</span>
+              </el-menu-item>
+              <el-menu-item index="phoneOilCard" route="phoneOilCard" style="padding: 0 5px">
+                <i class="el-icon-bank-card"></i>
+                <span style="font-size: 14px;" slot="title">油卡充值</span>
+              </el-menu-item>
+              <el-menu-item index="phoneMobileCard" route="phoneMobileCard" style="padding: 0 5px">
+                <i class="el-icon-mobile"></i>
+                <span style="font-size: 14px;" slot="title">手机卡充值</span>
+              </el-menu-item>
               <el-menu-item index="phoneBalance" route="phoneBalance" style="padding: 0 5px">
                 <i class="el-icon-s-order"></i>
                 <span style="font-size: 14px;" slot="title">充值管理</span>
               </el-menu-item>
+              <el-menu-item index="phoneReconciliation" route="phoneReconciliation" style="padding: 0 5px">
+                <i class="el-icon-document-checked"></i>
+                <span style="font-size: 14px;" slot="title">对账管理</span>
+              </el-menu-item>
+              <el-menu-item index="phoneView" route="phoneView" style="padding: 0 5px">
+                <i class="el-icon-s-platform"></i>
+                <span style="font-size: 14px;" slot="title">设置</span>
+              </el-menu-item>
+              <el-menu-item index="phoneDoc" route="phoneDoc" style="padding: 0 5px">
+                <i class="el-icon-document"></i>
+                <span style="font-size: 14px;" slot="title">接口文档</span>
+              </el-menu-item>
             </el-menu>
           </el-aside>
           <el-main style="position: relative;">
@@ -75,12 +111,10 @@ import { removeUser } from '@/utils/auth'
 export default {
     name: 'phoneIndex',
     created() {
-        this.curPath = this.$route.name;
         this.phoneCurPath = this.$route.name;
     },
     data() {
         return {
-            curPath: "",
             editVisible: false,
             editForm: {
                 pwd: "",
@@ -187,8 +221,8 @@ export default {
             handler(newVal) {
                 // console.log(newVal.name, oldVal.path);
                 if (newVal) {
-                    this.curPath = newVal.name
                     this.phoneCurPath = newVal.name
+                    this.isCollapse = !this.isCollapse
                 }
             }
         }

+ 22 - 8
src/pages/phoneSubPages/phoneBalance.vue

@@ -24,6 +24,9 @@
     <el-row>
       <el-col :span="24">
         <el-form  :model="balanceForm">
+            <el-form-item v-if="credit_bonus" label="授信可用金额:">
+                {{credit_bonus}}
+            </el-form-item>
           <el-form-item label="当前余额:">
               {{available_predeposit}}
           </el-form-item>
@@ -63,11 +66,12 @@
           range-separator="至"
           start-placeholder="开始日期"
           end-placeholder="结束日期"
-          style="width:260px;margin-bottom:20px;margin-right:10px;"
-          class="phone_picker"></el-date-picker>
-        <el-button style="margin-right:10px;margin-bottom:20px;" type="primary" @click="onSearch" :loading="searchLoading">查询</el-button>
-        <el-button style="margin-right:10px;margin-bottom:20px;" type="danger" @click="onReset">重置</el-button>
-        <el-button style="margin-bottom:20px;" type="warning" @click="onRecharge">充值申请提交</el-button>
+          style="width:260px;margin-bottom:10px;"
+          class="phone_picker"
+          size="small"></el-date-picker><br>
+        <el-button style="margin-right:10px;margin-bottom:10px;" type="primary" size="small" @click="onSearch" :loading="searchLoading">查询</el-button>
+        <el-button style="margin-right:10px;margin-bottom:10px;" type="danger" size="small" @click="onReset">重置</el-button>
+        <el-button style="margin-bottom:10px;" type="warning" size="small" @click="onRecharge">充值申请提交</el-button>
       </div>
       <el-table :data="tableData" border style="width: 1341px;font-size:13px;" v-loading="isLoading">
         <el-table-column align="center" type="index" width="50" label="序号" />
@@ -283,7 +287,9 @@ export default {
             evidence_amounts: '',
             searchLoading: false,
             // 大写金额
-            wordsAmount: ''
+            wordsAmount: '',
+            // 授信可用金额
+            credit_bonus: ''
         };
     },
     mounted() {
@@ -539,6 +545,7 @@ export default {
                     this.evidence_count = res.datas.evidence_count
                     this.warningList = res.datas.warning_phone
                     this.evidence_amounts = res.datas.evidence_amounts
+                    this.credit_bonus = res.datas.credit_bonus
                 }
             } catch (error) {
                 console.log(error);
@@ -582,7 +589,7 @@ export default {
 }
 </script>
 
-<style scoped>
+<style scoped lang="less">
 .upload-demo {
     display: inline-block;
     margin-left: 10px;
@@ -687,6 +694,9 @@ export default {
     font-size: 14px; /*no */
 }
 @media screen and (max-width: 768px) {
+    .el-card__body {
+        padding: 10px;/*no */
+    }
   .el-date-range-picker {
     width: 90%;
   }
@@ -694,7 +704,7 @@ export default {
     min-width: 0px;
   }
   .el-date-range-picker__time-header {
-    padding: 4px 5px 5px;/*no */
+    padding: 4px 3px 5px;/*no */
   }
   .el-date-range-picker__time-picker-wrap {
     padding: 0 2px;/*no */
@@ -702,10 +712,14 @@ export default {
   .el-input__inner {
     padding: 0 2px;/*no */
     text-align: center;
+    font-size: 12px;
   }
   .el-picker-panel {
     left: 15px !important;/*no */
   }
+  .el-date-range-picker__content {
+    padding: 1px;/*no */
+  }
   .el-date-range-picker__content .el-date-range-picker__header div {
     margin-left: 20px;/*no */
     margin-right: 20px;/*no */

+ 227 - 0
src/pages/phoneSubPages/phoneDoc.vue

@@ -0,0 +1,227 @@
+<template>
+  <div class="interfaceDoc">
+    <el-card>
+      <h1 style="font-size: 18px;">接 口 规 范</h1>
+      <h4>验签规则:</h4>
+      <p>
+        签名(sign字段)生成方式:将所有参数名按照ASCII自然排序,并拼接成key1=value&key2=value----,末尾加上“&key=密钥”,
+        然后进行MD5生成sign。如果字段值为空,拼接的时候需要去掉,并对各个字段的值做URL编码。
+      </p>
+      <p>验签方式同上</p>
+      <p>提交格式:使用POST提交form表单格式,提交的字段里面不要带key。</p>
+      <p>服务器返回数据:json格式</p>
+      <p>异步回调方式:POST表单请求异步地址</p><br/>
+      <h4>网关地址:</h4>
+      <p>网关地址: https://www.xyzshops.cn/mobile/index.php</p><br/>
+      <h4>可充值商品列表信息:</h4>
+        <pre>
+          描述:获取平台各种类型的充值卡支持的充值面额。
+          请求参数:
+              act : refill 固定填为refill
+              op :  固定为goods
+              mchid : 组织机构号(商户号)
+              sign : 签名(不参与签名的字段,参考签名方法)
+          返回:
+              {
+                "code":200,
+                "message":"成功",
+                "datas":{
+                    "sinopec":[
+                      100,
+                      200,
+                      500,
+                      1000,
+                      2000
+                    ],
+                    "chinamobile":[
+                      50,
+                      100,
+                      200
+                    ],
+                    "chinaunicom":[
+                      50,
+                      100,
+                      200
+                    ],
+                    "chinatelecom":[
+                      50,
+                      100,
+                      200
+                    ]
+                }
+              }
+        </pre>
+      <h4>充值接口:</h4>
+      <pre>
+        充值油卡和话费统一接口。
+        请求参数:
+            act: refill 固定填为refill
+            op: add  固定为add
+            mchid: 组织机构号(商户号)
+            cardno: 卡号
+            amount: 充值金额(固定金额,如100,200,500,1000等,详细请查看后台)
+            order_sn: 商户自己可唯一标记订单的序列号。
+            notifyurl: 异步通知地址
+            card_name:持卡人姓名(中石油需要填写,其余的不需要)
+            idcard: 持卡人身份证(中石油需要填写,其余的不需要)
+            sign: 签名(不参与签名的字段,参考签名方法)
+        返回参数:
+            code: 200代表成功,非200代表失败
+            message: code非200时,返回出错信息.
+      </pre>
+      <h4>充值成功后异步通知:</h4>
+      <pre>
+        充值油卡和话费统一接口。
+        请求异步地址的参数:
+            mchid: 组织机构号(商户号)
+            order_sn: 商户自己可唯一标记订单的序列号。
+            amount: 充值金额(固定金额,如100,200,500,1000等,详细请查看后台)
+            cardno: 卡号
+            trade_no: 平台唯一交易号,和提交的成功时返回对应。
+            card_name:持卡人姓名(中石油需要填写,其余的不需要)
+            idcard: 持卡人身份证(中石油需要填写,其余的不需要)
+            official_sn: 官方流水号
+            message: 失败原因
+            state:SUCCESS表示充值成功,CANCEL表示充值失败订单取消.
+            sign: 签名(不参与签名的字段,参考签名方法)
+        确认接受异步通知返回:
+            直接返回大写:SUCCESS
+            如未返回SUCCESS,则2,4,5,16,32……秒间隔通知,每种时间重复5次,累积通知80次后,取消通知。
+      </pre>
+      <h4>交易查询接口:</h4>
+      <pre>
+        通过商户自己的订单号查询订单状态。
+        请求参数:
+            act: refill 固定填为refill
+            op: query
+            mchid: 组织机构号(商户号)
+            order_sn: 商户订单序列号
+            sign: 签名(不参与签名的字段,参考签名方法)
+
+        返回参数:
+            code: 200代表成功,非200代表失败
+            message: code非200时,返回出错信息.
+            datas: 数组格式,里面包含交易信息。
+        示例:
+            {
+              "code":200,
+              "message":"成功",
+              "datas" : {
+                  "mchid":"1",
+                  "trade_no" :"230660948104151671",
+                  "order_sn" :"13281476",
+                  "card_no" :"1000111100020445281",
+                  "card_type" :"2",
+                  "refill_amount":"100.00",
+                  "order_amount":"97.80",
+                  "order_time" :"1607604106",
+                  "success_time" :0,
+                  "order_state" :"20"
+              }
+            }
+        其中:
+            card_type:
+                1, PetroChina
+                2, Sinopec
+                4, ChinaMobile
+                5, ChinaUnicom
+                6, ChinaTelecom
+            refill_amount: 充值金额
+            order_amount: 扣款金额
+            order_time: 下单时间
+            success_time: 确认是否成功时间,运营商回调时间。
+            order_state:
+                0,订单已经取消,充值失败会取消订单。
+                10,新订单
+                20,已经支付
+                30,正在处理
+                40,充值成功
+      </pre>
+      <h4>获取余额接口:</h4>
+      <pre>
+        获取商户余额接口。
+        请求参数:
+            act: refill 固定填为refill
+            op: balance  固定为balance
+            mchid: 组织机构号(商户号)
+            sign: 签名(不参与签名的字段,参考签名方法)
+        返回参数:
+            code: 200代表成功,非200代表失败
+            message: code非200时,返回出错信息
+            datas: 返回数据
+            balance:datas下数据,代表商户余额
+      </pre>
+      <h4>错误码说明:</h4>
+      <pre>
+        200:成功
+        201:参数验证错误,详情请看message。
+        202:找不到合适的通道
+        203:余额不足
+        204:充值失败
+        205:客户订单号重复或者为空
+        206:平台不支持该卡充值
+        207:今日充值额度已达上限
+
+        10021:商户未设置秘钥或签名错误
+        0:商户信息验证失败,详情请看message。
+      </pre>
+    </el-card>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'interfaceDoc'
+}
+</script>
+
+<style scoped>
+.el-card {
+  padding: 0 5%;
+}
+h1 {
+  text-align: center;
+  font-family: "Microsoft YaHei";
+  margin-bottom: 20px;
+}
+h4 {
+  line-height: 36px; /*no */
+  font-size: 16px; /*no */
+  font-family: "Microsoft YaHei";
+}
+h6 {
+  line-height: 32px; /*no */
+  font-family: "Microsoft YaHei";
+}
+p {
+  text-indent: 2em;
+  line-height: 32px; /*no */
+  font-size: 14px; /*no */
+  font-family: "Microsoft YaHei";
+}
+pre {
+  line-height: 32px; /*no */
+  font-size: 16px; /*no */
+  font-family: "Microsoft YaHei";
+  white-space: pre-wrap;       /* css-3 */
+  white-space: -moz-pre-wrap;  /* Mozilla, since 1999 */
+  white-space: -pre-wrap;      /* Opera 4-6 */
+  white-space: -o-pre-wrap;    /* Opera 7 */
+  word-wrap: break-word;       /* Internet Explorer 5.5+ */
+  overflow: auto;
+  word-break: break-all;
+  word-wrap: break-word;
+}
+</style>
+<style>
+.el-main {
+  padding: 0;
+  margin-right: calc(100% - 100vw);
+}
+.el-card {
+  margin: 20px 30px;
+}
+.el-card__body {
+    padding: 0px;
+}
+</style>

+ 261 - 0
src/pages/phoneSubPages/phoneMessage.vue

@@ -0,0 +1,261 @@
+<template>
+<el-card>
+<el-container direction="vertical">
+    <div>
+      <el-date-picker v-model="dataRange" size="small" clearable value-format="timestamp" format="yyyy-MM-dd" type="datetimerange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" style="margin-right: 10px;margin-bottom:10px;width:260px"></el-date-picker>
+      <el-select v-model="changeVal" size="small" clearable placeholder="变动类型" style="margin-right: 10px;margin-bottom:10px;">
+          <el-option
+            v-for="item in changeType"
+            :key="item.value"
+            :label="item.label"
+            :value="item.value">
+          </el-option>
+      </el-select><br>
+      <el-button type="primary" @click="queryMovingAccount" size="small" style="margin-bottom:10px;">查询</el-button>
+      <el-button style="margin-left:10px;margin-bottom:10px;" type="danger" size="small" @click="onReset">重置</el-button>
+    </div>
+    <el-table :data="tableData" border style="width:100%;font-size:12px;" v-loading="isLoading">
+      <el-table-column align="left" prop="lg_type_text" label="资金变动类型" width="200"></el-table-column>
+      <el-table-column align="left" prop="lg_desc" label="变更内容" width="340"></el-table-column>
+      <el-table-column align="right" prop="lg_av_amount" label="变动金额" width="80"></el-table-column>
+      <el-table-column align="right" prop="lg_available" label="变动前余额" width="80"></el-table-column>
+      <el-table-column align="left" prop="lg_add_time" label="时间" width="145"></el-table-column>
+    </el-table>
+    <el-row style="margin-top:10px;" type="flex" justify="end">
+      <el-pagination background layout="prev, pager, next" :total="total" :page-size="pageSize" @current-change="onPageChange" :current-page="pageNumber"></el-pagination>
+    </el-row>
+</el-container>
+</el-card>
+</template>
+<script src="https://code.jquery.com/jquery-3.0.0.min.js"></script>
+<script>
+import {
+    getMovingAccount,
+    queryMovingAccount,
+    exportMovingAccount
+} from "@/api";
+// 常量
+import { changeType } from '@/utils/constants'
+import {JSONToExcelConvertor} from '@/utils/export.js'
+export default {
+    name: 'phoneMssage',
+    data() {
+        return {
+            pageSize: 50,
+            pageNumber: 1,
+            cabinetValue: "",
+            cabinetOptions: [],
+            boxOptions: [],
+            boxValue: "",
+            tableData: [],
+            total: 0,
+            // 开始结束时间
+            dataRange: [],
+            // 变动类型-常量
+            changeType,
+            // 1-减款 2-加款
+            changeVal: '',
+            startTime: '',
+            endTime: '',
+            // 是否正在加载
+            isLoading: false
+        };
+    },
+    created() {
+        // this.getCabinetList();
+        this.getMovingAccount()
+    },
+    computed: {
+    },
+    // 监听器
+    watch: {
+        dataRange(newVal) {
+            // console.log(newVal);
+            if (newVal == null) {
+                this.startTime = '';
+                this.endTime = '';
+            }
+        }
+    },
+    methods: {
+        // 获取实时动账
+        async getMovingAccount() {
+            this.isLoading = true
+            try {
+                const res = await getMovingAccount(1)
+                console.log('动账', res);
+                if (res && res.code == 200) {
+                    this.tableData = res.datas.data
+                    this.total = res.datas.total * this.pageSize
+                }
+                this.isLoading = false
+            } catch (error) {
+                console.log(error);
+                this.isLoading = false
+            }
+        },
+        // 页码
+        async onPageChange(page) {
+            if (page == this.pageNumber) {
+                return;
+            } else {
+                this.isLoading = true
+                this.pageNumber = page;
+                if (this.dataRange == null) {
+                    this.startTime = ''
+                    this.endTime = ''
+                } else {
+                    this.startTime =  this.dataRange[0]/1000 || ''
+                    this.endTime = this.dataRange[1]/1000 || ''
+                }
+                try {
+                    let param = new URLSearchParams()
+                    param.append('curpage', this.pageNumber)
+                    param.append('start_time', this.startTime)
+                    param.append('end_time', this.endTime)
+                    param.append('lg_type', this.changeVal)
+                    // const res = await queryMovingAccount(this.pageNumber,this.startTime, this.endTime, this.changeVal)
+                    const res = await queryMovingAccount(param)
+                    console.log('查询动账', res);
+                    if (res && res.code == 200) {
+                        this.tableData = res.datas.data
+                    }
+                    this.isLoading = false
+                } catch (error) {
+                    console.log(error);
+                    this.isLoading = false
+                }
+            }
+        },
+        // 查询
+        async queryMovingAccount() {
+            this.isLoading = true
+            if (this.dataRange == null) {
+                this.startTime = ''
+                this.endTime = ''
+            } else {
+                this.startTime =  this.dataRange[0]/1000 || ''
+                this.endTime = this.dataRange[1]/1000 || ''
+            }
+            try {
+                let param = new URLSearchParams()
+                param.append('curpage', this.pageNumber)
+                param.append('start_time', this.startTime)
+                param.append('end_time', this.endTime)
+                param.append('lg_type', this.changeVal)
+                // const res = await queryMovingAccount(this.pageNumber,this.startTime, this.endTime, this.changeVal)
+                const res = await queryMovingAccount(param)
+                console.log('查询动账', res);
+                if (res && res.code == 200) {
+                    this.tableData = res.datas.data
+                    this.total = res.datas.total * this.pageSize
+                }
+                this.isLoading = false
+            } catch (error) {
+                console.log(error);
+                this.isLoading = false
+            }
+        },
+        // 重置
+        onReset() {
+            this.pageNumber = 1;
+            this.dataRange = [];
+            this.changeVal = '';
+            this.getMovingAccount();
+        },
+    },
+};
+</script>
+
+<style scoped lang="less">
+/deep/.el-table td, 
+/deep/.el-table th {
+    padding: 7px 0;
+}
+/deep/.el-table .cell,
+/deep/.el-table--border td:first-child .cell,
+/deep/.el-table--border th:first-child .cell {
+    padding-left: 7px;
+}
+/deep/.el-table .cell {
+    padding-right: 7px;
+}
+/deep/.el-date-editor .el-range-separator {
+    padding: 0;
+    width: 20px;/*no */
+}
+/deep/.el-date-editor .el-range-input {
+    width: 100px;/*no */
+}
+/deep/.el-input,
+/deep/.el-date-editor .el-range-input,
+/deep/.el-date-editor .el-range-separator {
+  font-size: 13px; /*no */
+}
+</style>
+<style>
+.el-main {
+  padding: 0;
+  margin-right: calc(100% - 100vw);
+}
+.el-card {
+  margin: 20px 30px;
+}
+.el-table td, .el-table th.is-leaf,.el-table--border, .el-table--group{
+  border-color: #ccc; 
+}
+.el-table--border::after, .el-table--group::after, .el-table::before{
+  background-color: #ccc;
+}
+.el-table td, .el-table th.is-leaf {
+  border-bottom: 1px solid #ccc;
+  border-right: 1px solid #ccc;
+}
+.el-table thead {
+  color: #606266;
+}
+.el-picker-panel__footer {
+    padding: 5px; /*no */
+}
+.el-button.is-plain {
+    color: #000;
+}
+.el-button--mini {
+    font-size: 14px; /*no */
+}
+@media screen and (max-width: 768px) {
+  .el-date-range-picker {
+    width: 90%;
+  }
+  .el-date-range-picker .el-picker-panel__body {
+    min-width: 0px;
+  }
+  .el-date-range-picker__time-header {
+    padding: 4px 3px 5px;/*no */
+  }
+  .el-date-range-picker__time-picker-wrap {
+    padding: 0 2px;/*no */
+  }
+  .el-input__inner {
+    padding: 0 2px;/*no */
+    text-align: center;
+    font-size: 12px;
+  }
+  .el-picker-panel {
+    left: 15px !important;/*no */
+  }
+  .el-date-range-picker__content {
+    padding: 1px;/*no */
+  }
+  .el-date-range-picker__content .el-date-range-picker__header div {
+    margin-left: 20px;/*no */
+    margin-right: 20px;/*no */
+  }
+  .el-date-range-picker__header div {
+    font-size: 13px;/*no */
+  }
+  .el-message {
+    min-width: 250px !important;
+  }
+}
+</style>

+ 396 - 0
src/pages/phoneSubPages/phoneMobileCard.vue

@@ -0,0 +1,396 @@
+<template>
+  <div class="mobilrCard">
+    <el-card>
+      <!-- 表单 -->
+      <el-form ref="form" :model="formData" label-width="85px" label-position="left">
+        <el-form-item label="支持电话卡的类型:">
+          <div style="display:inline-block" class="cardType">
+            <img src="../../assets/move.png" alt="">
+            <span>中国移动</span>
+          </div>
+          <div style="display:inline-block" class="cardType">
+            <img src="../../assets/Unicom.png" alt="">
+            <span>中国联通</span>
+          </div>
+          <div style="display:inline-block" class="cardType">
+            <img src="../../assets/telecom.png" alt="">
+            <span>中国电信</span>
+          </div>
+        </el-form-item>
+        <el-form-item label="充值金额:">
+          <template v-if="phone_amount.length">
+            <el-button
+              :type="idx === curBtn ? 'success' : 'info'"
+              v-for="(item,idx) in phone_amount"
+              :key="idx"
+              @click="hRecharge(item,idx)"
+              size="small"
+              style="margin-left:0;margin-right:6px">{{item}}</el-button>
+          </template>
+          <span v-else style="margin-left: 20px;font-size: 13px;color: #909399;">请选择充值金额</span>
+        </el-form-item>
+        <el-form-item label="手机号:">
+            <el-input
+              type="textarea"
+              placeholder="请填写手机号,最多一次可以充值30单"
+              v-model.trim="formData.code"
+              style="width: 100%;"
+              :rows="8"></el-input>
+        </el-form-item>
+        <el-form-item>
+            <el-button type="primary"
+              @click="rechargeBtn"
+              :loading="loadingSeeCard"
+              element-loading-spinner="el-icon-loading"
+              element-loading-background="rgba(0, 0, 0, 0.5)"
+              :disabled="disabled"
+              size="small">卡号校验</el-button>
+            <el-button type="success" @click="confirmRecharge" :disabled="disabledRecharge" size="small">充值</el-button>
+        </el-form-item>
+      </el-form>
+    </el-card>
+    <el-card style="margin-top:10px">
+        <!-- <p>充值结果:</p> -->
+        <h3 style="margin-bottom:20px">充值结果:</h3>
+        <!-- 提示 -->
+        <el-alert
+          v-if="tableData.length"
+          :title="'一共充值 '+all_no+' 单,成功 '+success_no+' 单,失败 '+error_no+' 单'"
+          type="info"
+          show-icon
+          style="margin-top:10px"
+          :closable="false">
+        </el-alert>
+        <!-- 表格 -->
+        <el-table
+          :data="tableData"
+          border
+          style="width: 100%;margin-top:20px;font-size:13px;"
+          v-loading="loading"
+          element-loading-text="充值中">
+          <el-table-column align="center" prop="card_no" label="手机号" width="170"></el-table-column>
+          <el-table-column align="center" label="订单号" width="170">
+            <template slot-scope="scope" v-if="scope.row.state == true">
+              {{scope.row.err}}
+            </template>
+          </el-table-column>
+          <el-table-column align="center" prop="amount" label="充值金额"></el-table-column>
+          <el-table-column align="center" label="充值状态" width="85">
+            <template slot-scope="scope">
+              <el-tag type="success" size="small" v-if="scope.row.state == true">成功提交</el-tag>
+              <el-tag type="danger" size="small" v-else>失败</el-tag>
+            </template>
+          </el-table-column>
+          <el-table-column align="center" label="错误原因" width="150">
+            <template slot-scope="scope" v-if="scope.row.state != true">
+              {{scope.row.err}}
+            </template>
+          </el-table-column>
+        </el-table>
+    </el-card>
+
+    <!-- 查看弹层 -->
+    <el-dialog
+      title="请审核手机号是否正确(可编辑)"
+      :visible.sync="dialogVisible"
+      width="30%"
+      @close="handleClose">
+      <el-input v-for="(item, idx) in input" :key="idx" v-model="input[idx]" style="margin-bottom: 10px"></el-input>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="handleClose">取 消</el-button>
+        <!-- <el-button type="primary" @click="onSubmit">确认无误</el-button> -->
+        <el-button type="primary" @click="trueBtn">确认无误</el-button>
+      </span>
+    </el-dialog>
+
+    <!-- 充值弹层 -->
+    <el-dialog
+      title="手机卡充值"
+      :visible.sync="dialogVisibleCard"
+      width="30%"
+      @close="handleCloseCard">
+      <el-input v-for="(item, idx) in input" :key="idx" :value="item" style="margin-bottom: 10px"></el-input>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="handleCloseCard">取 消</el-button>
+        <el-button type="primary" @click="onSubmit">确认充值</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+// getRechargeAmount-充值金额 OilCardRecharge-油卡充值
+import { getRechargeAmount, OilCardRecharge } from '@/api'
+export default {
+  name: 'phoneMobileCard',
+  data() {
+    return {
+      formData: {
+        code: ''
+      },
+      // 充值金额
+      phone_amount: [],
+      // 点击的按钮
+      curBtn: '',
+      curMoney: '',
+      // 表格数据
+      tableData: [],
+      // 卡号查看弹层
+      dialogVisible: false,
+      // 卡号充值弹层
+      dialogVisibleCard: false,
+      // 卡号
+      input: [],
+      // 第一位字符
+      firstStr: '',
+      // 文本域字符
+      codeStr: '',
+      // 分割后字符
+      splitStr: '',
+      loading: false,
+      // 充值数
+      all_no: 0,
+      // 成功数
+      success_no: 0,
+      // 失败数
+      error_no: 0,
+      // 查看卡号loading
+      loadingSeeCard: false,
+      disabled: false,
+      disabledRecharge: false,
+      btnLoading: false
+    }
+  },
+  created() {
+    this.getRechargeAmount()
+  },
+  watch: {
+    codeStr(newVal) {
+      console.log('newVal', newVal);
+      // 判断是否有,或者;
+      // console.log('newVal.substr(0,1)',newVal.substr(0,1) == ',');
+      if (newVal.substr(0,1) == "," || newVal.substr(0,1) == "," || newVal.substr(0,1) == ";" || newVal.substr(0,1) == ";") {
+        this.codeStr = this.codeStr.replace(/[,,;;]/g, "")
+        console.log('替换', this.codeStr);
+      }
+      if (this.codeStr.length > 0) {
+        // 手机卡11位
+        if (this.codeStr.length < 11) {
+          this.dialogVisible = false
+          this.dialogVisibleCard = false
+          this.$message.error('请输入合法手机号')
+          return
+        }
+        console.log('手机号', /^1[3-9]\d{9}$/.test(Number(this.codeStr.substr(0,11))));
+        if (!/^1[3-9]\d{9}$/.test(Number(this.codeStr.substr(0,11)))) {
+          this.dialogVisible = false
+          this.dialogVisibleCard = false
+          this.$message.error('请输入合法手机号')
+          return
+        }
+        this.splitStr = this.splitStr == '' ? this.splitStr.concat(this.codeStr.substring(0,11)) : this.splitStr.concat(',' + this.codeStr.substring(0,11))
+        this.codeStr = this.codeStr.substr(11)
+      }
+      if (!newVal) {
+        this.input = this.splitStr.split(',')
+      }
+    },
+    formData(newVal) {
+      if (newVal.code == '') {
+        this.splitStr = ''
+        this.input = []
+      }
+    },
+    input(newVal) {
+      if (newVal && newVal.length > 30) {
+        this.$message.error('一次最多可以充值30单')
+        this.splitStr = ''
+        this.input = []
+        this.dialogVisible = false
+        this.dialogVisibleCard = false
+      }
+    }
+  }, 
+  methods: {
+    // 获取充值金额
+    async getRechargeAmount() {
+      try {
+        const res = await getRechargeAmount()
+        console.log('充值金额', res);
+        if (res && res.code == 200) {
+          this.phone_amount = res.datas.phone_amount
+        }
+      } catch (error) {
+        console.log(error);
+      }
+    },
+    // 点击充值金额
+    hRecharge(item,idx) {
+      this.curMoney = item
+      this.curBtn = idx
+    },
+    // 查看按钮
+    rechargeBtn() {
+      this.disabled = true
+      if (this.dialogVisible) {
+        return
+      }
+      this.loadingSeeCard = true
+      if (!this.formData.code) {
+        this.$message.error('请填写手机号')
+        this.loadingSeeCard = false
+        this.disabled = false
+        return
+      }
+      if (!this.curMoney) {
+        this.$message.error('请选择充值金额')
+        this.loadingSeeCard = false
+        this.disabled = false
+        return
+      }
+      this.dialogVisible = true
+      this.input = []
+      this.splitStr = ''
+      this.codeStr = this.formData.code.replace(/\s/g,"").replace(/[\u4e00-\u9fa5]/g, "")
+      console.log('1', this.codeStr.substr(0,1));
+      this.loadingSeeCard = false
+      setTimeout(() => {
+        this.disabled = false
+      }, 1000)
+
+    },
+    confirmRecharge() {
+      this.disabledRecharge = true
+      if (this.dialogVisibleCard) {
+        return
+      }
+      if (!this.formData.code) {
+        this.$message.error('请填写手机号')
+        this.disabledRecharge = false
+        return
+      }
+      if (!this.curMoney) {
+        this.$message.error('请选择充值金额')
+        this.disabledRecharge = false
+        return
+      }
+      this.dialogVisibleCard = true
+      this.input = []
+      this.splitStr = ''
+      this.codeStr = this.formData.code.replace(/\s/g,"").replace(/[\u4e00-\u9fa5]/g, "")
+      console.log('1', this.codeStr);
+      setTimeout(() => {
+        this.disabledRecharge = false
+      }, 1000)
+    },
+    // 关闭弹层
+    handleClose() {
+      this.dialogVisible = false
+      this.splitStr = ''
+      this.input = []
+
+    },
+    handleCloseCard() {
+      this.dialogVisibleCard = false
+      this.splitStr = ''
+      this.input = []
+    },
+    // 确认无误按钮
+    trueBtn() {
+      this.dialogVisible = false
+      this.splitStr = this.input.toString()
+      this.formData.code = this.splitStr.replace(/[',]/g, '\n')
+      // console.log('this.formData.code', this.formData.code);
+    },
+    // 确认充值
+    async onSubmit() {
+      this.dialogVisibleCard = false
+      this.loading = true
+      try {
+        this.splitStr = this.input.toString()
+        // cardno, amount this.splitStr, this.curMoney
+        let param = new URLSearchParams()
+        param.append('cardno', this.splitStr)
+        param.append('amount', this.curMoney)
+        // const res = await OilCardRecharge({
+        //   cardno: this.splitStr,
+        //   amount: this.curMoney
+        // })
+        const res = await OilCardRecharge(param)
+        console.log('手机卡充值', res);
+        if (res && res.code == 200) {
+          this.tableData = res.datas.data
+          this.all_no = res.datas.all_no
+          this.success_no = res.datas.success_no
+          this.error_no = res.datas.error_no
+          this.splitStr = ''
+          this.curMoney = ''
+          this.curBtn = ''
+          this.formData.code = ''
+        }
+        this.loading = false
+      } catch (error) {
+        console.log(error);
+        this.loading = false
+      }
+    },
+  }
+}
+</script>
+
+<style scoped lang="less">
+.cardType {
+  margin-right: 10px;
+}
+.cardType img {
+  vertical-align: middle;
+  margin-right: 5px;
+}
+.cardType  span {
+  vertical-align: middle;
+}
+/deep/.el-table td, 
+/deep/.el-table th {
+    padding: 7px 0;
+}
+/deep/.el-table .cell,
+/deep/.el-table--border td:first-child .cell,
+/deep/.el-table--border th:first-child .cell {
+    padding-left: 7px;
+}
+/deep/.el-table .cell {
+    padding-right: 7px;
+}
+/deep/.el-card__body {
+  padding: 10px;
+}
+/deep/.el-button--mini{
+    padding: 7px 10px;
+    font-size: 12px;
+}
+</style>
+<style>
+.el-main {
+  padding: 0;
+  margin-right: calc(100% - 100vw);
+}
+.el-card {
+  margin: 20px 30px;
+}
+.el-table td, .el-table th.is-leaf,.el-table--border, .el-table--group{
+  border-color: #ccc; 
+}
+.el-table--border::after, .el-table--group::after, .el-table::before{
+  background-color: #ccc;
+}
+.el-table td, .el-table th.is-leaf {
+  border-bottom: 1px solid #ccc;
+  border-right: 1px solid #ccc;
+}
+.el-table thead {
+  color: #606266;
+}
+.el-message {
+  min-width: 250px !important;
+}
+</style>

+ 418 - 0
src/pages/phoneSubPages/phoneOilCard.vue

@@ -0,0 +1,418 @@
+<template>
+  <div class="oilCard">
+    <el-card>
+      <!-- 表单 -->
+      <el-form ref="form" :model="formData" label-position="left" >
+        <el-form-item label="支持油卡的类型:">
+          <div style="display:inline-block" class="cardType">
+            <img src="../../assets/petroleum.png" alt="">
+            <span>中国石油</span>
+          </div>
+          <div style="display:inline-block" class="cardType">
+            <img src="../../assets/petrifaction.png" alt="">
+            <span>中国石化</span>
+          </div>
+        </el-form-item>
+        <el-form-item label="充值金额:">
+          <template v-if="oil_amount.length">
+            <el-button
+              :type="idx === curBtn ? 'success' : 'info'"
+              v-for="(item,idx) in oil_amount"
+              :key="idx"
+              @click="hRecharge(item,idx)"
+              size="mini">{{item}}</el-button>
+          </template>
+          <span v-else style="font-size: 13px;color: #909399;">请选择充值金额</span>
+        </el-form-item>
+        <el-form-item label="卡号:">
+            <el-input
+              type="textarea"
+              placeholder="请填写油卡号,最多一次可以充值30单"
+              v-model.trim="formData.code"
+              style="width: 80%"
+              :rows="8"></el-input>
+        </el-form-item>
+        <el-form-item style="padding-left:53px;">
+            <el-button type="primary" size="small" @click="rechargeBtn" :disabled="disabled">卡号校验</el-button>
+            <el-button type="success" size="small" @click="confirmRecharge" :disabled="disabledRecharge">充值</el-button>
+        </el-form-item>
+      </el-form>
+    </el-card>
+    <el-card style="margin-top:20px">
+        <h3 style="margin-bottom:20px">充值结果:</h3>
+        <!-- 提示 -->
+        <el-alert
+          v-if="tableData.length"
+          :title="'一共充值 '+all_no+' 条,成功 '+success_no+' 条,失败 '+error_no+' 条'"
+          type="info"
+          show-icon
+          style="margin-top:10px"
+          :closable="false">
+        </el-alert>
+        <!-- 表格 -->
+        <el-table
+          :data="tableData"
+          border
+          style="width: 100%;margin-top:20px;font-size:13px;"
+          v-loading="loading"
+          element-loading-text="充值中">
+          <el-table-column align="center" prop="card_no" label="卡号" width="170"></el-table-column>
+          <el-table-column align="center" label="订单号" width="170">
+            <template slot-scope="scope" v-if="scope.row.state == true">
+              {{scope.row.err}}
+            </template>
+          </el-table-column>
+          <el-table-column align="center" prop="amount" label="充值金额"></el-table-column>
+          <el-table-column align="center" label="充值状态" width="85">
+            <template slot-scope="scope">
+              <el-tag type="success" size="small" v-if="scope.row.state == true">成功提交</el-tag>
+              <el-tag type="danger" size="small" v-else>失败</el-tag>
+            </template>
+          </el-table-column>
+          <el-table-column align="center" label="错误原因" width="150">
+            <template slot-scope="scope" v-if="scope.row.state != true">
+              {{scope.row.err}}
+            </template>
+          </el-table-column>
+        </el-table>
+    </el-card>
+
+    <!-- 查看弹层 -->
+    <el-dialog
+      title="请审核充值卡号是否正确(可编辑)"
+      :visible.sync="dialogVisible"
+      width="80%"
+      @close="handleClose">
+      <el-input v-for="(item, idx) in input" :key="idx" v-model="input[idx]" style="margin-bottom: 10px"></el-input>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="handleClose" size="small">取 消</el-button>
+        <el-button type="primary" size="small" @click="trueBtn">确认无误</el-button>
+      </span>
+    </el-dialog>
+
+    <!-- 充值弹层 -->
+    <el-dialog
+      title="油卡充值"
+      :visible.sync="dialogVisibleCard"
+      width="80%"
+      @close="handleCloseCard">
+      <el-input v-for="(item, idx) in input" :key="idx" :value="item" style="margin-bottom: 10px"></el-input>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="handleCloseCard" size="small">取 消</el-button>
+        <el-button type="primary" size="small" @click="onSubmit">确认充值</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+// getRechargeAmount-充值金额 OilCardRecharge-油卡充值
+import { getRechargeAmount, OilCardRecharge } from '@/api'
+export default {
+  name: 'phoneOilCard',
+  data() {
+    return {
+      formData: {
+        code: ''
+      },
+      // 充值金额
+      oil_amount: [],
+      // 点击的按钮
+      curBtn: '',
+      curMoney: '',
+      // 表格数据
+      tableData: [],
+      // 分页
+      pageSize: 10,
+      pageNumber: 1,
+      total: 0,
+      // 卡号确认弹层
+      dialogVisible: false,
+      dialogVisibleCard: false,
+      // 卡号
+      input: [],
+      // 第一位字符
+      firstStr: '',
+      // 文本域字符
+      codeStr: '',
+      // 分割后字符
+      splitStr: '',
+      loading: false,
+      // 充值数
+      all_no: 0,
+      // 成功数
+      success_no: 0,
+      // 失败数
+      error_no: 0,
+      disabled: false,
+      disabledRecharge: false
+    }
+  },
+  created() {
+    this.getRechargeAmount()
+  },
+  watch: {
+    codeStr(newVal) {
+      console.log('newVal', newVal);
+      // 判断是否有,或者;
+      // console.log('newVal.substr(0,1)',newVal.substr(0,1) == ',');
+      if (newVal.substr(0,1) == "," || newVal.substr(0,1) == "," || newVal.substr(0,1) == ";" || newVal.substr(0,1) == ";") {
+        this.codeStr = this.codeStr.replace(/[,,;;]/, "")
+        console.log('替换', this.codeStr);
+      }
+      if (this.codeStr.length > 0) {
+        this.firstStr = this.codeStr.substr(0,1)
+        // 1-中石化19位 9-中石油16位
+        if (this.firstStr == '1') {
+          if (this.codeStr.length < 19) {
+            this.dialogVisible = false
+            this.dialogVisibleCard = false
+            this.splitStr = ""
+            this.$message.error('请输入合法卡号')
+            return
+          }
+          this.splitStr = this.splitStr == '' ? this.splitStr.concat(this.codeStr.substring(0,19)) : this.splitStr.concat(',' + this.codeStr.substring(0,19))
+          this.codeStr = this.codeStr.substr(19)
+          console.log('codeStr', this.codeStr);
+        } else if (this.firstStr == '9') {
+          if (this.codeStr.length < 16) {
+            this.splitStr = ""
+            this.dialogVisible = false
+            this.dialogVisibleCard = false
+            this.$message.error('请输入合法卡号')
+            return
+          }
+          this.splitStr = this.splitStr == '' ? this.splitStr.concat(this.codeStr.substring(0,16)) : this.splitStr.concat(',' + this.codeStr.substring(0,16))
+          this.codeStr = this.codeStr.substr(16)
+          console.log('codeStr', this.codeStr);
+        } else {
+          this.splitStr = ""
+          this.dialogVisible = false
+          this.dialogVisibleCard = false
+          this.$message.error('请输入合法卡号')
+        }
+      }
+      if (!newVal) {
+        this.input = this.splitStr.split(',')
+      }
+    },
+    formData(newVal) {
+      if (newVal.code == '') {
+        this.splitStr = ''
+        this.input = []
+      }
+    },
+    input(newVal) {
+      if (newVal && newVal.length > 30) {
+        this.splitStr = ''
+        this.input = []
+        this.dialogVisible = false
+        this.dialogVisibleCard = false
+        this.$message.error('一次最多可以充值30单')
+      }
+    }
+  }, 
+  methods: {
+    // 获取充值金额
+    async getRechargeAmount() {
+      try {
+        const res = await getRechargeAmount()
+        console.log('充值金额', res);
+        if (res && res.code == 200) {
+          this.oil_amount = res.datas.oil_amount
+        }
+      } catch (error) {
+        console.log(error);
+      }
+    },
+    // 点击充值金额
+    hRecharge(item,idx) {
+      this.curMoney = item
+      this.curBtn = idx
+    },
+    // 查看按钮
+    rechargeBtn() {
+      this.disabled = true
+      if (this.dialogVisible) {
+        this.disabled = false
+        return
+      }
+      if (!this.formData.code) {
+        this.$message.error('请填写卡号')
+        this.disabled = false
+        return
+      }
+      if (!this.curMoney) {
+        this.$message.error('请选择充值金额')
+        this.disabled = false
+        return
+      }
+      this.dialogVisible = true
+      this.input = []
+      // 去掉中间空格和中文
+      this.codeStr = this.formData.code.replace(/\s/g,"").replace(/[\u4e00-\u9fa5]/g, "")
+      console.log('1', this.codeStr);
+      // this.inputBlur()
+      setTimeout(() => {
+        this.disabled = false
+      }, 1000)
+
+    },
+    // 确认无误按钮
+    trueBtn() {
+      this.dialogVisible = false
+      this.splitStr = this.input.toString()
+      this.formData.code = this.splitStr.replace(/[',]/g, '\n')
+      this.input = []
+      // console.log('this.formData.code', this.formData.code);
+    },
+    // 充值
+    confirmRecharge() {
+      this.disabledRecharge = true
+      if (this.dialogVisibleCard) {
+        return
+      }
+      if (!this.formData.code) {
+        this.disabledRecharge = false
+        this.$message.error('请填写油卡号')
+        return
+      }
+      if (!this.curMoney) {
+        this.disabledRecharge = false
+        this.$message.error('请选择充值金额')
+        return
+      }
+      this.codeStr = this.formData.code.replace(/\s/g,"").replace(/[\u4e00-\u9fa5]/g, "")
+      console.log('1', this.codeStr.substr(0,1));
+      this.input = []
+      this.splitStr = ''
+      this.dialogVisibleCard = true
+      setTimeout(() => {
+        this.disabledRecharge = false
+      }, 1000)
+    },
+    // 关闭弹层
+    handleClose() {
+      this.dialogVisible = false
+      this.splitStr = ''
+      this.input = []
+    },
+    handleCloseCard() {
+      this.dialogVisibleCard = false
+      this.splitStr = ''
+      this.input = []
+    },
+    // 确认充值按钮
+    async onSubmit() {
+      this.dialogVisibleCard = false
+      this.loading = true
+      try {
+        this.splitStr = this.input.toString()
+        // cardno, amount
+        let param = new URLSearchParams()
+        param.append('cardno', this.splitStr)
+        param.append('amount', this.curMoney)
+        // const res = await OilCardRecharge({
+        //   cardno: this.splitStr,
+        //   amount: this.curMoney
+        // })
+        const res = await OilCardRecharge(param)
+        console.log('油卡充值', res);
+        if (res && res.code == 200) {
+          this.tableData = res.datas.data
+          this.all_no = res.datas.all_no
+          this.success_no = res.datas.success_no
+          this.error_no = res.datas.error_no
+          this.splitStr = ''
+          this.curMoney = ''
+          this.curBtn = ''
+          this.formData.code = ''
+        }
+        this.loading = false
+      } catch (error) {
+        console.log(error);
+        this.loading = false
+      }
+    },
+    // 分页
+    async onPageChange(page) {
+        if (page == this.pageNumber) {
+            return;
+        } else {
+            // this.pageNumber = page;
+            // // setTimeout(() => {
+            // //     // this.getActionLogList();
+            // //     this.getOrderList(this.pageNumber)
+            // // }, 0);
+            // const startTime = this.dataRange[0]
+            // const endTime = this.dataRange[1]
+            // const res = await queryList(this.pageNumber, startTime, endTime, this.RechargeType)
+            // console.log('查询订单', res);
+            // if (res && res.code == 200) {
+            //     this.tableData = res.datas.data
+            // }
+        }
+    },
+  }
+}
+</script>
+
+<style scoped lang="less">
+.cardType {
+  margin-right: 10px;
+}
+.cardType img {
+  vertical-align: middle;
+  margin-right: 5px;
+}
+.cardType  span {
+  vertical-align: middle;
+}
+/deep/.el-table td, 
+/deep/.el-table th {
+    padding: 7px 0;
+}
+/deep/.el-table .cell,
+/deep/.el-table--border td:first-child .cell,
+/deep/.el-table--border th:first-child .cell {
+    padding-left: 7px;
+}
+/deep/.el-table .cell {
+    padding-right: 7px;
+}
+/deep/.el-card__body {
+  padding: 10px;
+}
+/deep/.el-button+.el-button {
+    margin-left: 6px;
+}
+/deep/.el-button--mini{
+    padding: 7px 10px;
+    font-size: 12px;
+}
+</style>
+<style>
+.el-main {
+  padding: 0;
+  margin-right: calc(100% - 100vw);
+}
+.el-card {
+  margin: 20px 30px;
+}
+.el-table td, .el-table th.is-leaf,.el-table--border, .el-table--group{
+  border-color: #ccc; 
+}
+.el-table--border::after, .el-table--group::after, .el-table::before{
+  background-color: #ccc;
+}
+.el-table td, .el-table th.is-leaf {
+  border-bottom: 1px solid #ccc;
+  border-right: 1px solid #ccc;
+}
+.el-table thead {
+  color: #606266;
+}
+.el-message {
+  min-width: 250px !important;
+}
+</style>

+ 441 - 0
src/pages/phoneSubPages/phoneOrder.vue

@@ -0,0 +1,441 @@
+<template>
+<el-card>
+<el-container direction="vertical">
+    <el-header height="auto">
+        <el-input
+            style="width:200px;margin-bottom:10px;margin-right: 10px;"
+            placeholder="请输入客户单号"
+            v-model.trim="mch_order"
+            clearable
+            size="small"></el-input>
+        <el-input
+            style="width:200px;margin-bottom:10px;margin-right: 10px;"
+            placeholder="请输入椰子单号"
+            v-model.trim="order_sn"
+            clearable
+            size="small"></el-input>
+        <el-input
+            style="width:200px;margin-bottom:10px;margin-right: 10px;"
+            placeholder="请输入卡号"
+            v-model.trim="card_no"
+            clearable
+            size="small"></el-input>
+        <el-date-picker
+            class="yezi_date"
+            v-model="dataRange"
+            clearable
+            value-format="timestamp"
+            format="yyyy-MM-dd"
+            type="datetimerange"
+            range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期"
+            style="margin-bottom:10px;margin-right: 10px;width:260px"
+            size="small"></el-date-picker>
+        <el-select v-model="RechargeType" clearable placeholder="--充值卡类型--" size="small" style="margin-right: 10px;margin-bottom:10px;width: 140px;">
+            <el-option
+                v-for="item in moneyType"
+                :key="item.value"
+                :label="item.label"
+                :value="item.value">
+            </el-option>
+        </el-select>
+        <el-select v-model="amount" clearable placeholder="--充值面额--" size="small" style="margin-right: 10px;margin-bottom:10px;width: 140px;">
+            <el-option
+                v-for="item in amountConstant"
+                :key="item.value"
+                :label="item.label"
+                :value="item.value">
+            </el-option>
+        </el-select>
+        <el-select v-model="RechargeStatus" clearable placeholder="--充值状态--" size="small" style="margin-right: 10px;margin-bottom:10px;width: 140px;">
+            <el-option
+                v-for="item in orderState"
+                :key="item.value"
+                :label="item.label"
+                :value="item.value">
+            </el-option>
+        </el-select>
+        <el-select
+            v-model="time"
+            placeholder="--充值耗时--"
+            style="margin-right: 10px;margin-bottom:10px;width: 140px;"
+            no-data-text="充值状态为充值中时,才可查询耗时"
+            clearable
+            size="small">
+            <template v-if="RechargeStatus == 30">
+                <el-option
+                    v-for="item in timeConstant"
+                    :key="item.value"
+                    :label="item.label"
+                    :value="item.value">
+                </el-option>
+            </template>
+        </el-select>
+        <div>
+            <el-button style="margin-right:10px;margin-bottom:20px" size="small" type="primary" @click="queryList">查询</el-button>
+            <el-button style="margin-right:10px;margin-left:0px;margin-bottom:20px" size="small" type="danger" @click="onReset">重置</el-button>
+            <!-- <el-button style="margin-right:10px;margin-left:0px;margin-bottom:20px" type="warning" @click="onExport">导出</el-button> -->
+        </div>
+    </el-header>
+   
+    <el-table :data="tableData" border style="width: 1561px;font-size:13px;" v-loading="isLoading" >
+        <el-table-column align="center" type="index" width="50" label="序号" />
+        <el-table-column align="center" prop="mch_order" width="200" label="客户单号"></el-table-column>
+        <el-table-column align="center" prop="card_no" width="180" label="卡号"></el-table-column>
+        <el-table-column align="center" prop="refill_amount" label="充值面额" width="80"></el-table-column>
+        <el-table-column align="center" prop="card_type_name" label="充值卡类型" width="95"></el-table-column>
+        <el-table-column align="center" prop="order_time" width="160" label="充值时间"></el-table-column>
+        <el-table-column align="center" prop="diff_time_text" width="85" label="耗时"></el-table-column>
+        <el-table-column align="center" label="充值状态" width="85">
+            <template slot-scope="{row}">
+                <el-tag type = 'success' v-if="row.order_state == '40'">充值成功</el-tag>
+                <el-tag type = 'warning' v-if="row.order_state == '20'">支付成功</el-tag>
+                <el-tag type = '' v-if="row.order_state == '30'">充值中</el-tag>
+                <el-tag type = 'info' v-if="row.order_state == '10'">新订单</el-tag>
+                <el-tag type = 'danger' v-if="row.order_state == '0'">已取消</el-tag>
+            </template>
+        </el-table-column>
+        <!-- <el-table-column align="center" prop="official_sn" label="批次号"></el-table-column> -->
+        <el-table-column align="center" prop="order_sn" width="185" label="椰子单号"></el-table-column>
+        <el-table-column align="center" prop="official_sn" width="250" label="官方流水号">
+            <template slot-scope="{row}">
+                {{row.official_sn ? row.official_sn : '无'}}
+            </template>
+        </el-table-column>
+        <el-table-column align="center" prop="err_msg" label="失败原因" width="300"></el-table-column>
+        <el-table-column align="center" prop="mch_amount" label="扣款" width="70"></el-table-column>
+    </el-table>
+    <el-row style="margin-top:10px;" type="flex" justify="end">
+        <el-pagination background layout="prev, pager, next" :total="total" :page-size="pageSize" :current-page="pageNumber" @current-change="onPageChange"></el-pagination>
+    </el-row>
+</el-container>
+</el-card>
+</template>
+
+<script>
+import {
+    getOrderList,
+    queryList,
+    exportList
+} from "@/api";
+import { moneyType, orderState, amountConstant, timeConstant } from '@/utils/constants'
+import {JSONToExcelConvertor} from '@/utils/export.js'
+export default {
+    name: 'phoneOrder',
+    data() {
+        return {
+            tableData: [],
+            pageSize: 50,
+            pageNumber: 1,
+            total: 0,
+            // 筛选时间 start_time end_time
+            dataRange: [],
+            startTime: '',
+            endTime: '',
+            // 充值类型 常量
+            moneyType,
+            // 充值卡
+            RechargeType: '',
+            // 是否正在加载
+            isLoading: false,
+            // 充值状态
+            RechargeStatus: '',
+            // 充值状态 常量
+            orderState,
+            // 客户单号
+            mch_order: '',
+            // 充值面额
+            amount: '',
+            // 充值面额-常量
+            amountConstant,
+            // 充值耗时
+            time: '',
+            // 充值耗时-常量
+            timeConstant,
+            // 卡号
+            card_no: '',
+            // 平台单号
+            order_sn: ''
+        };
+    },
+    created () {
+        this.fetchData()
+    },
+    mounted() {
+        this.getOrderList()
+        this.queryList()
+    },
+    // 监听器
+    watch: {
+        dataRange(newVal) {
+            // console.log(newVal);
+            if (newVal == null) {
+                this.startTime = '';
+                this.endTime = '';
+            }
+        },
+        RechargeStatus(newVal) {
+            if (newVal != 30) {
+                this.time = ''
+            }
+        }
+    },
+    methods: {
+        // 获取订单列表
+        async getOrderList () {
+            this.isLoading = true
+            if (this.dataRange == null) {
+                this.startTime = ''
+                this.endTime = ''
+            } else {
+                this.startTime =  this.dataRange[0] || ''
+                this.endTime = this.dataRange[1] || ''
+            }
+            try {
+                let param = new URLSearchParams()
+                param.append('page', 50)
+                param.append('start_time', this.startTime)
+                param.append('end_time', this.endTime)
+                const res = await getOrderList(param)
+                console.log('订单列表', res);
+                if (res && res.code == 200) {
+                    this.tableData = res.datas.data
+                    this.total = res.datas.total * this.pageSize
+                }
+                this.isLoading = false
+            } catch (error) {
+                console.log(error);
+                this.isLoading = false
+            }
+            // const res = await getIp()
+            // console.log('res', res);
+        },
+        // 查询
+        async queryList() {
+            this.isLoading = true
+            if (this.dataRange == null) {
+                this.startTime = ''
+                this.endTime = ''
+            } else {
+                this.startTime =  this.dataRange[0]/1000 || ''
+                this.endTime = this.dataRange[1]/1000 || ''
+            }
+            try {
+                let param = new URLSearchParams()
+                param.append('curpage', this.pageNumber)
+                param.append('start_time', this.startTime)
+                param.append('end_time', this.endTime)
+                param.append('card_type', this.RechargeType)
+                param.append('order_state', this.RechargeStatus)
+                param.append('refill_amount', this.amount)
+                param.append('mch_order', this.mch_order)
+                param.append('time', this.time)
+                param.append('card_no', this.card_no)
+                param.append('order_sn', this.order_sn)
+                // const res = await queryList(this.pageNumber, startTime, endTime, this.RechargeType)
+                const res = await queryList(param)
+                console.log('查询订单', res);
+                if (res && res.code == 200) {
+                    this.tableData = res.datas.data
+                    this.total = res.datas.total * this.pageSize
+                }
+                this.isLoading = false
+            } catch (error) {
+                console.log(error);
+                this.isLoading = false
+            }
+        },
+        // 重置
+        onReset() {
+            this.pageNumber = 1;
+            this.dataRange = [];
+            this.RechargeType = ''
+            this.RechargeStatus = ''
+            this.amount = ''
+            this.mch_order = ''
+            this.time = ''
+            this.card_no = ''
+            this.order_sn = ''
+            this.getOrderList();
+        },
+        // 分页
+        async onPageChange(page) {
+            if (page == this.pageNumber) {
+                return;
+            } else {
+                this.isLoading = true
+                this.pageNumber = page;
+                if (this.dataRange == null) {
+                    this.startTime = ''
+                    this.endTime = ''
+                } else {
+                    this.startTime =  this.dataRange[0]/1000 || ''
+                    this.endTime = this.dataRange[1]/1000 || ''
+                }
+                try {
+                    let param = new URLSearchParams()
+                    param.append('curpage', this.pageNumber)
+                    param.append('start_time', this.startTime)
+                    param.append('end_time', this.endTime)
+                    param.append('card_type', this.RechargeType)
+                    param.append('order_state', this.RechargeStatus)
+                    param.append('refill_amount', this.amount)
+                    param.append('mch_order', this.mch_order)
+                    param.append('card_no', this.card_no)
+                    param.append('order_sn', this.order_sn)
+                    // const res = await queryList(this.pageNumber, startTime, endTime, this.RechargeType)
+                    const res = await queryList(param)
+                    console.log('查询订单', res);
+                    if (res && res.code == 200) {
+                        this.tableData = res.datas.data
+                    }
+                    this.isLoading = false
+                } catch (error) {
+                    console.log(error);
+                    this.isLoading = false
+                }
+            }
+        },
+        // 设置默认日期
+        fetchData() {
+            let date = new Date()
+            let y = date.getFullYear()
+            let m = date.getMonth() + 1
+            let d = date.getDate()
+            let dEnd = date.getDate() + 1
+            let timeStart =  (new Date(`${y}/${m}/${d}`)).getTime()
+            let timeEnd = (new Date(`${y}/${m}/${dEnd}`)).getTime()
+            this.dataRange[0] = timeStart
+            this.dataRange[1] = timeEnd
+        },
+        // 导出
+        async onExport() {
+            if (this.dataRange == null) {
+                this.startTime = ''
+                this.endTime = ''
+            } else {
+                this.startTime =  this.dataRange[0]/1000 || ''
+                this.endTime = this.dataRange[1]/1000 || ''
+            }
+            try {
+                let param = new URLSearchParams()
+                param.append('curpage', this.pageNumber)
+                param.append('start_time', this.startTime)
+                param.append('end_time', this.endTime)
+                param.append('card_type', this.RechargeType)
+                param.append('order_state', this.RechargeStatus)
+                param.append('refill_amount', this.amount)
+                param.append('mch_order', this.mch_order)
+                param.append('time', this.time)
+                param.append('card_no', this.card_no)
+                param.append('order_sn', this.order_sn)
+                const res = await exportList(param)
+                console.log('导出', res);
+                if (res && res.code == 200) {
+                    JSONToExcelConvertor(res.datas.data, "交易流水", res.datas.title )
+                }
+            } catch (error) {
+                console.log(error);
+            }
+        }
+    },
+};
+</script>
+
+<style scoped lang="less">
+.el-header {
+    padding: 0;
+}
+/deep/.el-table td, 
+/deep/.el-table th {
+    padding: 7px 0;
+}
+/deep/.el-table .cell,
+/deep/.el-table--border td:first-child .cell,
+/deep/.el-table--border th:first-child .cell {
+    padding-left: 7px;
+}
+/deep/.el-table .cell {
+    padding-right: 7px;
+}
+/deep/.el-date-editor.yezi_date .el-range-separator {
+    padding: 0;
+    width: 20px;/*no */
+}
+/deep/.el-date-editor.yezi_date .el-range-input {
+    width: 100px;/*no */
+}
+/deep/.el-input,
+/deep/.el-date-editor.yezi_date .el-range-input,
+/deep/.el-date-editor.yezi_date .el-range-separator {
+    font-size: 13px; /*no */
+}
+</style>
+<style>
+.el-select-dropdown__empty {
+    padding: 5px;
+}
+.el-main {
+  padding: 0;
+  margin-right: calc(100% - 100vw);
+}
+.el-card {
+  margin: 20px 30px;
+}
+.el-table td, .el-table th.is-leaf,.el-table--border, .el-table--group{
+  border-color: #ccc; 
+}
+.el-table--border::after, .el-table--group::after, .el-table::before{
+  background-color: #ccc;
+}
+.el-table td, .el-table th.is-leaf {
+  border-bottom: 1px solid #ccc;
+  border-right: 1px solid #ccc;
+}
+.el-table thead {
+  color: #606266;
+}
+.el-picker-panel__footer {
+    padding: 5px; /*no */
+}
+.el-button.is-plain {
+    color: #000;
+}
+.el-button--mini {
+    font-size: 14px; /*no */
+}
+@media screen and (max-width: 768px) {
+  .el-date-range-picker {
+    width: 90%;
+  }
+  .el-date-range-picker .el-picker-panel__body {
+    min-width: 0px;
+  }
+  .el-date-range-picker__time-header {
+    padding: 4px 3px 5px;/*no */
+  }
+  .el-date-range-picker__time-picker-wrap {
+    padding: 0 2px;/*no */
+  }
+  .el-input__inner {
+    padding: 0 2px;/*no */
+    text-align: center;
+    font-size: 12px;
+  }
+  .el-picker-panel {
+    left: 15px !important;/*no */
+  }
+  .el-date-range-picker__content {
+    padding: 1px;/*no */
+  }
+  .el-date-range-picker__content .el-date-range-picker__header div {
+    margin-left: 20px;/*no */
+    margin-right: 20px;/*no */
+  }
+  .el-date-range-picker__header div {
+    font-size: 13px;/*no */
+  }
+  .el-message {
+    min-width: 250px !important;
+  }
+}
+</style>

+ 244 - 0
src/pages/phoneSubPages/phoneReconciliation.vue

@@ -0,0 +1,244 @@
+<template>
+  <div class="reconciliation">
+    <el-card>
+       <div style="margin-bottom:20px;">
+          <el-select
+            v-model="value"
+            placeholder="请选择日期类型"
+            style="margin-bottom:10px" clearable
+            size="small">
+            <el-option
+              v-for="item in RecTime"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value">
+            </el-option>
+          </el-select>
+          <el-date-picker
+            v-model="dataRange"
+            clearable value-format="timestamp" format="yyyy-MM-dd"
+            type="datetimerange" range-separator="至"
+            start-placeholder="开始日期" end-placeholder="结束日期" style="width:260px;margin-bottom:10px"
+            @focus="hFocusDate"
+            :disabled="isDisabled"
+            size="small"></el-date-picker><br>
+          <el-button type="primary" @click="onSearch" :loading="searchLoading" size="small">查询</el-button>
+          <el-button style="margin-left:10px;" type="danger" @click="onReset" size="small">重置</el-button>
+      </div>
+      <el-table :data="tableData" border style="width: 100%;font-size:13px;" v-loading="isLoading">
+        <el-table-column align="center" prop="count" label="订单总数" />
+        <el-table-column align="center" prop="successCount" label="成功订单数" />
+        <el-table-column align="center" prop="errorCount" label="失败订单数" />
+        <el-table-column align="center" prop="sendCount" label="充值中订单数" width="100"></el-table-column>
+        <el-table-column align="center" prop="refill_amounts" label="总充值金额"></el-table-column>
+        <el-table-column align="center" prop="mch_amounts" label="总扣款金额"></el-table-column>
+    </el-table>
+    </el-card>
+  </div>
+</template>
+
+<script>
+// getRec-对账管理
+import { getRec } from '@/api'
+import { RecTime } from '@/utils/constants'
+export default {
+  name: 'reconciliation',
+  data () {
+    return {
+      dataRange: [],
+      startTime: '',
+      endTime: '',
+      value: '',
+      RecTime,
+      recForm: {
+        // 订单总数
+        count: 0,
+        // 成功
+        successCount: 0,
+        // 失败
+        errorCount: 0,
+        // 充值中
+        sendCount: 0,
+        // 总充值金额
+        refill_amounts: 0,
+        // 扣款金额
+        mch_amounts: 0,
+      },
+      isDisabled: false,
+      tableData: [],
+      isLoading: false,
+      searchLoading: false
+    }
+  },
+  created() {
+  },
+  // 监听器
+  watch: {
+    dataRange(newVal) {
+      // console.log(newVal);
+      if (newVal == null) {
+          this.startTime = '';
+          this.endTime = '';
+      }
+    },
+    value: {
+      handler(newVal) {
+        // console.log('newVal', newVal);
+        if (!newVal) {
+          this.isDisabled = true
+        } else {
+          this.isDisabled = false
+        }
+      },
+      immediate: true
+    }
+  },
+  methods: {
+    // 查询
+    async onSearch() {
+      try {
+        if (!this.value) {
+          if (this.timer) {
+            window.clearTimeout(this.timer)
+          }
+          this.timer = setTimeout(() => {
+            this.$message.warning('请选择日期类型')
+          }, 1000)
+          return
+        }
+        this.searchLoading = true
+        this.isLoading = true
+        this.startTime = this.dataRange[0]/1000
+        this.endTime = this.dataRange[1]/1000
+        let param = new URLSearchParams()
+        param.append('time_type', this.value)
+        param.append('start_time', this.startTime)
+        param.append('end_time', this.endTime)
+        let res = await getRec(param)
+        console.log('对账管理', res);
+        if (res && res.code == 200) {
+          this.recForm = res.datas
+          if (!this.tableData.length) {
+            this.tableData.push(res.datas)
+          } else {
+            const obj = this.tableData[0]
+            // console.log('obj', obj);
+            this.tableData[0] = Object.assign(obj, res.datas)
+          }
+        }
+        this.isLoading =  false
+        this.searchLoading = false
+      } catch (error) {
+        console.log(error);
+        this.isLoading =  false
+        this.searchLoading = false
+      }
+    },
+    // 重置
+    onReset() {
+      this.dataRange = [];
+      this.startTime = ''
+      this.endTime = ''
+      this.value = ''
+      this.recForm.count = 0
+      this.recForm.successCount = 0
+      this.recForm.errorCount = 0
+      this.recForm.sendCount = 0
+      this.recForm.refill_amounts = 0
+      this.recForm.mch_amounts = 0
+      this.tableData = []
+    },
+    // 时间获取焦点
+    hFocusDate() {
+      if (!this.value) {
+        if (this.timer) {
+            window.clearTimeout(this.timer)
+          }
+          this.timer = setTimeout(() => {
+            this.$message.warning('请选择日期类型')
+          }, 1000)
+      }
+    }
+  }
+}
+</script>
+
+<style scoped lang="less">
+/deep/.el-form-item {
+  margin-bottom: 5px;/*no */
+}
+/deep/.el-card {
+  padding-bottom: 0;
+}
+/deep/.el-date-editor .el-range-input {
+    width: 100px;/*no */
+}
+/deep/.el-form-item__label {
+    text-align: left;
+}
+/deep/.el-table td, 
+/deep/.el-table th {
+    padding: 7px 0;
+}
+/deep/.el-table .cell,
+/deep/.el-table--border td:first-child .cell,
+/deep/.el-table--border th:first-child .cell {
+    padding-left: 7px;
+}
+/deep/.el-table .cell {
+    padding-right: 7px;
+}
+</style>
+<style>
+.el-table td, .el-table th.is-leaf,.el-table--border, .el-table--group{
+  border-color: #ccc; 
+}
+.el-table--border::after, .el-table--group::after, .el-table::before{
+  background-color: #ccc;
+}
+.el-table td, .el-table th.is-leaf {
+  border-bottom: 1px solid #ccc;
+  border-right: 1px solid #ccc;
+}
+.el-table thead {
+  color: #606266;
+}
+@media screen and (max-width: 768px) {
+  .el-date-range-picker {
+    width: 90%;
+  }
+  .el-date-range-picker .el-picker-panel__body {
+    min-width: 0px;
+  }
+  .el-date-range-picker__time-header {
+    padding: 4px 3px 5px;/*no */
+  }
+  .el-date-range-picker__time-picker-wrap {
+    padding: 0 2px;/*no */
+  }
+  .el-input__inner {
+    padding: 0 2px;/*no */
+    text-align: center;
+    font-size: 12px;
+  }
+  .el-picker-panel {
+    left: 15px !important;/*no */
+  }
+  .el-date-range-picker__content {
+    padding: 1px;/*no */
+  }
+  .el-date-range-picker__content .el-date-range-picker__header div {
+    margin-left: 20px;/*no */
+    margin-right: 20px;/*no */
+  }
+  .el-date-range-picker__header div {
+    font-size: 13px;/*no */
+  }
+  .el-message {
+    min-width: 250px !important;
+  }
+  .el-date-editor .el-range-separator {
+    width: 8%;
+  }
+}
+</style>

+ 607 - 0
src/pages/phoneSubPages/phoneView.vue

@@ -0,0 +1,607 @@
+<template>
+<div>
+    <!-- 用户设置 -->
+    <el-card>
+        <el-container direction="vertical">
+            <h3 style="margin-bottom:10px">用户设置:</h3>
+            <el-form label-width="90px" :model="userForm" :rules="userRule" ref="userForm" label-position="left">
+                <el-form-item label="用户名:">
+                    <el-input size="small" v-model.trim="userForm.name" style="width: 200px;"></el-input>
+                </el-form-item>
+                <el-form-item label="联系方式:" prop="phone">
+                    <el-input size="small" v-model.trim="userForm.phone" style="width: 200px;"></el-input>
+                </el-form-item>
+                <el-form-item style="margin-bottom:10px">
+                    <el-button type="primary" size="small" @click="onSubUser">提交</el-button>
+                    <el-button type="danger" size="small" @click="resetForm">重置</el-button>
+                </el-form-item>
+            </el-form>
+        </el-container>
+    </el-card>
+    <!-- 开发者设置 -->
+    <el-card style="margin-top:10px">
+        <el-container direction="vertical">
+            <h3 style="margin-bottom:10px">开发者设置:</h3>
+            <el-form :model="formKey" :rules="ruleKey" ref="keyForm" label-position="left">
+                <el-form-item label="密钥设置:" :prop="useKey == '1' ? 'ReSecurityKey' : 'securityKey'"  class="keySet">
+                    <el-input v-if="useKey == '1'" size="small" v-model.trim="formKey.ReSecurityKey" autocomplete="off" style="width: 300px;margin-right:10px"></el-input>
+                    <el-input v-else size="small" v-model.trim="formKey.securityKey" autocomplete="off" style="width: 300px;margin-right:10px"></el-input>
+                    <el-button type="primary" size="small" @click="updateKey">{{useKey == '1' ? '重设' : '设置'}}</el-button>
+                    <span style="color:rgb(255 1 1 / 0.7);margin-left:10px;font-size:12px;">请输入32位字符串,用于接口生成签名</span>
+                </el-form-item>
+                <el-form-item label="ip白名单:" style="margin-bottom:10px;" label-width="85px">
+                    <div v-if="cIpList">
+                        <el-input style="width: 150px;margin-bottom: 10px;margin-right: 10px;" size="small" :value="ipFormData.name"></el-input>
+                        <i class="el-icon-circle-plus-outline" style="color:#409EFF;font-size:22px;" @click="add"></i>
+                    </div>
+                    <template v-else>
+                        <div v-for="(item, idx) in ipList" :key="item">
+                            <el-input style="width: 150px;margin-bottom: 10px;margin-right: 10px;" size="small" :value="item"></el-input>
+                            <template v-if="idx == 0">
+                                <i class="el-icon-circle-plus-outline" style="color:#409EFF;font-size:22px;" @click="add"></i>
+                                <i class="el-icon-remove-outline" style="color:#F56C6C;margin-left:10px;font-size:22px;" @click="del(item)"></i>
+                            </template>
+                            <!-- <i v-if="idx == 0" class="el-icon-circle-plus-outline" style="color:#409EFF;" @click="add"></i> -->
+                            <i v-else class="el-icon-remove-outline" style="color:#F56C6C;font-size:22px;" @click="del(item)"></i>
+                        </div>
+                    </template>
+                </el-form-item>
+            </el-form>
+            <!-- 添加ip弹层 -->
+            <el-dialog title="添加ip白名单" :visible="dialogFormVisible" @close="btnCancle" width="80%">
+                <el-form :model="ipFormData" :rules="rules" ref="ipFormData" label-width="50px">
+                    <el-form-item label="ip:" prop="name">
+                        <el-input v-model="ipFormData.name" autocomplete="off" style="width: 200px"></el-input>
+                    </el-form-item>
+                </el-form>
+                <span slot="footer" class="dialog-footer">
+                    <el-button @click="btnCancle" size="small">取 消</el-button>
+                    <el-button type="primary" @click="onSubmit('ipFormData')" size="small">确 定</el-button>
+                </span>
+            </el-dialog>
+        </el-container>
+    </el-card>
+    <!-- 余额预警电话设置 -->
+    <el-card style="margin-top:10px">
+        <el-container direction="vertical">
+            <h3 style="margin-bottom:10px">余额预警电话设置:</h3>
+            <el-form ref="formWarning" :model="balanceForm" :rules="balanceRules">
+                <el-form-item
+                    label="设置余额预警:"
+                    prop="alarm_amount"
+                    style="margin-bottom: 10px;"
+                    label-width="110px">
+                    <el-input
+                        size="small"
+                        v-model="balanceForm.alarm_amount"
+                        autocomplete="off"
+                        style="width: 140px;margin-right:10px"
+                        onkeyup="value=value.replace(/[^\d.]/g,'')"
+                        @blur="balanceForm.alarm_amount = $event.target.value"
+                        ></el-input>
+                    <el-button type="primary" size="small" @click="onBalance">设置</el-button>
+                    <span style="color:rgb(255 1 1 / 0.7);margin-left:10px;font-size:12px;">建议设置50000及以上余额预警</span>
+                </el-form-item>
+                <el-form-item style="margin-bottom: 0;color:#606266">
+                    <span style="font-size:12px;display: block;line-height">请设置余额预警电话,当账户所剩余额达到预警额度时,将会给预留电话发送短信提醒,以免给您的业务带来不便。每隔五分钟提醒一次,最多提示五次。</span>
+                </el-form-item>
+                <el-form-item label="设置预警电话:" style="margin-bottom:10px">
+                    <div v-if="cWarningList">
+                        <el-input style="width: 150px;margin-bottom: 10px;margin-right: 10px;" :value="addphone.phone" size="small"></el-input>
+                        <i class="el-icon-circle-plus-outline" style="color:#409EFF;font-size:22px;" @click="addwphone"></i>
+                    </div>
+                    <template v-else>
+                        <div v-for="(item, idx) in warningList" :key="item">
+                            <el-input style="width: 150px;margin-bottom: 10px;margin-right: 10px;" :value="item" size="small"></el-input>
+                            <template v-if="idx == 0">
+                                <i class="el-icon-circle-plus-outline" style="color:#409EFF;font-size:22px;" @click="addwphone"></i>
+                                <i class="el-icon-remove-outline" style="color:#F56C6C;margin-left:10px;font-size:22px;" @click="delwphone(item)"></i>
+                            </template>
+                            <i v-else class="el-icon-remove-outline" style="color:#F56C6C;font-size:22px;" @click="delwphone(item)"></i>
+                        </div>
+                    </template>
+                </el-form-item>
+            </el-form>
+            <!-- 添加预警弹层 -->
+            <el-dialog title="添加预警电话" :visible="warningDialogVisible" @close="cancleWarning">
+                <el-form :model="addphone" :rules="ruleAddphone" ref="addphone" label-width="100px">
+                    <el-form-item label="预警电话:" prop="phone">
+                        <el-input v-model="addphone.phone" autocomplete="off" style="width: 300px"></el-input>
+                    </el-form-item>
+                </el-form>
+                <span slot="footer" class="dialog-footer">
+                    <el-button @click="cancleWarning">取 消</el-button>
+                    <el-button type="primary" @click="onSubmitWarning('addphone')">确 定</el-button>
+                </span>
+            </el-dialog>
+        </el-container>
+    </el-card>
+</div>
+</template>
+
+<script>
+// getIpList获取Ip列表 delIpList-删除 addIp-添加 getUserInfo-用户信息 onSubUser-提交用户设置 addwphone-添加预警电话 delwphone-删除
+import {
+    // getIpList,
+    delIpList,
+    addIp,
+    getUserInfo,
+    updateKey,
+    onSubUser,
+    addwphone,
+    delwphone,
+    phonrRec
+} from "@/api";
+export default {
+    name: 'pageView',
+    data() {
+        var checkAmount = (rule, value, callback) => {
+            console.log('rule', rule, value);
+            console.log('value', value);
+            if (value === '') {
+                return callback(new Error('余额预警不能为空'));
+            } else if (value.indexOf(".") != -1 && value.split('.').length > 2) {
+                callback(new Error('请输入正确格式,只能有一位小数点'));
+            } else if (value.indexOf(".") != -1 && value.split('.')[1].length > 2) {
+                callback(new Error('小数点后面只能有两位'));
+            } else {
+                var Money = parseFloat(value).toFixed(3);
+                var MoneyResult = Money.substring(0, Money.length - 1);
+                var xsd = MoneyResult.toString().split(".");
+                if (xsd.length > 1) {
+                    if (xsd[1].length == 1) {
+                        this.balanceForm.alarm_amount = MoneyResult;
+                    }
+                    if (xsd[1].length > 1) {
+                        this.balanceForm.alarm_amount = xsd[0].toString() + "." + xsd[1].toString().substring(0, 2);
+                    }
+                }
+                callback()
+            }
+        };
+        var checkPhone = (rule, value, callback) => {
+            if (!value) {
+                return callback(new Error('联系方式不能为空'));
+            } else if (!/^1[3-9]\d{9}$/.test(value)) {
+                callback(new Error('请输入合法手机号'));
+            } else {
+                callback()
+            }
+        };
+        return {
+            pageSize: 10,
+            pageNumber: 1,
+            ipList: [],
+            total: 0,
+            // ip
+            ip: null,
+            // ip弹层
+            dialogFormVisible: false,
+            // 新增ip数据
+            ipFormData: {
+                name: ''
+            },
+            // 表单校验
+            rules: {
+                name: [
+                    { required: true, message: '请输入ip', trigger: 'blur' },
+                    { pattern: /((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)/, message:'请输入合法ip', trigger: 'blur' }
+                ]
+            },
+            repeatIp: false,
+            // 密钥校验,只能是数字和字母
+            formKey: { 
+                securityKey: '',
+                ReSecurityKey: ''
+            },
+            ruleKey: {
+                securityKey: [
+                    { required: true, message: '请输入密钥', trigger: 'blur' },
+                    { min: 1, max: 32, message:'请输入32位的字符串', trigger: 'blur' }
+                ],
+                // 之前设置过密钥
+                ReSecurityKey: [
+                    { min: 1, max: 32, message:'请输入32位的字符串', trigger: 'blur' }
+                ]
+            },
+            // 是否设置过密钥 1-设置过
+            useKey: '',
+            // 用户设置
+            userForm: {
+                name: '',
+                phone: ''
+            },
+            userRule: {
+                phone: [
+                    {validator: checkPhone, trigger: 'blur'}
+                ]
+            },
+            // 预警电话列表
+            warningList: [],
+            // 添加预警
+            addphone: {
+                phone: ''
+            },
+            ruleAddphone: {
+                phone: [
+                    { required: true, message: '请输入预警电话', trigger: 'blur' },
+                    { pattern: /^1[3-9]\d{9}$/, message:'请输入正确的电话', trigger: 'blur' }
+                ]
+            },
+            warningDialogVisible: false,
+            repeatPhone: false,
+            // 余额预警
+            balanceForm: {
+                alarm_amount: '',
+            },
+            balanceRules: {
+                alarm_amount: [
+                    {validator: checkAmount, trigger: 'blur'}
+                ]
+            },
+            // 话费充值设置
+            phoneForm: {
+                // time_out: '',
+                quality: 1
+            },
+            phoneRules: {
+            }
+        };
+    },
+    created() {
+        // this.getIpList();
+        this.getUserInfo()
+    },
+    computed: {
+        cIpList() {
+            return this.ipList < 1
+        },
+        cWarningList() {
+            return this.warningList < 1
+        }
+    },
+    methods: {
+        // 删除
+        del(ip) {
+            console.log('ip', ip);
+            // 提示
+            this.$confirm("确认删除该ip?", {
+                confirmButtonText: "确定",
+                cancelButtonText: "取消",
+                type: "warning",
+                customClass: 'phone_sty'
+            })
+            .then(async () => {
+                // 调用删除接口
+                try {
+                    let param = new URLSearchParams()
+                    param.append('ip', ip)
+                    // const res = await delIpList({ip: ip})
+                    const res = await delIpList(param)
+                    console.log('删除ip', res);
+                    if (res && res.code == 200) {
+                        // 提示
+                        this.$message({
+                            message: '删除成功',
+                            type: 'success',
+                        });
+                        // 获取列表
+                        this.getUserInfo()
+                    } else {
+                        this.$message.error('删除失败')
+                    }
+                } catch (error) {
+                    console.log(error);
+                    this.$message.error('删除失败')
+                }
+            })
+            .catch(() => {
+                return false;
+            });
+        },
+        // 添加
+        add() {
+            this.ipFormData.name = ''
+            this.dialogFormVisible = true
+        },
+        // 关闭弹层
+        btnCancle() {
+            this.dialogFormVisible = false
+            this.$refs.ipFormData.resetFields()
+        },
+        // 确定添加
+        onSubmit(formName) {
+            this.$refs[formName].validate(async(valid) => {
+                if (valid) {
+                    // console.log(valid);
+                    if (this.ipList.length > 0) {
+                        // this.ipList.forEach(item => {
+                        //     this.repeatIp = item.ip == this.ipFormData.name
+                        // })
+                        this.repeatIp = this.ipList.find((item => item == this.ipFormData.name))
+                    }
+                    if (this.repeatIp) {
+                        this.$message.error('该ip已存在')
+                        return
+                    }
+                    // console.log('校验通过');
+                    try {
+                        let param = new URLSearchParams()
+                        param.append('ip', this.ipFormData.name)
+                        const res = await addIp(param)
+                        console.log('添加ip', res);
+                        if (res && res.code == 200) {
+                            this.$message({
+                                message: '添加ip成功',
+                                type: 'success'
+                            });
+                            this.getUserInfo()
+                            // this.dialogFormVisible = false
+                            // this.ipFormData.name = ''
+                        } else {
+                            this.$message.error('添加ip失败')
+                        } 
+                        this.dialogFormVisible = false
+                        this.ipFormData.name = ''
+                    } catch (error) {
+                        console.log(error);
+                        this.dialogFormVisible = false
+                        this.ipFormData.name = ''
+                        this.$message.error('添加ip失败')
+                    }
+                }
+            });
+        },
+        // 获取商户号
+        async getUserInfo() {
+            try {
+                const res = await getUserInfo()
+                console.log('个人中心', res);
+                if (res && res.code == 200) {
+                    this.ipList = res.datas.ips
+                    this.useKey = res.datas.use_key
+                    this.userForm.name = res.datas.contact_name != 'null' ? res.datas.contact_name : ''
+                    this.userForm.phone = res.datas.contact_phone != 'null' ? res.datas.contact_phone : ''
+                    this.balanceForm.alarm_amount = res.datas.alarm_amount != 'null' ? res.datas.alarm_amount : ''
+                    this.warningList = res.datas.warning_phone
+                    // this.phoneForm.time_out = res.datas.time_out
+                    this.phoneForm.quality = res.datas.quality
+                }
+            } catch (error) {
+                console.log(error);
+            }
+        },
+        // 设置密钥
+        async updateKey() {
+            let res
+            this.$refs.keyForm.validate(async(valid) => {
+                if (valid) {
+                    if (this.useKey == '1') {
+                        try {
+                            let param = new URLSearchParams()
+                            param.append('secure_key', this.formKey.ReSecurityKey)
+                            // res = await updateKey(this.formKey.ReSecurityKey)
+                            res = await updateKey(param)
+                        } catch (error) {
+                            console.log(error);
+                        }
+                    } else {
+                        try {
+                            let param = new URLSearchParams()
+                            param.append('secure_key', this.formKey.securityKey)
+                            // res = await updateKey(this.formKey.securityKey)
+                            res = await updateKey(param)
+                        } catch (error) {
+                            console.log(error);
+                        }
+                    }
+                    console.log('密钥', res);
+                    if (res && res.code == 200) {
+                        this.$message.success('设置密钥成功')
+                    } else {
+                        this.$message.error('设置密钥失败')
+                    }
+                    this.formKey.ReSecurityKey = ''
+                    this.formKey.securityKey = ''
+                }
+            })
+        },
+        // 提交用户设置
+        onSubUser() {
+            this.$refs.userForm.validate(async(valid) => {
+                // console.log('valid', valid);
+                if (valid) {
+                    try {
+                        let param = new URLSearchParams()
+                        param.append('contact_name', this.userForm.name)
+                        param.append('contact_phone', this.userForm.phone)
+                        const res = await onSubUser(param)
+                        if (res && res.code && res.code == 200) {
+                            this.$message.success('提交用户设置成功')
+                            this.getUserInfo()
+                        }
+                        // this.userForm.name = ''
+                        // this.userForm.phone = ''
+                        console.log('用户设置提交', res);
+                    } catch (error) {
+                        console.log(error);
+                        this.$message.error('提交用户设置失败')
+                    }
+                }
+            })
+        },
+        // 重置
+        resetForm() {
+            this.userForm.name = ''
+            this.$refs.userForm.resetFields();
+        },
+        // 添加预警
+        addwphone() {
+            this.addphone.phone = ''
+            this.warningDialogVisible = true
+        },
+        // 关闭预警弹层
+        cancleWarning() {
+            this.warningDialogVisible = false
+            this.$refs.addphone.resetFields()
+        },
+        // 确认添加
+        onSubmitWarning(formName) {
+            this.$refs[formName].validate(async(valid) => {
+                if (valid) {
+                    console.log(valid);
+                    if (this.warningList.length > 0) {
+                        this.repeatPhone = this.warningList.find((item => item == this.addphone.phone))
+                    }
+                    if (this.repeatPhone) {
+                        this.$message.error('该预警电话已存在')
+                        return
+                    }
+                    // console.log('校验通过');
+                    try {
+                        let param = new URLSearchParams()
+                        param.append('phone', this.addphone.phone)
+                        const res = await addwphone(param)
+                        console.log('添加预警电话', res);
+                        if (res && res.code == 200) {
+                            this.$message({
+                                message: '添加预警电话成功',
+                                type: 'success'
+                            });
+                            this.getUserInfo()
+                            // this.dialogFormVisible = false
+                            // this.ipFormData.name = ''
+                        } else {
+                            this.$message.error('添加预警电话失败')
+                        } 
+                        this.warningDialogVisible = false
+                        this.addphone.phone = ''
+                    } catch (error) {
+                        console.log(error);
+                        this.warningDialogVisible = false
+                        this.addphone.phone = ''
+                        this.$message.error('添加预警电话失败')
+                    }
+                }
+            });
+        },
+        // 删除预警电话
+        delwphone(phone) {
+            console.log('phone',phone);
+            // 提示
+            this.$confirm("确认删除该预警电话?", {
+                confirmButtonText: "确定",
+                cancelButtonText: "取消",
+                type: "warning",
+            })
+            .then(async () => {
+                // 调用删除接口
+                try {
+                    let param = new URLSearchParams()
+                    param.append('phone', phone)
+                    // const res = await delIpList({ip: ip})
+                    const res = await delwphone(param)
+                    console.log('删除预警电话', res);
+                    if (res && res.code == 200) {
+                        // 提示
+                        this.$message({
+                            message: '删除预警电话成功',
+                            type: 'success'
+                        });
+                        // 获取列表
+                        this.getUserInfo()
+                    } else {
+                        this.$message.error('删除预警电话失败')
+                    }
+                } catch (error) {
+                    console.log(error);
+                    this.$message.error('删除预警电话失败')
+                }
+            })
+            .catch(() => {
+                return false;
+            });
+        },
+        // 设置余额预警
+        async onBalance() {
+            try {
+                // if (!this.warningList.length) {
+                //     this.warningDialogVisible = true
+                //     return
+                // }
+                let param = new URLSearchParams()
+                param.append('alarm_amount', this.balanceForm.alarm_amount)
+                const res = await onSubUser(param)
+                // console.log('设置余额预警', res);
+                if (res && res.code == 200) {
+                    this.getUserInfo()
+                    this.$message.success('设置余额预警成功')
+                }
+            } catch (error) {
+                console.log(error);
+                this.$message.error('设置余额预警失败')
+            }
+        },
+        // 设置回调时间
+        onSetTime() {
+            this.$refs.phoneForm.validate(async(valid) => {
+                if (valid) {
+                    try {
+                        let param = new URLSearchParams()
+                        param.append('quality', this.phoneForm.quality)
+                        // param.append('time_out', this.phoneForm.time_out)
+                        const res = await phonrRec(param)
+                        console.log('设置-话费', res);
+                        if (res && res.code == 200) {
+                            this.getUserInfo()
+                            this.$message.success('设置话费充值成功')
+                        }
+                    } catch (error) {
+                        console.log(error);
+                        this.$message.error('设置话费充值失败')
+                    }
+                }
+            })
+        }
+    },
+};
+</script>
+
+<style scoped lang="less">
+.dialog-footer {
+  display: block;
+  text-align: center;
+}
+.dialog-footer .el-button {
+    margin: 0 30px;
+
+}
+.el-icon-circle-plus-outline,
+.el-icon-remove-outline {
+    font-size: 25px;
+    vertical-align: middle;
+}
+.el-alert {
+    padding: 0px 10px;
+}
+.keySet .el-button {
+    margin-right: 10px;
+}
+.el-card {
+    padding-bottom: 0px;
+}
+/deep/.el-card__body {
+    padding: 15px;
+}
+</style>
+<style>
+.el-main {
+  padding: 0;
+}
+.el-card {
+  margin: 20px 30px;
+}
+.el-message {
+  min-width: 250px !important;
+}
+</style>

+ 7 - 1
src/pages/subPages/balance.vue

@@ -20,6 +20,9 @@
         </el-col>
         <el-col :span="14">
             <el-form  :model="balanceForm">
+                <el-form-item v-if="credit_bonus" label="授信可用金额:">
+                    {{credit_bonus}}
+                </el-form-item>
                 <el-form-item label="当前余额:">
                     {{available_predeposit}}
                 </el-form-item>
@@ -272,7 +275,9 @@ export default {
             evidence_amounts: '',
             searchLoading: false,
             // 大写金额
-            wordsAmount: ''
+            wordsAmount: '',
+            // 授信可用金额
+            credit_bonus: ''
         };
     },
     mounted() {
@@ -540,6 +545,7 @@ export default {
                     this.evidence_count = res.datas.evidence_count
                     this.warningList = res.datas.warning_phone
                     this.evidence_amounts = res.datas.evidence_amounts
+                    this.credit_bonus = res.datas.credit_bonus
                 }
             } catch (error) {
                 console.log(error);

+ 65 - 1
src/router/index.js

@@ -24,6 +24,13 @@ const phoneIndex = () => import('@/pages/phoneIndex');
 // 首页
 const phoneHome = () => import('@/pages/phoneSubPages/phoneHome');
 const phoneBalance = () => import('@/pages/phoneSubPages/phoneBalance');
+const phoneOrder = () => import('@/pages/phoneSubPages/phoneOrder');
+const phoneMessage = () => import('@/pages/phoneSubPages/phoneMessage');
+const phoneOilCard = () => import('@/pages/phoneSubPages/phoneOilCard');
+const phoneMobileCard = () => import('@/pages/phoneSubPages/phoneMobileCard');
+const phoneReconciliation = () => import('@/pages/phoneSubPages/phoneReconciliation');
+const phoneView = () => import('@/pages/phoneSubPages/phoneView');
+const phoneDoc = () => import('@/pages/phoneSubPages/phoneDoc');
 
 Vue.use(VueRouter)
 
@@ -114,6 +121,48 @@ Vue.use(VueRouter)
         name:'phoneBalance',
         component:phoneBalance
       },
+      // 订单管理
+      {
+        path:'/phoneOrder',
+        name:'phoneOrder',
+        component:phoneOrder
+      },
+      // 账户日志 phoneMessage
+      {
+        path:'/phoneMessage',
+        name:'phoneMessage',
+        component:phoneMessage
+      },
+      // 油卡充值
+      {
+        path:'/phoneOilCard',
+        name:'phoneOilCard',
+        component: phoneOilCard
+      },
+      // 手机卡充值 phoneMobileCard
+      {
+        path:'/phoneMobileCard',
+        name:'phoneMobileCard',
+        component: phoneMobileCard
+      },
+      // 对账管理 phoneReconciliation
+      {
+        path:'/phoneReconciliation',
+        name:'phoneReconciliation',
+        component: phoneReconciliation
+      },
+      // 设置 phoneView
+      {
+        path:'/phoneView',
+        name:'phoneView',
+        component: phoneView
+      },
+      // 接口文档 phoneDoc
+      {
+        path:'/phoneDoc',
+        name:'phoneDoc',
+        component: phoneDoc
+      }
     ]
   }
 ]
@@ -123,11 +172,26 @@ const router = new VueRouter({
   mode: 'hash',
   base: '/merchant'
 })
-
+/* 判断PC或移动端 */
+function IsPC() {
+  var userAgentInfo = navigator.userAgent;
+  var Agents = ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"];
+  var flag = true;
+  for (var v = 0; v < Agents.length; v++) {
+    if (userAgentInfo.indexOf(Agents[v]) > 0) {
+      flag = false;
+      break;
+    }
+  }
+  return flag;
+}
 router.beforeEach((to,from,next)=>{
   if (to.path !== '/login' && !getUser('name')) {
     next('/login')
   }
+  if (IsPC() && to.path.indexOf('phone')>0) {
+    next('/login')
+  }
   next();
 });