123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508 |
- <template>
- <view>
- <view class="uni-header">
- <view class="uni-group">
- <uni-stat-breadcrumb />
- </view>
- <view class="uni-group">
- <button class="uni-button" type="default" size="mini" @click="search">搜索</button>
- <download-excel class="hide-on-phone" :fields="exportExcel.fields" :data="exportExcelData" :type="exportExcel.type" :name="exportExcel.filename">
- <button class="uni-button" type="primary" size="mini">导出 Excel</button>
- </download-excel>
- </view>
- </view>
- <view class="uni-container">
- <view class="uni-stat--x">
- <uni-stat-tabs label="平台选择" type="boldLine" mode="platform" v-model="query.platform" @change="platformChange" />
- </view>
- <unicloud-db ref="udb" :collection="collectionList" field="user_id,nickname,provider,provider_pay_type,uni_platform,status,type,order_no,out_trade_no,transaction_id,device_id,client_ip,openid,description,err_msg,total_fee,refund_fee,refund_count,refund_list,provider_appid,appid,user_order_success,create_date,pay_date,notify_date,cancel_date" :where="where" page-data="replace"
- :orderby="orderby" :getcount="true" :page-size="options.pageSize" :page-current="options.pageCurrent"
- v-slot:default="{data,pagination,loading,error,options}" :options="options" loadtime="manual" @load="onqueryload">
- <uni-table ref="table" :loading="loading" :emptyText="error.message || loading ? '请求中...' : '没有更多数据'" border stripe type="" @selection-change="selectionChange" style="min-height: 900px;">
- <uni-tr>
- <uni-th align="center">序号</uni-th>
- <uni-th ref="user_id" align="center" :filterDefaultValue="filterDefaultValueUserId" filter-type="search" @filter-change="filterChange($event, 'user_id')" sortable @sort-change="sortChange($event, 'user_id')">用户</uni-th>
- <uni-th align="center" filter-type="select" :filter-data="options.filterData.provider_localdata" @filter-change="filterChange($event, 'provider')">支付供应商</uni-th>
- <uni-th align="center" filter-type="search" @filter-change="filterChange($event, 'provider_pay_type')" sortable @sort-change="sortChange($event, 'provider_pay_type')">支付方式</uni-th>
- <uni-th align="center" filter-type="search" @filter-change="filterChange($event, 'uni_platform')" sortable @sort-change="sortChange($event, 'uni_platform')">应用平台</uni-th>
- <uni-th align="center" filter-type="select" :filter-data="options.filterData.status_localdata" @filter-change="filterChange($event, 'status')">订单状态</uni-th>
- <uni-th align="center" filter-type="search" @filter-change="filterChange($event, 'type')" sortable @sort-change="sortChange($event, 'type')">订单类型</uni-th>
- <uni-th align="center" filter-type="search" @filter-change="filterChange($event, 'order_no')" sortable @sort-change="sortChange($event, 'order_no')">业务系统订单号</uni-th>
- <uni-th align="center" filter-type="search" @filter-change="filterChange($event, 'out_trade_no')" sortable @sort-change="sortChange($event, 'out_trade_no')">支付插件订单号</uni-th>
- <uni-th align="center" filter-type="search" @filter-change="filterChange($event, 'transaction_id')" sortable @sort-change="sortChange($event, 'transaction_id')">交易单号</uni-th>
- <uni-th align="center" filter-type="search" @filter-change="filterChange($event, 'description')" sortable @sort-change="sortChange($event, 'description')">支付描述</uni-th>
- <uni-th align="center" filter-type="range" @filter-change="filterChange($event, 'total_fee', 0.01)" sortable @sort-change="sortChange($event, 'total_fee')">订单支付金额</uni-th>
- <uni-th align="center" filter-type="range" @filter-change="filterChange($event, 'refund_fee', 0.01)" sortable @sort-change="sortChange($event, 'refund_fee')">订单退款金额</uni-th>
- <uni-th align="center" filter-type="range" @filter-change="filterChange($event, 'refund_count')" sortable @sort-change="sortChange($event, 'refund_count')">当前退款笔数</uni-th>
- <uni-th align="center" sortable @sort-change="sortChange($event, 'user_order_success')">回调状态</uni-th>
- <uni-th align="center" filter-type="timestamp" @filter-change="filterChange($event, 'create_date')" sortable @sort-change="sortChange($event, 'create_date')">创建时间</uni-th>
- <uni-th align="center" filter-type="timestamp" @filter-change="filterChange($event, 'pay_date')" sortable @sort-change="sortChange($event, 'pay_date')">支付时间</uni-th>
- <uni-th align="center" filter-type="timestamp" @filter-change="filterChange($event, 'cancel_date')" sortable @sort-change="sortChange($event, 'cancel_date')">取消时间</uni-th>
- <uni-th align="center" filter-type="search" @filter-change="filterChange($event, 'provider_appid')" sortable @sort-change="sortChange($event, 'provider_appid')">开放平台appid</uni-th>
- <uni-th align="center" filter-type="search" @filter-change="filterChange($event, 'appid')" sortable @sort-change="sortChange($event, 'appid')">DCloud AppId</uni-th>
- <uni-th align="center" filter-type="search" @filter-change="filterChange($event, 'device_id')" sortable @sort-change="sortChange($event, 'device_id')">设备ID</uni-th>
- <uni-th align="center" filter-type="search" @filter-change="filterChange($event, 'client_ip')" sortable @sort-change="sortChange($event, 'client_ip')">客户端IP</uni-th>
- <uni-th align="center" filter-type="search" @filter-change="filterChange($event, 'openid')" sortable @sort-change="sortChange($event, 'openid')">openid</uni-th>
- </uni-tr>
- <uni-tr v-for="(item,index) in data" :key="index">
- <uni-td align="center">{{ parseInt((index+1) + (pagination.current-1) * pagination.size) }} </uni-td>
- <uni-td align="center"><text class="text-btn" @click="pageToUser(item)">{{ nameFormat(item) }}</text> </uni-td>
- <uni-td align="center">{{options.provider_valuetotext[item.provider]}}</uni-td>
- <uni-td align="center">{{item.provider_pay_type}}</uni-td>
- <uni-td align="center">{{item.uni_platform}}</uni-td>
- <uni-td align="center">{{options.status_valuetotext[item.status]}}</uni-td>
- <uni-td align="center">{{item.type}}</uni-td>
- <uni-td align="center">{{item.order_no}}</uni-td>
- <uni-td align="center">{{item.out_trade_no}}</uni-td>
- <uni-td align="center">{{item.transaction_id}}</uni-td>
- <uni-td align="center">{{item.description}}</uni-td>
- <uni-td align="center">{{ (item.total_fee * 0.01).toFixed(2) }}</uni-td>
- <uni-td align="center">{{ (item.refund_fee * 0.01).toFixed(2) }}</uni-td>
- <uni-td align="center">{{item.refund_count}}</uni-td>
- <uni-td align="center">
- <view v-if="item.user_order_success === true" style="color:#18bc37">✔正常</view>
- <view v-else-if="[-1,0].indexOf(item.status) > -1 ">-</view>
- <view v-else style="color:#e43d33">●异常</view>
- </uni-td>
- <uni-td align="center">
- <uni-dateformat :threshold="[0, 0]" :date="item.create_date"></uni-dateformat>
- </uni-td>
- <uni-td align="center">
- <uni-dateformat :threshold="[0, 0]" :date="item.pay_date"></uni-dateformat>
- </uni-td>
- <uni-td align="center">
- <uni-dateformat :threshold="[0, 0]" :date="item.cancel_date"></uni-dateformat>
- </uni-td>
- <uni-td align="center">{{item.provider_appid}}</uni-td>
- <uni-td align="center">{{item.appid}}</uni-td>
- <uni-td align="center">{{item.device_id}}</uni-td>
- <uni-td align="center">{{item.client_ip}}</uni-td>
- <uni-td align="center">{{item.openid}}</uni-td>
- </uni-tr>
- </uni-table>
- <view class="uni-pagination-box">
- <uni-pagination show-icon :page-size="pagination.size" v-model="pagination.current" :total="pagination.count" @change="onPageChanged" />
- </view>
- </unicloud-db>
- </view>
- <uni-popup ref="popup" type="center" :animation="false">
- <view style="padding: 30px;background-color: #ffffff;width: 500px;">
- <view style="margin-bottom: 20px;text-align: center;font-size: 20px;font-weight: bold;">退款确认</view>
- <uni-forms ref="refundForm" :modelValue="refundFormData" label-position="left" labelWidth="100px" :rules="refundFormRules">
- <uni-forms-item label="退款金额" name="refund_fee">
- <uni-easyinput type="text" v-model.number="refundFormData.refund_fee" placeholder="请输入退款金额" :clearable="false" ></uni-easyinput>
- <view style="color: #666;margin-top: 5px;font-size: 12px;">最大可退:{{ refundFormData.max_refund_fee }}</view>
- </uni-forms-item>
- <uni-forms-item label="退款原因" name="refund_desc">
- <uni-easyinput type="textarea" v-model="refundFormData.refund_desc" placeholder="请输入退款原因" :clearable="false" />
- </uni-forms-item>
- <button type="warn" style="width: 100px;height: 40px;font-size: 16px;" @click="confirmRefund(refundFormData);">确定</button>
- </uni-forms>
- </view>
- </uni-popup>
- </view>
- </template>
- <script>
- import { enumConverter, filterToWhere } from '../../../../js_sdk/validator/uni-pay-orders.js';
- // 引入支付云对象
- const uniPayCo = uniCloud.importObject("uni-pay-co");
- const db = uniCloud.database();
- // 表查询配置
- const dbOrderBy = 'create_date desc'; // 排序字段
- const dbSearchFields = ['order_no', 'out_trade_no', 'transaction_id']; // 模糊搜索字段,支持模糊搜索的字段列表。联表查询格式: 主表字段名.副表字段名,例如用户表关联角色表 role.role_name
- // 分页配置
- const pageSize = 20;
- const pageCurrent = 1;
- const orderByMapping = {
- "ascending": "asc",
- "descending": "desc"
- };
- import {
- mapfields,
- stringifyQuery,
- stringifyField,
- stringifyGroupField,
- getTimeOfSomeDayAgo,
- division,
- format,
- formatDate,
- parseDateTime,
- getFieldTotal,
- debounce
- } from '@/js_sdk/uni-stat/util.js'
- export default {
- data() {
- return {
- collectionList: "uni-pay-orders",
- query: {
- appid: '',
- platform_id: '',
- uni_platform: '',
- version: '',
- pay_date: [],
- },
- where: '',
- orderby: dbOrderBy,
- orderByFieldName: "",
- selectedIndexs: [],
- filterDefaultValueUserId: "",
- refundFormData:{
- out_trade_no: "",
- max_refund_fee: "",
- refund_fee:"",
- refund_desc: ""
- },
- refundFormRules:{
- refund_fee: {
- rules:[
- // 校验 name 不能为空
- { required: true,errorMessage: '退款金额必须>0' },
- // 对name字段进行长度验证
- {
- minimum: 0.01,
- maximum: 0,
- errorMessage: '最大可退 {maximum} 元',
- }
- ],
- },
- refund_desc: {
- rules:[
- // 校验 name 不能为空
- { required: true,errorMessage: '请输入退款原因' },
- ],
- }
- },
- options: {
- pageSize,
- pageCurrent,
- filterData: {
- "provider_localdata": [{
- "text": "微信支付",
- "value": "wxpay"
- },
- {
- "text": "支付宝",
- "value": "alipay"
- },
- {
- "text": "苹果应用内支付",
- "value": "appleiap"
- }
- ],
- "status_localdata": [{
- "text": "已关闭",
- "value": -1
- },
- {
- "text": "未支付",
- "value": 0
- },
- {
- "text": "已支付",
- "value": 1
- },
- {
- "text": "已部分退款",
- "value": 2
- },
- {
- "text": "已全额退款",
- "value": 3
- }
- ]
- },
- ...enumConverter
- },
- imageStyles: {
- width: 64,
- height: 64
- },
- exportExcel: {
- "filename": "uni-pay-orders.xls",
- "type": "xls",
- "fields": {
- "用户ID": "user_id",
- "用户昵称": "nickname",
- "支付供应商": "provider",
- "支付方式": "provider_pay_type",
- "应用平台": "uni_platform",
- "订单状态": "status",
- "支付失败原因": "err_msg",
- "订单类型": "type",
- "业务系统订单号": "order_no",
- "支付插件订单号": "out_trade_no",
- "交易单号": "transaction_id",
- "支付描述": "description",
- "订单支付金额": "total_fee",
- "订单退款金额": "refund_fee",
- "当前退款笔数": "refund_count",
- "退款详情": "refund_list",
- "回调状态": "user_order_success",
- "创建时间": "create_date",
- "支付时间": "pay_date",
- "异步通知时间": "notify_date",
- "取消时间": "cancel_date",
- "开放平台appid": "provider_appid",
- "DCloud AppId": "appid",
- "设备ID": "device_id",
- "客户端IP": "client_ip",
- "openid": "openid",
- }
- },
- exportExcelData: []
- }
- },
- onLoad(e) {
- this._filter = {}
- if (e.user_id) {
- this.filterDefaultValueUserId = e.user_id;
- this.filterChange({
- filterType: "search",
- filter: e.user_id,
- }, "user_id");
- }
- },
- onReady() {
- this.$refs.udb.loadData()
- },
- methods: {
- onqueryload(data) {
- this.exportExcelData = data
- },
- getWhere() {
- let where = "";
- let {
- pay_date,
- appid,
- version,
- uni_platform,
- //query, // 模糊查询
- } = this.query;
- if (pay_date && pay_date.length == 2) {
- where += ` && pay_date>=${pay_date[0]} && pay_date<=${pay_date[1]}`;
- }
- if (appid) {
- where += ` && appid=='${appid}'`;
- }
- if (version) {
- where += ` && stat_data.app_version=='${version}'`;
- }
- if (uni_platform) {
- where += ` && stat_data.platform=='${uni_platform}'`;
- }
- // if (query) {
- // const queryRe = new RegExp(query, 'i');
- // let queryReStr = dbSearchFields.map(name => queryRe + '.test(' + name + ')').join(' || ');
- // where += ` && (${queryReStr})`;
- // }
- where = where.substring(3).trim();
- // console.log('where: ', where)
- return where;
- },
- search() {
- const newWhere = this.getWhere()
- this.where = newWhere
- this.$nextTick(() => {
- this.loadData()
- })
- },
- loadData(clear = true) {
- this.$refs.udb.loadData({
- clear
- })
- },
- onPageChanged(e) {
- this.selectedIndexs.length = 0
- this.$refs.table.clearSelection()
- this.$refs.udb.loadData({
- current: e.current
- })
- },
- navigateTo(url, clear) {
- // clear 表示刷新列表时是否清除页码,true 表示刷新并回到列表第 1 页,默认为 true
- uni.navigateTo({
- url,
- events: {
- refreshData: () => {
- this.loadData(clear)
- }
- }
- })
- },
- // 多选处理
- selectedItems() {
- let dataList = this.$refs.udb.dataList
- return this.selectedIndexs.map(i => dataList[i]._id)
- },
- // 批量删除
- delTable() {
- this.$refs.udb.remove(this.selectedItems(), {
- success: (res) => {
- this.$refs.table.clearSelection()
- }
- })
- },
- // 多选
- selectionChange(e) {
- this.selectedIndexs = e.detail.index
- },
- refundPopup(key, item){
- if (key) {
- let {
- total_fee = 0,
- refund_fee = 0,
- out_trade_no
- } = item;
- let max_refund_fee = Number(((total_fee - refund_fee) / 100).toFixed(2));
- this.refundFormData.max_refund_fee = max_refund_fee;
- this.refundFormData.refund_fee = max_refund_fee;
- this.refundFormData.out_trade_no = out_trade_no;
- this.refundFormRules.refund_fee.rules[1].maximum = max_refund_fee;
- this.$refs.popup.open();
- } else {
- this.refundFormData.max_refund_fee = "";
- this.refundFormData.refund_fee = "";
- this.refundFormData.out_trade_no = "";
- this.refundFormRules.refund_fee.rules[1].maximum = 0;
- this.$refs.popup.close();
- }
- },
- // 主动退款
- async confirmRefund(item) {
- let {
- total_fee = 0,
- refund_fee = 0,
- out_trade_no,
- refund_desc
- } = item;
- item.refund_fee = Number((item.refund_fee).toFixed(2));
- this.$refs.refundForm.validate().then(async formData=>{
- //console.log('表单数据信息:', formData);
- let apply_refund_fee = Number(refund_fee);
- if (isNaN(apply_refund_fee) || apply_refund_fee <= 0) {
- uni.showToast({
- title: "请输入正确的退款金额",
- icon: 'none',
- success: () => {
- setTimeout(() => {
- this.confirmRefund(item);
- }, 500);
- }
- })
- return;
- }
- let refundData = {
- out_trade_no,
- refund_fee: parseInt(apply_refund_fee * 100), // 金额已分为单位,100 = 1元
- refund_desc,
- };
- //console.log('refundData: ', refundData)
- let res = await uniPayCo.refund(refundData);
- if (!res.errCode) {
- this.refundPopup(false);
- this.loadData(false);
- }
- }).catch(err =>{
- //console.log('表单错误信息:', err);
- });
- },
- sortChange(e, name) {
- this.orderByFieldName = name;
- if (e.order) {
- this.orderby = name + ' ' + orderByMapping[e.order]
- } else {
- this.orderby = ''
- }
- this.$refs.table.clearSelection()
- this.$nextTick(() => {
- this.$refs.udb.loadData()
- })
- },
- filterChange(e, name, k) {
- if (k && e.filter) {
- if (typeof e.filter == "object") {
- if (typeof e.filter[0] === "number") e.filter[0] = e.filter[0] / k;
- if (typeof e.filter[1] === "number") e.filter[1] = e.filter[1] / k;
- }
- }
- this._filter[name] = {
- type: e.filterType,
- value: e.filter,
- }
- let newWhere = filterToWhere(this._filter, db.command)
- if (Object.keys(newWhere).length) {
- this.where = newWhere
- } else {
- this.where = ''
- }
- this.$nextTick(() => {
- this.$refs.udb.loadData()
- })
- },
- platformChange(id, index, name, item) {
- this.query.version = 0
- this.query.uni_platform = item.code
- },
- nameFormat(item) {
- if (!item.user_id) {
- return "匿名用户";
- } else if (item.nickname) {
- return `${item.user_id}(${item.nickname})`
- } else {
- return item.user_id;
- }
- },
- pageToUser(item) {
- let { user_id } = item;
- uni.navigateTo({
- url: `/pages/system/user/list?id=${user_id}`
- });
- },
- },
- watch: {
- query: {
- deep: true,
- handler(val) {
- this.search()
- }
- }
- },
- computed: {
- versionQuery() {
- const {
- appid,
- uni_platform
- } = this.query
- const query = stringifyQuery({
- appid,
- uni_platform
- })
- return query
- }
- },
- }
- </script>
- <style lang="scss" scoped>
- .text-btn{
- color: $uni-color-primary;
- cursor: pointer;
- margin: 0 5px;
- }
- </style>
|