10 Commits

Author SHA1 Message Date
danaisuiyuan
e2d52ba4cc docs(czrt6): 0511 迁移说明写入 16 位用户 uid/id 范围
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 09:25:03 +08:00
danaisuiyuan
d8ad6cde20 feat(integral-external): 新增寄卖外部免认证三件套页面 2026-05-02 06:13:41 +08:00
danaisuiyuan
49900919c6 chore(admin): 恢复 crmeb-admin application-byjyw149.yml
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-02 04:30:02 +08:00
danaisuiyuan
5cbca4ba76 revert(env,uniapp): 保留 sxsy80 业务合并,恢复 byjyw149 环境与合同 PDF
- 恢复 admin/front application.yml、admin 端 env、WaUserController 合同模板与域名
- 恢复 single_uniapp22miao 中与域名/签约相关的页面与 config
- 移除合并中新增的多客户 profile 与 sxsy80/czcf82 合同 PDF 资源

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-02 04:26:38 +08:00
apple
f43950eabf fix(integral-external): 外部用户列表用户 ID 筛选默认可空
Replace el-input-number (min clamped to 1) with text uidStr and only
send uid when a valid positive integer is entered.

Made-with: Cursor
2026-04-27 13:44:24 +08:00
apple
708bf9af48 feat(sxsy80): 外部用户 UID 筛选与积分明细展示
User list API accepts uid; admin external pages tighten filters and
integral log maps self-bonus rows via wa_selfbonus_log for display.

Made-with: Cursor
2026-04-27 13:30:05 +08:00
apple
5c4450c417 docs(sxsy80): 迁移文档、清理脚本与 wa_merchandise 提取工具
补充数据迁移说明与 cleanup SQL;增加从 dump 提取保留 id 与生成 INSERT 的脚本及产物。

Made-with: Cursor
2026-04-27 12:13:19 +08:00
apple
901bf6f500 docs(czrt6): 池州瑞棠数据迁移说明、dump 与可执行 SQL
新增从 dump 生成的 INSERT 脚本、按主键预删后执行的 pymysql 运行器,并在文档中记录执行方式与结果摘要。

Made-with: Cursor
2026-04-27 12:13:12 +08:00
apple
e7ffbbf302 docs(sxsy80): 补充文档、合同资源与数据清理脚本
- 更新前后端 sign_contract_sxsy80.pdf
- 增加 com-sxsy80 说明、数据迁移与 SQL/执行脚本
- 增加 com-xsj33 数据迁移说明与 docs 下合同源文件

Made-with: Cursor
2026-04-26 16:50:36 +08:00
apple
3c6ec4ed73 feat(sxsy80): 太原树英商贸环境与域名配置
- 新增 application-sxsy80.yml(前后端),MySQL/Redis 指向 106.14.132.80,imagePath 与 sync shop_14
- 默认 profile 切换为 sxsy80
- 合同 PDF 与落库域名 https://sxsy.cichude.com
- uni-app:积分域 sxsy-jf、抢购跳转 sxsy、静态合同路径
- backend-adminend:VUE_APP_BASE_API 指向 sxsy-jf
- 分支 sxsy80 基于 origin/czcf82

Made-with: Cursor
2026-04-26 16:37:46 +08:00
77 changed files with 10078 additions and 269 deletions

1
.gitignore vendored
View File

@@ -15,6 +15,7 @@ frontend/yarn.lock
# Backend
backend/target/
backend/**/target/
backend/**/logs/
backend/**/*.log
backend/.idea/

View File

@@ -8,8 +8,8 @@ ENV = 'development'
# VUE_APP_BASE_API = 'http://jfanyueadmin.szxingming.com'
# VUE_APP_BASE_API = 'http://jfadmin.wenjinhui.com'
# VUE_APP_BASE_API = 'http://jfadmin-bsy.bosenyuan.com'
# czcf82 项目(池州春芳商贸)
VUE_APP_BASE_API = 'https://czcf-jf.uj345.com'
# byjyw149 项目(宝应金雅文商贸)
VUE_APP_BASE_API = 'https://jf.jinyawen.com'
# hapr191 项目(淮安鹏然商贸)
# VUE_APP_BASE_API = 'http://jfadmin.hapengran.com'

View File

@@ -8,8 +8,8 @@ ENV = 'production'
# miao33 项目
# VUE_APP_BASE_API = 'http://jfadmin.xiashengjun.com'
# czcf82 项目(池州春芳商贸)
VUE_APP_BASE_API = 'https://czcf-jf.uj345.com'
# byjyw149 项目(宝应金雅文商贸)
VUE_APP_BASE_API = 'https://jf.jinyawen.com'
# hapr191 项目(淮安鹏然商贸)
# VUE_APP_BASE_API = 'http://jfadmin.hapengran.com'

View File

@@ -39,3 +39,59 @@ export function getExternalIntegralLog(data) {
data: body,
});
}
/**
* 寄卖订单 列表(免认证)
*/
export function getExternalWaOrderList(params) {
return requestNoAuth({
url: 'external/integral/wa-order/list',
method: 'get',
params,
});
}
/**
* 寄卖订单 详情(免认证)
*/
export function getExternalWaOrderInfo(id) {
return requestNoAuth({
url: 'external/integral/wa-order/info',
method: 'get',
params: { id },
});
}
/**
* 团队每日对账报表(免认证)
*/
export function getExternalTeamDailyReport(params) {
return requestNoAuth({
url: 'external/integral/team-report/daily',
method: 'get',
params,
});
}
/**
* 团队每日对账报表 - Excel 导出(免认证)
*/
export function exportExternalTeamDailyReport(params) {
return requestNoAuth({
url: 'external/integral/team-report/daily/export',
method: 'get',
params,
responseType: 'blob',
});
}
/**
* 今日抢单用户列表(免认证)
*/
export function getExternalGrabUserList(params) {
return requestNoAuth({
url: 'external/integral/grab-user/list',
method: 'get',
params,
});
}

View File

@@ -24,6 +24,24 @@ const integralExternalRouter = {
name: 'IntegralExternalUserDetail',
meta: { title: '用户积分明细' },
},
{
path: 'wa-order',
component: () => import('@/views/integral-external/wa-order/index'),
name: 'IntegralExternalWaOrder',
meta: { title: '寄卖订单' },
},
{
path: 'team-report',
component: () => import('@/views/integral-external/team-report/index'),
name: 'IntegralExternalTeamReport',
meta: { title: '团队日报' },
},
{
path: 'grab-user',
component: () => import('@/views/integral-external/grab-user/index'),
name: 'IntegralExternalGrabUser',
meta: { title: '今日抢单用户' },
},
],
};

View File

@@ -28,6 +28,11 @@ service.interceptors.request.use(
// 响应拦截器 — 不拦截 401 跳转
service.interceptors.response.use(
(response) => {
// Blob / arraybuffer 等二进制响应直接透传,不做业务码拆包
const responseType = response.config && response.config.responseType;
if (responseType === 'blob' || responseType === 'arraybuffer') {
return response.data;
}
const res = response.data;
if (res.code !== 0 && res.code !== 200) {
Message({

View File

@@ -121,6 +121,27 @@ export default {
url: '/integral-external/user/integral-detail',
alwaysShow: true,
},
{
bgColor: '#F56C6C',
icon: 'icondingdanguanli',
title: '寄卖订单',
url: '/integral-external/wa-order',
alwaysShow: true,
},
{
bgColor: '#67C23A',
icon: 'iconfenxiaoguanli',
title: '团队日报',
url: '/integral-external/team-report',
alwaysShow: true,
},
{
bgColor: '#E6A23C',
icon: 'iconhuiyuanguanli',
title: '今日抢单用户',
url: '/integral-external/grab-user',
alwaysShow: true,
},
],
statisticData: [
{ title: '待发货订单', num: 0, path: '/order/index', perms: ['admin:order:list'] },

View File

@@ -0,0 +1,297 @@
<template>
<div class="divBox relative">
<!-- 顶部搜索区 -->
<el-card class="box-card">
<div class="container">
<el-form
ref="searchForm"
:model="tableFrom"
inline
size="small"
label-width="100px"
>
<el-form-item label="用户ID">
<el-input
v-model="tableFrom.uid"
placeholder="请输入用户ID"
class="selWidth"
clearable
@keyup.enter.native="seachList"
/>
</el-form-item>
<el-form-item label="联系方式:">
<el-input
v-model="tableFrom.mobile"
placeholder="请输入手机号 / 账号"
class="selWidth"
clearable
@keyup.enter.native="seachList"
/>
</el-form-item>
<el-form-item label="上级ID">
<el-input
v-model="tableFrom.pid"
placeholder="请输入上级ID"
class="selWidth"
clearable
@keyup.enter.native="seachList"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="seachList">查询</el-button>
<el-button icon="el-icon-refresh-left" @click="resetHandler">重置</el-button>
</el-form-item>
</el-form>
</div>
</el-card>
<!-- 主表 -->
<el-card class="box-card mt10">
<div class="header-actions">
<el-button size="mini" icon="el-icon-refresh" circle @click="getList" />
<el-button size="mini" icon="el-icon-upload2" circle @click="exportCsv" />
</div>
<el-table
v-loading="listLoading"
:data="tableData.data"
size="mini"
class="table"
highlight-current-row
:header-cell-style="{ fontWeight: 'bold' }"
>
<el-table-column prop="id" label="用户ID" min-width="80" />
<el-table-column prop="username" label="账号" min-width="130">
<template slot-scope="scope">
<span>{{ scope.row.username || scope.row.mobile || '-' }}</span>
</template>
</el-table-column>
<el-table-column prop="nickname" label="昵称" min-width="100" show-overflow-tooltip>
<template slot-scope="scope">
<span>{{ scope.row.nickname || '-' }}</span>
</template>
</el-table-column>
<el-table-column label="昨日卖/今日买" min-width="120" align="center">
<template slot-scope="scope">
<span>{{ scope.row.prevSellCnt || 0 }}/{{ scope.row.todayBuyCnt || 0 }}</span>
</template>
</el-table-column>
<el-table-column label="合同" min-width="80" align="center">
<template slot-scope="scope">
<el-link
v-if="scope.row.contract"
type="primary"
:underline="false"
@click="openContract(scope.row.contract)"
>查看</el-link>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column prop="mobile" label="联系方式" min-width="130" />
<el-table-column label="上级ID" min-width="90" align="center">
<template slot-scope="scope">
<span>{{ scope.row.pid || '-' }}</span>
</template>
</el-table-column>
<el-table-column label="最高可抢单数" min-width="110" align="center">
<template slot-scope="scope">
<span>{{ scope.row.maxOrder ? scope.row.maxOrder : '未设置' }}</span>
</template>
</el-table-column>
<el-table-column prop="todayBuyAmount" label="今日购买总金额" min-width="130" align="right" />
<el-table-column prop="todaySellAmount" label="今日卖出总金额" min-width="130" align="right" />
<el-table-column label="用户等级" min-width="100" align="center">
<template slot-scope="scope">
<span :style="{ color: levelColor(scope.row.level) }">
{{ scope.row.levelName || '普通用户' }}
</span>
</template>
</el-table-column>
<el-table-column prop="money" label="余额" min-width="100" align="right" />
<el-table-column prop="coupon" label="优惠券" min-width="100" align="right" />
<el-table-column prop="selfBonus" label="个人奖金" min-width="100" align="right" />
<el-table-column prop="shareBonus" label="推广奖金" min-width="100" align="right" />
<el-table-column label="状态" min-width="80" align="center">
<template slot-scope="scope">
<el-tag :type="scope.row.status === 1 ? 'success' : 'danger'" size="mini">
{{ scope.row.statusStr || (scope.row.status === 1 ? '正常' : '禁用') }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="updatedAt" label="更新时间" min-width="160" show-overflow-tooltip />
<el-table-column label="操作" min-width="160" fixed="right" align="center">
<template slot-scope="scope">
<el-button type="text" size="small" @click="onEditPid(scope.row)">修改上级</el-button>
<el-button type="text" size="small" @click="onContractRenew(scope.row)">合同重签</el-button>
<el-button type="text" size="small" @click="onEdit(scope.row)">编辑</el-button>
</template>
</el-table-column>
</el-table>
<div class="block mt20">
<el-pagination
:page-sizes="[15, 30, 45, 60]"
:page-size="tableFrom.limit"
:current-page="tableFrom.page"
layout="total, sizes, prev, pager, next, jumper"
:total="tableData.total"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</el-card>
<!-- 写操作提示对话框外部页面默认不直接修改资金类字段 -->
<el-dialog title="提示" :visible.sync="writeTipVisible" width="380px" append-to-body>
<span>{{ writeTipText }}</span>
<span slot="footer">
<el-button type="primary" size="small" @click="writeTipVisible = false">知道了</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import { getExternalGrabUserList } from '@/api/integralExternal';
export default {
name: 'IntegralExternalGrabUser',
data() {
return {
listLoading: false,
tableData: { data: [], total: 0 },
tableFrom: {
uid: '',
mobile: '',
pid: '',
page: 1,
limit: 15,
},
writeTipVisible: false,
writeTipText: '',
};
},
mounted() {
this.getList();
},
methods: {
getList() {
this.listLoading = true;
const params = { ...this.tableFrom };
// 空字段不发送
Object.keys(params).forEach((k) => {
if (params[k] === '' || params[k] === null) delete params[k];
});
getExternalGrabUserList(params)
.then((res) => {
this.tableData.data = res.list || [];
this.tableData.total = res.total || 0;
})
.catch(() => {})
.finally(() => {
this.listLoading = false;
});
},
seachList() {
this.tableFrom.page = 1;
this.getList();
},
resetHandler() {
this.tableFrom = { uid: '', mobile: '', pid: '', page: 1, limit: 15 };
this.getList();
},
handleSizeChange(val) {
this.tableFrom.limit = val;
this.getList();
},
handleCurrentChange(val) {
this.tableFrom.page = val;
this.getList();
},
openContract(url) {
if (!url) return;
window.open(url, '_blank');
},
levelColor(level) {
switch (level) {
case 2:
return '#E6A23C';
case 3:
return '#67C23A';
default:
return '#409EFF';
}
},
onEditPid() {
this.writeTipText = '请在管理后台「用户管理」中修改上级;本页面不支持写操作。';
this.writeTipVisible = true;
},
onContractRenew() {
this.writeTipText = '请在管理后台「用户管理」中进行合同重签;本页面不支持写操作。';
this.writeTipVisible = true;
},
onEdit() {
this.writeTipText = '请在管理后台「用户管理」中编辑;本页面不支持写操作。';
this.writeTipVisible = true;
},
/**
* 简易 CSV 导出(仅当前页)
* 生产环境如需全量导出建议改为后端 /grab-user/list/export
*/
exportCsv() {
const rows = this.tableData.data || [];
if (rows.length === 0) {
this.$message.info('当前页没有数据可导出');
return;
}
const headers = [
'用户ID', '账号', '昵称', '昨日卖/今日买', '联系方式', '上级ID',
'最高可抢单数', '今日购买总金额', '今日卖出总金额', '用户等级',
'余额', '优惠券', '个人奖金', '推广奖金', '状态', '更新时间',
];
const lines = [headers.join(',')];
rows.forEach((r) => {
const fields = [
r.id,
r.username || r.mobile || '',
r.nickname || '',
`${r.prevSellCnt || 0}/${r.todayBuyCnt || 0}`,
r.mobile || '',
r.pid || '',
r.maxOrder || '',
r.todayBuyAmount || '0',
r.todaySellAmount || '0',
r.levelName || '普通用户',
r.money || '0',
r.coupon || '0',
r.selfBonus || '0',
r.shareBonus || '0',
r.statusStr || (r.status === 1 ? '正常' : '禁用'),
r.updatedAt || '',
].map((v) => `"${String(v).replace(/"/g, '""')}"`);
lines.push(fields.join(','));
});
const blob = new Blob(['' + lines.join('\n')], { type: 'text/csv;charset=utf-8;' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `今日抢单用户_${new Date().toISOString().slice(0, 10)}.csv`;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
},
},
};
</script>
<style scoped lang="scss">
.mt10 { margin-top: 10px; }
.mt20 { margin-top: 20px; }
.selWidth { width: 220px; }
.header-actions {
text-align: right;
margin-bottom: 8px;
}
.block { text-align: right; }
</style>

View File

@@ -0,0 +1,421 @@
<template>
<div class="divBox relative">
<!-- 条件区 -->
<el-card class="box-card">
<el-form
ref="searchForm"
:model="tableFrom"
inline
size="small"
label-width="120px"
>
<el-form-item label="团队长 ID">
<el-input
v-model.number="tableFrom.leaderId"
placeholder="留空=全部"
class="leaderIdWidth"
clearable
@keyup.enter.native="seachList"
/>
</el-form-item>
<el-form-item label="日期 D">
<el-date-picker
v-model="tableFrom.date"
type="date"
value-format="yyyy-MM-dd"
placeholder="缺省=昨天"
class="dateWidth"
:picker-options="pickerOptions"
/>
</el-form-item>
<el-form-item label="含禁用成员:">
<el-switch v-model="tableFrom.includeDisabled" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="seachList">查询</el-button>
<el-button icon="el-icon-refresh-left" @click="resetHandler">重置</el-button>
<el-button
icon="el-icon-download"
:disabled="!tableFrom.leaderId"
@click="exportExcel"
>导出 Excel</el-button>
</el-form-item>
</el-form>
<div v-if="!tableFrom.leaderId" class="hint">
Tips: 团队长 ID 留空时返回所有团队的日报导出 Excel 仅支持单团队
</div>
</el-card>
<!-- 跨团队总计仅在多团队模式下显示 -->
<el-card v-if="report && report.teams && report.teams.length > 1" class="box-card mt10">
<div class="report-header">
<span class="title">
全部团队总计 · {{ report.teamCount }} 个团队 · {{ report.totalMemberCount }} · {{ report.date }}
</span>
<span class="rate-info">
服务费率 {{ report.serviceRate }} · E 积分率 {{ report.eScoreRate }}
</span>
</div>
<el-row :gutter="16" class="summary-row">
<el-col :span="6">
<div class="summary-card">
<div class="summary-label">{{ report.previousDate }} 买单合计</div>
<div class="summary-value">{{ formatNum(report.grandSummary.prevBuy) }}</div>
</div>
</el-col>
<el-col :span="6">
<div class="summary-card">
<div class="summary-label">{{ report.date }} 卖单合计</div>
<div class="summary-value">{{ formatNum(report.grandSummary.todaySell) }}</div>
</div>
</el-col>
<el-col :span="6">
<div class="summary-card">
<div class="summary-label">{{ report.date }} 买单合计</div>
<div class="summary-value">{{ formatNum(report.grandSummary.todayBuy) }}</div>
</div>
</el-col>
<el-col :span="6">
<div class="summary-card">
<div class="summary-label">实际收付合计</div>
<div
class="summary-value"
:class="actualClass(report.grandSummary.actual)"
>{{ formatNum(report.grandSummary.actual) }}</div>
</div>
</el-col>
</el-row>
</el-card>
<!-- 各团队子报表 -->
<template v-if="report && report.teams && report.teams.length">
<el-card
v-for="team in report.teams"
:key="team.leaderId"
class="box-card mt10 team-card"
>
<div class="report-header">
<span class="title">
团队长 {{ team.leaderNickname || team.teamCode || '-' }}
· {{ team.memberCount }} · {{ team.date }}
</span>
<el-button
v-if="!tableFrom.leaderId"
size="mini"
type="text"
icon="el-icon-download"
@click="exportTeamExcel(team)"
>导出该团队</el-button>
</div>
<!-- 团队级 4 卡片摘要仅在单团队模式 / 想看每个团队也可以看保留显示 -->
<el-row v-if="report.teams.length === 1" :gutter="16" class="summary-row">
<el-col :span="6">
<div class="summary-card">
<div class="summary-label">{{ team.previousDate }} 买单合计</div>
<div class="summary-value">{{ formatNum(team.summary.prevBuy) }}</div>
</div>
</el-col>
<el-col :span="6">
<div class="summary-card">
<div class="summary-label">{{ team.date }} 卖单合计</div>
<div class="summary-value">{{ formatNum(team.summary.todaySell) }}</div>
</div>
</el-col>
<el-col :span="6">
<div class="summary-card">
<div class="summary-label">{{ team.date }} 买单合计</div>
<div class="summary-value">{{ formatNum(team.summary.todayBuy) }}</div>
</div>
</el-col>
<el-col :span="6">
<div class="summary-card">
<div class="summary-label">实际收付合计</div>
<div
class="summary-value"
:class="actualClass(team.summary.actual)"
>{{ formatNum(team.summary.actual) }}</div>
</div>
</el-col>
</el-row>
<el-table
:data="team.rows"
size="mini"
class="table"
border
highlight-current-row
:header-cell-style="headerCellStyle"
:show-summary="true"
:summary-method="(meta) => getTeamSummaries(meta, team)"
>
<el-table-column label="昵称" prop="nickname" min-width="120">
<template slot-scope="scope">
<span>{{ scope.row.nickname || '-' }}</span>
<el-tag v-if="scope.row.status === 0" size="mini" type="info" style="margin-left: 4px">已禁用</el-tag>
</template>
</el-table-column>
<el-table-column :label="prevBuyLabel(team)" prop="prevBuy" min-width="110" align="right">
<template slot-scope="scope">{{ formatNum(scope.row.prevBuy) }}</template>
</el-table-column>
<el-table-column :label="todaySellLabel(team)" prop="todaySell" min-width="110" align="right">
<template slot-scope="scope">{{ formatNum(scope.row.todaySell) }}</template>
</el-table-column>
<el-table-column :label="todayBuyLabel(team)" prop="todayBuy" min-width="110" align="right">
<template slot-scope="scope">{{ formatNum(scope.row.todayBuy) }}</template>
</el-table-column>
<el-table-column :label="serviceFeeLabel(team)" prop="serviceFee" min-width="120" align="right">
<template slot-scope="scope">{{ formatNum(scope.row.serviceFee) }}</template>
</el-table-column>
<el-table-column label="E积分" prop="eScore" min-width="90" align="right">
<template slot-scope="scope">{{ formatNum(scope.row.eScore) }}</template>
</el-table-column>
<el-table-column label="实际收付" prop="actual" min-width="110" align="right">
<template slot-scope="scope">
<span :class="actualClass(scope.row.actual)">{{ formatNum(scope.row.actual) }}</span>
</template>
</el-table-column>
<el-table-column label="团队" min-width="120" align="center">
<template>
<span>{{ team.leaderNickname || team.teamCode || '-' }}</span>
</template>
</el-table-column>
<el-table-column label="备注" min-width="180">
<template slot-scope="scope">
<el-input
v-model="scope.row.remark"
size="mini"
placeholder="可填写仅当前会话有效"
clearable
/>
</template>
</el-table-column>
</el-table>
<div v-if="!team.rows || team.rows.length === 0" class="empty-tip">该团队当日无成员数据</div>
</el-card>
</template>
<el-card v-else-if="report" class="box-card mt10">
<div class="empty-tip">未查询到任何团队数据。</div>
</el-card>
</div>
</template>
<script>
import { saveAs } from 'file-saver';
import {
getExternalTeamDailyReport,
exportExternalTeamDailyReport,
} from '@/api/integralExternal';
export default {
name: 'IntegralExternalTeamReport',
data() {
return {
listLoading: false,
report: null,
tableFrom: {
leaderId: '',
date: this.yesterdayStr(),
includeDisabled: false,
},
pickerOptions: {
disabledDate(t) {
return t.getTime() > Date.now();
},
},
};
},
mounted() {
// 进入页面默认拉取所有团队(不传 leaderId
this.seachList();
},
methods: {
yesterdayStr() {
const d = new Date();
d.setDate(d.getDate() - 1);
const m = String(d.getMonth() + 1).padStart(2, '0');
const day = String(d.getDate()).padStart(2, '0');
return `${d.getFullYear()}-${m}-${day}`;
},
headerCellStyle() {
return {
background: '#C6EFCE',
color: '#000',
fontWeight: 'bold',
textAlign: 'center',
};
},
seachList() {
this.listLoading = true;
const params = {
date: this.tableFrom.date,
includeDisabled: this.tableFrom.includeDisabled,
};
if (this.tableFrom.leaderId) {
params.leaderId = this.tableFrom.leaderId;
}
getExternalTeamDailyReport(params)
.then((res) => {
this.report = res || null;
})
.catch(() => {
this.report = null;
})
.finally(() => {
this.listLoading = false;
});
},
resetHandler() {
this.tableFrom = {
leaderId: '',
date: this.yesterdayStr(),
includeDisabled: false,
};
this.seachList();
},
formatNum(v) {
if (v === null || v === undefined || v === '') return '0';
const n = Number(v);
if (Number.isNaN(n)) return v;
const sign = n < 0 ? '-' : '';
const abs = Math.abs(n);
const fixed = abs.toFixed(2);
const [intPart, decPart] = fixed.split('.');
const withSep = intPart.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
return `${sign}${withSep}.${decPart}`;
},
actualClass(v) {
const n = Number(v);
if (Number.isNaN(n)) return '';
if (n < 0) return 'text-danger';
if (n === 0) return 'text-muted';
return '';
},
prevBuyLabel(team) {
return team && team.previousDate ? `${team.previousDate.slice(5)} 买单` : 'D-1 买单';
},
todaySellLabel(team) {
return team && team.date ? `${team.date.slice(5)} 卖单` : 'D 卖单';
},
todayBuyLabel(team) {
return team && team.date ? `${team.date.slice(5)} 买单` : 'D 买单';
},
serviceFeeLabel(team) {
return team && team.serviceRate
? `服务费*${team.serviceRate}`
: `服务费*${this.report ? this.report.serviceRate : '0.02'}`;
},
/** 团队子表的小计行(直接取 team.summary不在前端逐行累加 */
getTeamSummaries({ columns }, team) {
const result = new Array(columns.length).fill('');
if (!team || !team.summary) return result;
const s = team.summary;
const map = {
nickname: '小计',
prevBuy: s.prevBuy,
todaySell: s.todaySell,
todayBuy: s.todayBuy,
serviceFee:s.serviceFee,
eScore: s.eScore,
actual: s.actual,
};
columns.forEach((col, idx) => {
const v = map[col.property];
if (v !== undefined && v !== null) {
result[idx] = col.property === 'nickname' ? v : this.formatNum(v);
}
});
return result;
},
/** 工具栏里的"导出 Excel"按钮:使用当前 tableFrom 的 leaderId */
exportExcel() {
if (!this.tableFrom.leaderId) {
this.$message.warning('Excel 导出需要指定团队长 ID');
return;
}
this.doExport(this.tableFrom.leaderId, '');
},
/** 多团队卡片右上角的"导出该团队"按钮 */
exportTeamExcel(team) {
if (!team || !team.leaderId) return;
this.doExport(team.leaderId, team.leaderNickname || team.teamCode || '');
},
doExport(leaderId, nickname) {
this.listLoading = true;
exportExternalTeamDailyReport({
leaderId,
date: this.tableFrom.date,
includeDisabled: this.tableFrom.includeDisabled,
})
.then((blob) => {
const file = blob instanceof Blob ? blob : new Blob([blob], {
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
});
const date = this.tableFrom.date || this.yesterdayStr();
const name = nickname || `leader${leaderId}`;
saveAs(file, `团队${name}_${date}.xlsx`);
})
.catch(() => {})
.finally(() => {
this.listLoading = false;
});
},
},
};
</script>
<style scoped lang="scss">
.mt10 { margin-top: 10px; }
.selWidth { width: 240px; }
.leaderIdWidth { width: 100px; }
.dateWidth { width: 160px; }
.hint {
margin-top: 4px;
color: #909399;
font-size: 12px;
}
.team-card {
margin-top: 10px;
}
.report-header {
display: flex;
justify-content: space-between;
align-items: baseline;
margin-bottom: 12px;
.title {
font-size: 16px;
font-weight: bold;
}
.rate-info {
color: #909399;
font-size: 12px;
}
}
.summary-row {
margin-bottom: 4px;
}
.summary-card {
background: #f5f7fa;
border: 1px solid #ebeef5;
border-radius: 4px;
padding: 10px 14px;
}
.summary-label {
color: #909399;
font-size: 12px;
margin-bottom: 6px;
}
.summary-value {
font-size: 22px;
font-weight: bold;
color: #303133;
}
.text-danger { color: #C00000; font-weight: bold; }
.text-muted { color: #909399; }
.empty-tip {
text-align: center;
color: #909399;
padding: 30px 0;
}
</style>

View File

@@ -45,7 +45,7 @@
<div class="container mb10">
<el-form inline size="small" :model="searchForm" label-width="96px">
<el-row>
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
<el-col :xs="24" :sm="12" :md="8" :lg="5" :xl="5">
<el-form-item label="用户ID">
<el-input
v-model="searchForm.uidStr"
@@ -56,7 +56,7 @@
/>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
<el-col :xs="24" :sm="12" :md="8" :lg="5" :xl="5">
<el-form-item label="用户名称:">
<el-input
v-model="searchForm.nickName"
@@ -67,7 +67,7 @@
/>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
<el-col :xs="24" :sm="12" :md="8" :lg="5" :xl="5">
<el-form-item label="手机号:">
<el-input
v-model="searchForm.phone"
@@ -78,7 +78,7 @@
/>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
<el-col :xs="24" :sm="12" :md="10" :lg="8" :xl="8">
<el-form-item label="时间选择:">
<el-date-picker
v-model="timeVal"
@@ -90,11 +90,12 @@
range-separator=""
start-placeholder="开始日期"
end-placeholder="结束日期"
class="date-range-width"
@change="onchangeTime"
/>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
<el-col :xs="24" :sm="12" :md="6" :lg="4" :xl="4">
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="handleSearch">搜索</el-button>
<el-button @click="handleReset">重置</el-button>
@@ -119,7 +120,6 @@
<span>{{ scope.row.nickName || '-' }}</span>
</template>
</el-table-column>
<el-table-column prop="title" label="标题" min-width="150" show-overflow-tooltip />
<el-table-column label="积分变动" min-width="100">
<template slot-scope="scope">
<el-tag :type="scope.row.type === 1 ? 'success' : 'danger'" size="small">
@@ -356,7 +356,10 @@ export default {
text-align: right;
}
.filter-input {
width: 180px;
width: 150px;
}
.date-range-width {
width: 350px;
}
.overview-card--all .hint-text {
display: block;

View File

@@ -5,7 +5,7 @@
<div class="container">
<el-form inline size="small" :model="userFrom" label-width="90px">
<el-row>
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
<el-col :xs="24" :sm="12" :md="6" :lg="5" :xl="5">
<el-form-item label="用户搜索:">
<el-input
v-model="userFrom.keywords"
@@ -16,7 +16,18 @@
/>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
<el-col :xs="24" :sm="12" :md="6" :lg="5" :xl="5">
<el-form-item label="用户ID">
<el-input
v-model="userFrom.uidStr"
placeholder="可选,留空查全部"
clearable
class="selWidth"
@keyup.enter.native="seachList"
/>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="10" :lg="8" :xl="8">
<el-form-item label="时间选择:">
<el-date-picker
v-model="timeVal"
@@ -27,11 +38,12 @@
range-separator=""
start-placeholder="开始日期"
end-placeholder="结束日期"
class="date-range-width"
@change="onchangeTime"
/>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
<el-col :xs="24" :sm="12" :md="6" :lg="5" :xl="5">
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="small" @click="seachList">搜索</el-button>
<el-button size="small" @click="handleReset">重置</el-button>
@@ -114,6 +126,7 @@ export default {
},
userFrom: {
keywords: '',
uidStr: '',
dateLimit: '',
page: 1,
limit: 15,
@@ -128,6 +141,14 @@ export default {
getList() {
this.listLoading = true;
const params = { ...this.userFrom };
delete params.uidStr;
const uidParsed =
this.userFrom.uidStr === '' || this.userFrom.uidStr == null
? null
: parseInt(String(this.userFrom.uidStr).trim(), 10);
if (uidParsed != null && !Number.isNaN(uidParsed) && uidParsed > 0) {
params.uid = uidParsed;
}
if (!params.keywords) delete params.keywords;
if (!params.dateLimit) delete params.dateLimit;
@@ -146,7 +167,7 @@ export default {
this.getList();
},
handleReset() {
this.userFrom = { keywords: '', dateLimit: '', page: 1, limit: 15 };
this.userFrom = { keywords: '', uidStr: '', dateLimit: '', page: 1, limit: 15 };
this.timeVal = [];
this.getList();
},
@@ -201,6 +222,9 @@ export default {
text-align: right;
}
.selWidth {
width: 200px;
width: 160px;
}
.date-range-width {
width: 350px;
}
</style>

View File

@@ -0,0 +1,747 @@
<template>
<div class="divBox relative">
<!-- 顶部搜索区 -->
<el-card class="box-card">
<el-form size="small" inline label-width="100px">
<el-form-item label="订单状态:">
<el-radio-group v-model="uiStatus" type="button" size="mini" @change="onStatusChange">
<el-radio-button label="all">全部</el-radio-button>
<el-radio-button label="unPaid">待付款</el-radio-button>
<el-radio-button label="paid">已支付</el-radio-button>
<el-radio-button label="complete">交易完成</el-radio-button>
<el-radio-button label="cancel">已取消</el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item label="时间字段:">
<el-select
v-model="timeField"
placeholder="选择时间维度"
style="width: 140px"
size="mini"
@change="seachList"
>
<el-option label="抢购时间" value="buyTime" />
<el-option label="支付时间" value="payTime" />
<el-option label="完成时间" value="confirmTime" />
<el-option label="创建时间" value="createdAt" />
</el-select>
</el-form-item>
<el-form-item label="日期范围:">
<el-date-picker
v-model="timeVal"
value-format="yyyy-MM-dd"
format="yyyy-MM-dd"
size="mini"
type="daterange"
placeholder="自定义时间"
style="width: 220px"
@change="onTimeChange"
/>
</el-form-item>
<el-form-item label="订单号:">
<el-input
v-model="tableFrom.orderSn"
placeholder="请输入订单号"
clearable
class="selWidth"
size="mini"
@keyup.enter.native="seachList"
/>
</el-form-item>
<el-form-item label="买家ID">
<el-input
v-model.number="tableFrom.buyerId"
placeholder="买家用户ID"
clearable
class="selWidth"
size="mini"
/>
</el-form-item>
<el-form-item label="卖家ID">
<el-input
v-model.number="tableFrom.sellerId"
placeholder="卖家ID0=平台)"
clearable
class="selWidth"
size="mini"
/>
</el-form-item>
<el-form-item label="是否转拍:">
<el-select
v-model="tableFrom.isResell"
placeholder="全部"
clearable
style="width: 100px"
size="mini"
@change="seachList"
>
<el-option :value="1" label="是" />
<el-option :value="0" label="否" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="seachList">查询</el-button>
<el-button icon="el-icon-refresh-left" size="mini" @click="resetHandler">重置</el-button>
</el-form-item>
</el-form>
</el-card>
<!-- 操作按钮区 -->
<el-card class="box-card mt10">
<div class="header-actions">
<el-popover
placement="bottom-end"
width="300"
trigger="click"
v-model="columnPopoverVisible"
>
<div class="column-setting">
<div class="column-setting-actions">
<el-button size="mini" type="text" @click="selectAllColumns">全选</el-button>
<el-button size="mini" type="text" @click="invertColumns">反选</el-button>
<el-button size="mini" type="text" @click="resetColumns">恢复默认</el-button>
</div>
<el-checkbox-group v-model="visibleColumns" class="column-checkbox-group">
<el-checkbox
v-for="col in columnsConfig"
:key="col.prop"
:label="col.prop"
:disabled="col.fixed"
>{{ col.label }}</el-checkbox>
</el-checkbox-group>
</div>
<el-button slot="reference" size="mini" icon="el-icon-setting">列设置</el-button>
</el-popover>
<el-button size="mini" icon="el-icon-refresh" @click="getList" />
</div>
<el-table
v-loading="listLoading"
:data="tableData.data"
size="mini"
class="table"
highlight-current-row
:header-cell-style="{ fontWeight: 'bold' }"
>
<template v-for="col in columnsConfig">
<el-table-column
v-if="col.prop !== 'actions' && visibleColumns.includes(col.prop)"
:key="col.prop"
:label="col.label"
:min-width="col.width"
:show-overflow-tooltip="col.tooltip"
:align="col.align || 'left'"
>
<template slot-scope="scope">
<!-- 商品图片单元格使用 el-image其他文本走 formatCell -->
<el-image
v-if="col.prop === 'merchandiseImage' && scope.row.merchandiseImage"
:src="scope.row.merchandiseImage"
:preview-src-list="[scope.row.merchandiseImage]"
style="width:48px;height:48px;border-radius:4px"
fit="cover"
/>
<span v-else-if="col.prop === 'merchandiseImage'">-</span>
<span v-else v-html="formatCell(col.prop, scope.row)" />
</template>
</el-table-column>
</template>
<el-table-column label="操作" min-width="120" fixed="right" align="center">
<template slot-scope="scope">
<el-button type="text" size="small" @click="openDetail(scope.row.id)">详情</el-button>
</template>
</el-table-column>
</el-table>
<div class="block mt20">
<el-pagination
:page-sizes="[15, 30, 45, 60]"
:page-size="tableFrom.limit"
:current-page="tableFrom.page"
layout="total, sizes, prev, pager, next, jumper"
:total="tableData.total"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</el-card>
<!-- 详情抽屉 -->
<el-drawer
:visible.sync="drawerVisible"
direction="rtl"
size="680px"
:destroy-on-close="true"
:with-header="false"
append-to-body
custom-class="wa-order-drawer"
@close="onDrawerClose"
>
<div v-loading="detailLoading" class="drawer-body">
<!-- 顶部摘要订单号 + 状态徽标 + 关闭 -->
<div class="drawer-header">
<div class="header-left">
<div class="order-sn-row">
<span class="order-sn-label">订单号</span>
<span class="order-sn">{{ detail ? detail.orderSn : '-' }}</span>
<el-button
v-if="detail"
size="mini"
type="text"
icon="el-icon-document-copy"
@click="copyOrderSn"
>复制</el-button>
</div>
<div class="tag-row">
<el-tag v-if="detail" :type="statusTagType(detail)" size="small">{{ statusLabel(detail) }}</el-tag>
<el-tag v-if="detail && detail.isResell === 1" type="warning" size="small" effect="plain">转拍</el-tag>
<el-tag v-if="detail && detail.isCancel === 1" type="danger" size="small" effect="plain">已取消</el-tag>
</div>
</div>
<el-button
class="close-btn"
icon="el-icon-close"
type="text"
@click="drawerVisible = false"
/>
</div>
<div v-if="detail" class="drawer-content">
<!-- 时间链路 -->
<el-card shadow="never" class="block-card">
<div slot="header" class="block-title">订单时间链路</div>
<el-steps :active="stepActive(detail)" finish-status="success" align-center>
<el-step title="抢购下单" :description="detail.buyTime || '-'" />
<el-step
v-if="detail.isResell === 1"
title="转拍生成"
:description="detail.createdAt || '-'"
/>
<el-step title="支付" :description="detail.payTime || '-'" />
<el-step title="完成" :description="detail.confirmTime || '-'" />
</el-steps>
</el-card>
<!-- 订单基础 -->
<el-card shadow="never" class="block-card">
<div slot="header" class="block-title">订单基础</div>
<el-descriptions :column="2" :colon="false" size="small" class="info-desc">
<el-descriptions-item label="订单ID">{{ detail.id }}</el-descriptions-item>
<el-descriptions-item label="订单金额">
<span class="price">{{ detail.totalMoney }}</span>
</el-descriptions-item>
<el-descriptions-item label="商品ID">{{ detail.merchandiseId || '-' }}</el-descriptions-item>
<el-descriptions-item label="商品名称">{{ detail.merchandiseTitle || '-' }}</el-descriptions-item>
<el-descriptions-item label="是否显示">{{ detail.isShow === 1 ? '显示' : '隐藏' }}</el-descriptions-item>
<el-descriptions-item label="原订单ID">{{ detail.oldId || '-' }}</el-descriptions-item>
<el-descriptions-item label="商品图片" :span="2">
<el-image
v-if="detail.merchandiseImage"
:src="detail.merchandiseImage"
:preview-src-list="[detail.merchandiseImage]"
style="width:80px;height:80px;border-radius:4px"
fit="cover"
/>
<span v-else>-</span>
</el-descriptions-item>
</el-descriptions>
</el-card>
<!-- 买家 -->
<el-card shadow="never" class="block-card">
<div slot="header" class="block-title">买家信息</div>
<el-descriptions :column="2" :colon="false" size="small" class="info-desc">
<el-descriptions-item label="买家ID">{{ detail.buyerId || '-' }}</el-descriptions-item>
<el-descriptions-item label="买家昵称">{{ detail.buyerName || '-' }}</el-descriptions-item>
<el-descriptions-item label="收货人">{{ detail.consignee || '-' }}</el-descriptions-item>
<el-descriptions-item label="收货电话">{{ detail.phone || '-' }}</el-descriptions-item>
<el-descriptions-item label="收货地区" :span="2">{{ joinArea(detail) }}</el-descriptions-item>
<el-descriptions-item label="详细地址" :span="2">{{ detail.address || '-' }}</el-descriptions-item>
</el-descriptions>
</el-card>
<!-- 卖家 -->
<el-card shadow="never" class="block-card">
<div slot="header" class="block-title">卖家信息</div>
<el-descriptions :column="2" :colon="false" size="small" class="info-desc">
<el-descriptions-item label="卖家ID">
{{ detail.sellerId === 0 ? '0平台' : detail.sellerId }}
</el-descriptions-item>
<el-descriptions-item label="卖家昵称">
{{ detail.sellerId === 0 ? '平台' : (detail.sellerName || '-') }}
</el-descriptions-item>
</el-descriptions>
</el-card>
<!-- 支付与日志 -->
<el-card shadow="never" class="block-card">
<div slot="header" class="block-title">支付与日志</div>
<el-descriptions :column="2" :colon="false" size="small" class="info-desc">
<el-descriptions-item label="抢购时间">{{ detail.buyTime || '-' }}</el-descriptions-item>
<el-descriptions-item label="支付时间">{{ detail.payTime || '-' }}</el-descriptions-item>
<el-descriptions-item label="完成时间">{{ detail.confirmTime || '-' }}</el-descriptions-item>
<el-descriptions-item label="创建时间">{{ detail.createdAt || '-' }}</el-descriptions-item>
<el-descriptions-item label="下单IP">{{ detail.buyIp || '-' }}</el-descriptions-item>
<el-descriptions-item v-if="detail.isCancel === 1" label="取消IP">
{{ detail.cancelIp || '-' }}
</el-descriptions-item>
<el-descriptions-item label="支付凭证" :span="2">
<el-image
v-if="detail.payImg"
:src="detail.payImg"
:preview-src-list="[detail.payImg]"
style="width:80px;height:80px;border-radius:4px"
fit="cover"
/>
<span v-else>-</span>
</el-descriptions-item>
</el-descriptions>
</el-card>
</div>
<div class="drawer-footer">
<el-button @click="drawerVisible = false"> </el-button>
</div>
</div>
</el-drawer>
</div>
</template>
<script>
import {
getExternalWaOrderList,
getExternalWaOrderInfo,
} from '@/api/integralExternal';
const STORAGE_KEY = 'waOrderColumns:external';
const COLUMN_DEFS = [
{ prop: 'id', label: '订单ID', width: 80, defaultVisible: true, fixed: true, tooltip: false, align: 'left' },
{ prop: 'orderSn', label: '订单号', width: 210, defaultVisible: true, fixed: true, tooltip: true },
{ prop: 'merchandiseId', label: '商品ID', width: 90, defaultVisible: true, align: 'left' },
{ prop: 'merchandiseTitle', label: '商品名称', width: 200, defaultVisible: true, tooltip: true },
{ prop: 'merchandiseImage', label: '商品图片', width: 90, defaultVisible: false, align: 'center' },
{ prop: 'totalMoney', label: '订单金额', width: 110, defaultVisible: true, align: 'right' },
{ prop: 'statusStr', label: '订单状态', width: 110, defaultVisible: true, align: 'center' },
{ prop: 'isResell', label: '是否转拍', width: 90, defaultVisible: false, align: 'center' },
{ prop: 'buyerName', label: '买家昵称', width: 120, defaultVisible: true, tooltip: true },
{ prop: 'buyerId', label: '买家ID', width: 90, defaultVisible: false },
{ prop: 'sellerName', label: '卖家昵称', width: 120, defaultVisible: true, tooltip: true },
{ prop: 'sellerId', label: '卖家ID', width: 90, defaultVisible: false },
{ prop: 'consignee', label: '收货人', width: 100, defaultVisible: false },
{ prop: 'phone', label: '收货电话', width: 130, defaultVisible: false },
{ prop: 'areaText', label: '收货地区', width: 180, defaultVisible: false, tooltip: true },
{ prop: 'address', label: '详细地址', width: 220, defaultVisible: false, tooltip: true },
{ prop: 'buyTime', label: '抢购时间', width: 160, defaultVisible: true },
{ prop: 'createdAt', label: '转拍/创建时间', width: 160, defaultVisible: false },
{ prop: 'payTime', label: '支付时间', width: 160, defaultVisible: true },
{ prop: 'confirmTime', label: '完成时间', width: 160, defaultVisible: true },
{ prop: 'updatedAt', label: '更新时间', width: 160, defaultVisible: false },
{ prop: 'buyIp', label: '下单IP', width: 130, defaultVisible: false },
{ prop: 'cancelIp', label: '取消IP', width: 130, defaultVisible: false },
{ prop: 'isShow', label: '显示', width: 80, defaultVisible: false, align: 'center' },
];
export default {
name: 'IntegralExternalWaOrder',
data() {
return {
listLoading: false,
tableData: { data: [], total: 0 },
tableFrom: {
orderSn: '',
buyerId: '',
sellerId: '',
status: null,
isCancel: null,
isResell: null,
buyTimeStart: '',
buyTimeEnd: '',
confirmTimeStart: '',
confirmTimeEnd: '',
page: 1,
limit: 15,
},
uiStatus: 'all',
timeField: 'buyTime',
timeVal: [],
columnsConfig: COLUMN_DEFS.concat([{ prop: 'actions', label: '操作', fixed: true }]),
visibleColumns: this.loadColumns(),
columnPopoverVisible: false,
drawerVisible: false,
detail: null,
detailLoading: false,
};
},
mounted() {
// 支持 ?detailId=xxx 直接打开抽屉
if (this.$route && this.$route.query && this.$route.query.detailId) {
this.openDetail(this.$route.query.detailId);
}
this.getList();
},
methods: {
loadColumns() {
try {
const raw = localStorage.getItem(STORAGE_KEY);
if (raw) {
const arr = JSON.parse(raw);
if (Array.isArray(arr) && arr.length) {
const validProps = COLUMN_DEFS.map((c) => c.prop);
// 1) 与最新字段定义做交集2) 锁定列必须存在3) 新增的 defaultVisible 列自动并入
const next = arr.filter((p) => validProps.includes(p));
COLUMN_DEFS.forEach((c) => {
if ((c.fixed || c.defaultVisible) && !next.includes(c.prop)) {
next.push(c.prop);
}
});
return next;
}
}
} catch (e) { /* ignore */ }
return COLUMN_DEFS.filter((c) => c.defaultVisible || c.fixed).map((c) => c.prop);
},
persistColumns() {
try {
localStorage.setItem(STORAGE_KEY, JSON.stringify(this.visibleColumns));
} catch (e) { /* ignore */ }
},
selectAllColumns() {
this.visibleColumns = COLUMN_DEFS.map((c) => c.prop);
this.persistColumns();
},
invertColumns() {
const all = COLUMN_DEFS.map((c) => c.prop);
const next = all.filter((p) => !this.visibleColumns.includes(p));
// 锁定列必须保留
COLUMN_DEFS.filter((c) => c.fixed).forEach((c) => {
if (!next.includes(c.prop)) next.push(c.prop);
});
this.visibleColumns = next;
this.persistColumns();
},
resetColumns() {
this.visibleColumns = COLUMN_DEFS.filter((c) => c.defaultVisible || c.fixed).map((c) => c.prop);
this.persistColumns();
},
onStatusChange() {
this.applyUiStatus();
this.seachList();
},
applyUiStatus() {
// UI 标签 → status / isCancel 组合
switch (this.uiStatus) {
case 'unPaid':
this.tableFrom.status = 0;
this.tableFrom.isCancel = 0;
break;
case 'paid':
this.tableFrom.status = 1;
this.tableFrom.isCancel = 0;
break;
case 'complete':
this.tableFrom.status = 2;
this.tableFrom.isCancel = 0;
break;
case 'cancel':
this.tableFrom.status = null;
this.tableFrom.isCancel = 1;
break;
default:
this.tableFrom.status = null;
this.tableFrom.isCancel = null;
}
},
onTimeChange(val) {
// 清掉所有时间字段
this.tableFrom.buyTimeStart = '';
this.tableFrom.buyTimeEnd = '';
this.tableFrom.confirmTimeStart = '';
this.tableFrom.confirmTimeEnd = '';
if (val && val.length === 2) {
const startKey = `${this.timeField}Start`;
const endKey = `${this.timeField}End`;
// WaOrderSearchRequest 仅支持 buyTime / confirmTime其余维度回退到 buyTime
if (startKey in this.tableFrom) {
this.tableFrom[startKey] = `${val[0]} 00:00:00`;
this.tableFrom[endKey] = `${val[1]} 23:59:59`;
} else {
this.tableFrom.buyTimeStart = `${val[0]} 00:00:00`;
this.tableFrom.buyTimeEnd = `${val[1]} 23:59:59`;
}
}
this.seachList();
},
seachList() {
this.tableFrom.page = 1;
this.getList();
},
resetHandler() {
this.tableFrom = {
orderSn: '', buyerId: '', sellerId: '',
status: null, isCancel: null, isResell: null,
buyTimeStart: '', buyTimeEnd: '', confirmTimeStart: '', confirmTimeEnd: '',
page: 1, limit: 15,
};
this.uiStatus = 'all';
this.timeField = 'buyTime';
this.timeVal = [];
this.getList();
},
getList() {
this.listLoading = true;
const params = { ...this.tableFrom };
// null/空字段不发
Object.keys(params).forEach((k) => {
if (params[k] === '' || params[k] === null) delete params[k];
});
getExternalWaOrderList(params)
.then((res) => {
this.tableData.data = res.list || [];
this.tableData.total = res.total || 0;
})
.catch(() => {})
.finally(() => {
this.listLoading = false;
});
},
handleSizeChange(val) {
this.tableFrom.limit = val;
this.getList();
},
handleCurrentChange(val) {
this.tableFrom.page = val;
this.getList();
},
formatCell(prop, row) {
if (!row) return '-';
switch (prop) {
case 'totalMoney':
return row.totalMoney != null ? `${row.totalMoney}` : '-';
case 'statusStr': {
const status = this.statusLabel(row);
const type = this.statusTagType(row);
return `<span class="el-tag el-tag--${type} el-tag--mini">${status}</span>`;
}
case 'isResell':
return row.isResell === 1
? '<span style="color:#E6A23C">是</span>'
: '否';
case 'sellerId':
return row.sellerId === 0 ? '0平台' : row.sellerId;
case 'sellerName':
return row.sellerId === 0 ? '平台' : (row.sellerName || '-');
case 'areaText':
return this.joinArea(row);
case 'isShow':
return row.isShow === 1 ? '是' : '否';
case 'merchandiseTitle':
return row.merchandiseTitle || row.productName || '-';
default: {
const v = row[prop];
return v == null || v === '' ? '-' : v;
}
}
},
statusLabel(row) {
if (!row) return '-';
if (row.isCancel === 1) return '已取消';
if (row.isResell === 1 && row.status === 0) return '转拍中';
switch (row.status) {
case 0: return '待付款';
case 1: return '已支付';
case 2: return '交易完成';
default: return '-';
}
},
statusTagType(row) {
if (!row) return 'info';
if (row.isCancel === 1) return 'info';
switch (row.status) {
case 0: return 'warning';
case 1: return 'primary';
case 2: return 'success';
default: return 'info';
}
},
stepActive(row) {
if (!row) return 0;
if (row.confirmTime) return row.isResell === 1 ? 4 : 3;
if (row.payTime) return row.isResell === 1 ? 3 : 2;
if (row.isResell === 1 && row.createdAt) return 2;
if (row.buyTime) return 1;
return 0;
},
joinArea(row) {
if (!row) return '-';
const parts = [row.province, row.city, row.area].filter(Boolean);
return parts.length ? parts.join(' / ') : '-';
},
openDetail(id) {
if (!id) return;
this.drawerVisible = true;
this.detailLoading = true;
this.detail = null;
getExternalWaOrderInfo(id)
.then((res) => {
this.detail = res || null;
})
.catch(() => {
this.$message.error('订单详情加载失败');
this.drawerVisible = false;
})
.finally(() => {
this.detailLoading = false;
});
},
onDrawerClose() {
this.detail = null;
// 清掉 URL 上的 detailId
if (this.$route && this.$route.query && this.$route.query.detailId) {
const q = { ...this.$route.query };
delete q.detailId;
this.$router.replace({ path: this.$route.path, query: q });
}
},
copyOrderSn() {
if (!this.detail || !this.detail.orderSn) return;
const ta = document.createElement('textarea');
ta.value = this.detail.orderSn;
document.body.appendChild(ta);
ta.select();
try { document.execCommand('copy'); this.$message.success('已复制订单号'); }
catch (e) { this.$message.error('复制失败'); }
document.body.removeChild(ta);
},
},
watch: {
visibleColumns: {
deep: true,
handler() { this.persistColumns(); },
},
},
};
</script>
<style scoped lang="scss">
.mt10 { margin-top: 10px; }
.mt20 { margin-top: 20px; }
.selWidth { width: 180px; }
.header-actions {
text-align: right;
margin-bottom: 8px;
}
.column-setting {
.column-setting-actions {
margin-bottom: 8px;
border-bottom: 1px dashed #ebeef5;
padding-bottom: 4px;
}
}
.column-checkbox-group {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 6px 0;
}
.block { text-align: right; }
/* ===== 抽屉详情样式 ===== */
.drawer-body {
display: flex;
flex-direction: column;
height: 100%;
}
.drawer-header {
flex: 0 0 auto;
display: flex;
justify-content: space-between;
align-items: flex-start;
padding: 16px 20px;
background: #f5f7fa;
border-bottom: 1px solid #ebeef5;
.header-left { flex: 1; min-width: 0; }
.order-sn-row {
display: flex;
align-items: center;
gap: 8px;
.order-sn-label {
color: #909399;
font-size: 12px;
}
.order-sn {
font-size: 16px;
font-weight: 600;
color: #303133;
word-break: break-all;
}
}
.tag-row {
margin-top: 8px;
display: flex;
gap: 6px;
flex-wrap: wrap;
}
.close-btn {
font-size: 18px;
color: #909399;
margin-left: 12px;
}
}
.drawer-content {
flex: 1 1 auto;
overflow-y: auto;
padding: 12px 16px;
}
.drawer-footer {
flex: 0 0 auto;
text-align: right;
padding: 12px 20px;
border-top: 1px solid #ebeef5;
background: #fafafa;
}
.block-card {
margin-bottom: 12px;
border: 1px solid #ebeef5;
::v-deep .el-card__header {
padding: 10px 14px;
background: #fafbfc;
}
::v-deep .el-card__body {
padding: 12px 14px;
}
}
.block-title {
font-size: 14px;
font-weight: 600;
color: #303133;
position: relative;
padding-left: 8px;
&::before {
content: '';
position: absolute;
left: 0; top: 3px;
width: 3px; height: 14px;
background: #409EFF;
border-radius: 2px;
}
}
.info-desc {
::v-deep .el-descriptions__label {
color: #909399;
font-weight: normal;
width: 90px;
}
::v-deep .el-descriptions__content {
color: #303133;
}
}
.price {
color: #f56c6c;
font-weight: 600;
}
::v-deep .wa-order-drawer .el-drawer__body {
padding: 0;
overflow: hidden;
}
</style>

View File

@@ -3,20 +3,35 @@ package com.zbkj.admin.controller;
import cn.hutool.core.collection.CollUtil;
import com.zbkj.common.page.CommonPage;
import com.zbkj.common.request.*;
import com.zbkj.common.response.ExternalGrabUserResponse;
import com.zbkj.common.response.StoreOrderDetailResponse;
import com.zbkj.common.response.TeamDailyMultiReportResponse;
import com.zbkj.common.response.TeamDailyReportResponse;
import com.zbkj.common.response.UserIntegralRecordResponse;
import com.zbkj.common.response.UserResponse;
import com.zbkj.common.response.WaOrderResponse;
import com.zbkj.common.result.CommonResult;
import com.zbkj.service.service.ExternalGrabUserService;
import com.zbkj.service.service.StoreOrderService;
import com.zbkj.service.service.TeamReportExternalService;
import com.zbkj.service.service.UserIntegralRecordService;
import com.zbkj.service.service.UserService;
import com.zbkj.service.service.WaOrderAdminService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
/**
* 积分模块外部免认证接口 Controller
* 供管理后台外部页面(/integral-external/*)调用,跳过登录验证。
@@ -40,6 +55,15 @@ public class ExternalIntegralController {
@Autowired
private UserService userService;
@Autowired
private WaOrderAdminService waOrderAdminService;
@Autowired
private TeamReportExternalService teamReportExternalService;
@Autowired
private ExternalGrabUserService externalGrabUserService;
/**
* 积分明细分页列表(免认证)
* 复用 UserIntegralRecordService.findAdminList与 /admin/user/integral/list 逻辑完全一致。
@@ -93,4 +117,90 @@ public class ExternalIntegralController {
}
return CommonResult.success(restPage);
}
// ========================================================================
// 寄卖订单管理wa_order
// 复用 WaOrderAdminService仅读路径不使用 @PreAuthorize。
// ========================================================================
/**
* 寄卖订单分页列表(免认证)
*/
@ApiOperation(value = "寄卖订单分页列表(免认证)")
@GetMapping(value = "/wa-order/list")
public CommonResult<CommonPage<WaOrderResponse>> waOrderList(
@ModelAttribute @Validated WaOrderSearchRequest request,
@Validated PageParamRequest pageParamRequest) {
CommonPage<WaOrderResponse> restPage =
CommonPage.restPage(waOrderAdminService.getAdminList(request, pageParamRequest));
return CommonResult.success(restPage);
}
/**
* 寄卖订单详情(免认证)
*/
@ApiOperation(value = "寄卖订单详情(免认证)")
@GetMapping(value = "/wa-order/info")
public CommonResult<WaOrderResponse> waOrderInfo(@RequestParam Integer id) {
return CommonResult.success(waOrderAdminService.getDetailById(id));
}
// ========================================================================
// 团队每日对账日报
// ========================================================================
/**
* 团队每日对账日报(免认证)。
* - leaderId 非空返回该团队对账teams 仅 1 项)
* - leaderId 为空:按团队长分组返回所有团队对账 + 跨团队总计
*/
@ApiOperation(value = "团队每日对账(免认证)")
@GetMapping(value = "/team-report/daily")
public CommonResult<TeamDailyMultiReportResponse> teamDailyReport(
@ModelAttribute @Validated TeamDailyReportRequest request) {
return CommonResult.success(teamReportExternalService.getMultiDailyReport(request));
}
/**
* 团队每日对账日报 - Excel 导出(免认证;仅支持单团队,必须传 leaderId
*/
@ApiOperation(value = "团队每日对账 Excel 导出(免认证)")
@GetMapping(value = "/team-report/daily/export")
public ResponseEntity<byte[]> teamDailyReportExport(
@ModelAttribute @Validated TeamDailyReportRequest request) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
TeamDailyReportResponse data = teamReportExternalService.exportDailyReport(request, out);
String fileName = String.format("团队%s_%s.xlsx",
data.getTeamCode() == null ? "" : data.getTeamCode(),
data.getDate());
String encoded = URLEncoder.encode(fileName, StandardCharsets.UTF_8.name())
.replaceAll("\\+", "%20");
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.parseMediaType(
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"));
headers.add(HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename=\"" + encoded + "\"; filename*=UTF-8''" + encoded);
return new ResponseEntity<>(out.toByteArray(), headers, org.springframework.http.HttpStatus.OK);
}
// ========================================================================
// 今日抢单用户列表
// ========================================================================
/**
* 今日抢单用户列表(免认证)
* 过滤口径:今日购买总金额 &gt; 0已在 SQL 层落实。
*/
@ApiOperation(value = "今日抢单用户分页列表(免认证)")
@GetMapping(value = "/grab-user/list")
public CommonResult<CommonPage<ExternalGrabUserResponse>> grabUserList(
@ModelAttribute @Validated ExternalGrabUserRequest request,
@Validated PageParamRequest pageParamRequest) {
CommonPage<ExternalGrabUserResponse> restPage =
CommonPage.restPage(externalGrabUserService.list(request, pageParamRequest));
return CommonResult.success(restPage);
}
}

View File

@@ -1,59 +0,0 @@
# CRMEB 相关配置
crmeb:
captchaOn: false # 是否开启行为验证码
asyncConfig: true #是否同步config表数据到redis
server:
port: 30032
sync:
source-id: shop_13
target-mer-id: 13
spring:
datasource:
name: yangtangyoupin
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://121.43.134.82:3306/${spring.datasource.name}?useUnicode=true&serverTimezone=GMT%2B8&characterEncoding=utf8
username: yangtangyoupin
password: 5Fn8eWrbYFtAhCZw
redis:
host: 121.43.134.82 #地址
port: 6379 #端口
password: '123456'
timeout: 10000 # 连接超时时间(毫秒)
database: 2 #默认数据库
jedis:
pool:
max-active: 200 # 连接池最大连接数(使用负值表示没有限制)
max-wait: -1 # 连接池最大阻塞等待时间(使用负值表示没有限制)
max-idle: 10 # 连接池中的最大空闲连接
min-idle: 0 # 连接池中的最小空闲连接
time-between-eviction-runs: -1 #逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认-1
second:
database: 2 # 微信accessToken存储库
debug: true
logging:
level:
io.swagger.*: error
com.zbjk.crmeb: debug
org.springframework.boot.autoconfigure: ERROR
config: classpath:logback-spring.xml
file:
path: ./logs
# mybatis 配置
mybatis-plus:
# 配置sql打印日志
configuration:
log-impl:
#swagger 配置
swagger:
basic:
enable: true #是否开启界面
check: false #是否打开验证
username: crmeb #访问swagger的账号
password: crmeb.com #访问swagger的密码

View File

@@ -1,59 +0,0 @@
# CRMEB 相关配置
crmeb:
captchaOn: false # 是否开启行为验证码
asyncConfig: true #是否同步config表数据到redis
server:
port: 30032
sync:
source-id: shop_12
target-mer-id: 12
spring:
datasource:
name: yangtangyoupin
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://101.37.101.6:3306/${spring.datasource.name}?useUnicode=true&serverTimezone=GMT%2B8&characterEncoding=utf8
username: yangtangyoupin
password: 5Fn8eWrbYFtAhCZw
redis:
host: 101.37.101.6 #地址
port: 6379 #端口
password: '123456'
timeout: 10000 # 连接超时时间(毫秒)
database: 2 #默认数据库
jedis:
pool:
max-active: 200 # 连接池最大连接数(使用负值表示没有限制)
max-wait: -1 # 连接池最大阻塞等待时间(使用负值表示没有限制)
max-idle: 10 # 连接池中的最大空闲连接
min-idle: 0 # 连接池中的最小空闲连接
time-between-eviction-runs: -1 #逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认-1
second:
database: 2 # 微信accessToken存储库
debug: true
logging:
level:
io.swagger.*: error
com.zbjk.crmeb: debug
org.springframework.boot.autoconfigure: ERROR
config: classpath:logback-spring.xml
file:
path: ./logs
# mybatis 配置
mybatis-plus:
# 配置sql打印日志
configuration:
log-impl:
#swagger 配置
swagger:
basic:
enable: true #是否开启界面
check: false #是否打开验证
username: crmeb #访问swagger的账号
password: crmeb.com #访问swagger的密码

View File

@@ -38,7 +38,7 @@ server:
spring:
profiles:
active: czcf82
active: byjyw149
servlet:
multipart:
max-file-size: 50MB #设置单个文件大小

View File

@@ -0,0 +1,33 @@
package com.zbkj.common.request;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
/**
* 今日抢单用户列表 查询请求(外部免认证)
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
* +----------------------------------------------------------------------
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value = "ExternalGrabUserRequest 对象", description = "今日抢单用户列表查询请求")
public class ExternalGrabUserRequest implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "用户ID精确")
private Integer uid;
@ApiModelProperty(value = "联系方式(模糊匹配 mobile / username")
private String mobile;
@ApiModelProperty(value = "上级ID精确")
private Integer pid;
}

View File

@@ -0,0 +1,37 @@
package com.zbkj.common.request;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.List;
/**
* 团队每日对账日报 查询请求(外部免认证)
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
* +----------------------------------------------------------------------
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value = "TeamDailyReportRequest 对象", description = "团队每日对账查询请求")
public class TeamDailyReportRequest implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "团队长 IDwa_users.id为空时按团队长分组返回所有团队")
private Integer leaderId;
@ApiModelProperty(value = "查询日期 Dyyyy-MM-dd缺省为昨天")
private String date;
@ApiModelProperty(value = "是否包含禁用成员,默认 false")
private Boolean includeDisabled = Boolean.FALSE;
@ApiModelProperty(value = "限定成员 ID 列表(前端勾选过滤)")
private List<Integer> memberIds;
}

View File

@@ -37,6 +37,9 @@ public class UserSearchRequest implements Serializable {
@ApiModelProperty(value = "关键字")
private String keywords;
@ApiModelProperty(value = "用户uid")
private Integer uid;
@ApiModelProperty(value = "时间")
private String dateLimit;

View File

@@ -0,0 +1,115 @@
package com.zbkj.common.response;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
/**
* 今日抢单用户列表 响应对象(外部免认证)
* 字段保留 3 位小数(与上传参考图一致),由 Service 层格式化为字符串。
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
* +----------------------------------------------------------------------
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value = "ExternalGrabUserResponse 对象", description = "今日抢单用户列表响应")
public class ExternalGrabUserResponse implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "用户ID")
private Integer id;
@ApiModelProperty(value = "账号 / 用户名")
private String username;
@ApiModelProperty(value = "昵称")
private String nickname;
@ApiModelProperty(value = "手机号 / 联系方式")
private String mobile;
@ApiModelProperty(value = "合同 URL为空表示未上传")
private String contract;
@ApiModelProperty(value = "上级ID")
private Integer pid;
@ApiModelProperty(value = "最高可抢单数")
private Integer maxOrder;
@ApiModelProperty(value = "用户等级(数值)")
private Integer level;
@ApiModelProperty(value = "用户等级文案")
private String levelName;
@ApiModelProperty(value = "余额(保留 3 位小数)")
private String money;
@ApiModelProperty(value = "优惠券(保留 3 位小数)")
private String coupon;
@ApiModelProperty(value = "个人奖金(保留 3 位小数)")
private String selfBonus;
@ApiModelProperty(value = "推广奖金(保留 3 位小数)")
private String shareBonus;
@ApiModelProperty(value = "状态0=禁用1=正常")
private Integer status;
@ApiModelProperty(value = "状态文案")
private String statusStr;
@ApiModelProperty(value = "更新时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
private Date updatedAt;
@ApiModelProperty(value = "今日购买总金额(保留 3 位小数)")
private String todayBuyAmount;
@ApiModelProperty(value = "今日卖出总金额(保留 3 位小数)")
private String todaySellAmount;
@ApiModelProperty(value = "今日买单数")
private Integer todayBuyCnt;
@ApiModelProperty(value = "昨日卖单数")
private Integer prevSellCnt;
/** 内部使用SQL 聚合后由 Service 二次处理为格式化字符串;不输出到 JSON */
@JsonIgnore
@ApiModelProperty(hidden = true)
private BigDecimal todayBuyAmountRaw;
@JsonIgnore
@ApiModelProperty(hidden = true)
private BigDecimal todaySellAmountRaw;
@JsonIgnore
@ApiModelProperty(hidden = true)
private BigDecimal moneyRaw;
@JsonIgnore
@ApiModelProperty(hidden = true)
private BigDecimal couponRaw;
@JsonIgnore
@ApiModelProperty(hidden = true)
private BigDecimal selfBonusRaw;
@JsonIgnore
@ApiModelProperty(hidden = true)
private BigDecimal shareBonusRaw;
}

View File

@@ -0,0 +1,71 @@
package com.zbkj.common.response;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* 团队每日对账日报 - 单成员行
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
* +----------------------------------------------------------------------
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value = "TeamDailyMemberRow 对象", description = "团队每日对账 - 单成员行")
public class TeamDailyMemberRow implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "成员用户 ID")
private Integer userId;
@ApiModelProperty(value = "成员昵称")
private String nickname;
@ApiModelProperty(value = "团队代号")
private String teamCode;
@ApiModelProperty(value = "成员状态1=启用0=禁用")
private Integer status;
/** 内部使用:所属团队长 ID即 wa_users.pid不输出到 JSON */
@JsonIgnore
@ApiModelProperty(hidden = true)
private Integer leaderId;
@ApiModelProperty(value = "D-1 买单合计")
@JsonFormat(shape = JsonFormat.Shape.STRING)
private BigDecimal prevBuy;
@ApiModelProperty(value = "D 卖单合计")
@JsonFormat(shape = JsonFormat.Shape.STRING)
private BigDecimal todaySell;
@ApiModelProperty(value = "D 买单合计")
@JsonFormat(shape = JsonFormat.Shape.STRING)
private BigDecimal todayBuy;
@ApiModelProperty(value = "服务费 = D买单 × service_rate")
@JsonFormat(shape = JsonFormat.Shape.STRING)
private BigDecimal serviceFee;
@ApiModelProperty(value = "E 积分 = D买单 × e_score_rate")
@JsonFormat(shape = JsonFormat.Shape.STRING)
private BigDecimal eScore;
@ApiModelProperty(value = "实际收付 = D卖单 D买单 服务费 E积分")
@JsonFormat(shape = JsonFormat.Shape.STRING)
private BigDecimal actual;
@ApiModelProperty(value = "备注(前端会话级,非持久化)")
private String remark;
}

View File

@@ -0,0 +1,59 @@
package com.zbkj.common.response;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.List;
/**
* 团队每日对账日报 — 多团队聚合响应(外部免认证)。
*
* 当前端不传 leaderId 时返回此结构,按团队长分组列出全部团队的报表,
* 并附带跨团队的总计。当 leaderId 传入时 teams 仅含 1 项。
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
* +----------------------------------------------------------------------
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value = "TeamDailyMultiReportResponse 对象", description = "多团队每日对账响应")
public class TeamDailyMultiReportResponse implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("查询日期 Dyyyy-MM-dd")
private String date;
@ApiModelProperty("D-1 日期yyyy-MM-dd")
private String previousDate;
@ApiModelProperty("服务费率")
@JsonFormat(shape = JsonFormat.Shape.STRING)
private BigDecimal serviceRate;
@ApiModelProperty("E 积分率")
@JsonFormat(shape = JsonFormat.Shape.STRING)
private BigDecimal eScoreRate;
@ApiModelProperty("团队数")
private Integer teamCount;
@ApiModelProperty("成员合计(跨团队)")
private Integer totalMemberCount;
@ApiModelProperty("各团队报表(按 leaderId 分组)")
private List<TeamDailyReportResponse> teams;
@ApiModelProperty("跨团队总计")
private TeamDailySummary grandSummary;
@ApiModelProperty("警告信息(如非法 memberIds")
private List<String> warnings;
}

View File

@@ -0,0 +1,62 @@
package com.zbkj.common.response;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.List;
/**
* 团队每日对账日报 响应(外部免认证)
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
* +----------------------------------------------------------------------
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value = "TeamDailyReportResponse 对象", description = "团队每日对账日报响应")
public class TeamDailyReportResponse implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("团队长 ID")
private Integer leaderId;
@ApiModelProperty("团队长昵称")
private String leaderNickname;
@ApiModelProperty("团队代号")
private String teamCode;
@ApiModelProperty("成员人数")
private Integer memberCount;
@ApiModelProperty("查询日期 Dyyyy-MM-dd")
private String date;
@ApiModelProperty("D-1 日期yyyy-MM-dd")
private String previousDate;
@ApiModelProperty("服务费率")
@JsonFormat(shape = JsonFormat.Shape.STRING)
private BigDecimal serviceRate;
@ApiModelProperty("E 积分率")
@JsonFormat(shape = JsonFormat.Shape.STRING)
private BigDecimal eScoreRate;
@ApiModelProperty("成员行")
private List<TeamDailyMemberRow> rows;
@ApiModelProperty("小计")
private TeamDailySummary summary;
@ApiModelProperty("警告信息(如非法 memberIds")
private List<String> warnings;
}

View File

@@ -0,0 +1,50 @@
package com.zbkj.common.response;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* 团队每日对账日报 - 小计
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
* +----------------------------------------------------------------------
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value = "TeamDailySummary 对象", description = "团队每日对账 - 小计")
public class TeamDailySummary implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("D-1 买单合计")
@JsonFormat(shape = JsonFormat.Shape.STRING)
private BigDecimal prevBuy = BigDecimal.ZERO;
@ApiModelProperty("D 卖单合计")
@JsonFormat(shape = JsonFormat.Shape.STRING)
private BigDecimal todaySell = BigDecimal.ZERO;
@ApiModelProperty("D 买单合计")
@JsonFormat(shape = JsonFormat.Shape.STRING)
private BigDecimal todayBuy = BigDecimal.ZERO;
@ApiModelProperty("服务费合计")
@JsonFormat(shape = JsonFormat.Shape.STRING)
private BigDecimal serviceFee = BigDecimal.ZERO;
@ApiModelProperty("E 积分合计")
@JsonFormat(shape = JsonFormat.Shape.STRING)
private BigDecimal eScore = BigDecimal.ZERO;
@ApiModelProperty("实际收付合计")
@JsonFormat(shape = JsonFormat.Shape.STRING)
private BigDecimal actual = BigDecimal.ZERO;
}

View File

@@ -10,6 +10,7 @@ import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
/**
@@ -51,7 +52,7 @@ public class UserIntegralRecordResponse implements Serializable {
private String title;
@ApiModelProperty(value = "积分")
private Integer integral;
private BigDecimal integral;
@ApiModelProperty(value = "剩余")
private Integer balance;

View File

@@ -93,6 +93,12 @@ public class WaOrderResponse implements Serializable {
@ApiModelProperty(value = "寄售商品ID")
private Integer merchandiseId;
@ApiModelProperty(value = "寄售商品标题")
private String merchandiseTitle;
@ApiModelProperty(value = "寄售商品图片")
private String merchandiseImage;
@ApiModelProperty(value = "确认收货时间")
private Date confirmTime;

View File

@@ -73,7 +73,7 @@ public class WaUserController {
FileInputStream fileInputStream = null;
try {
// 读取模板PDF文件
Resource resource = new ClassPathResource("pdf/sign_contract_czcf82.pdf");
Resource resource = new ClassPathResource("pdf/sign_contract_byjyw149.pdf");
InputStream pdfInputStream = resource.getInputStream();
document = PDDocument.load(pdfInputStream);
pdfInputStream.close();
@@ -199,7 +199,7 @@ public class WaUserController {
// user.setContract("https://anyue.szxingming.com/"+pdfResultVo.getUrl());
// user.setContract("https://xiashengjun.com/"+pdfResultVo.getUrl());
// user.setContract("https://ccd.cichude.com/"+pdfResultVo.getUrl());
user.setContract("https://czcf.uj345.com/"+pdfResultVo.getUrl());
user.setContract("https://jinyawen.com/"+pdfResultVo.getUrl());
waUsersDao.updateById(user);
}
return CommonResult.success(pdfResultVo);

View File

@@ -1,54 +0,0 @@
crmeb:
imagePath: /www/wwwroot/czchunfang.com/ # 池州春芳商贸服务器图片路径 斜杠结尾
asyncConfig: true #是否同步config表数据到redis
server:
port: 30031
spring:
datasource:
name: yangtangyoupin
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://121.43.134.82:3306/${spring.datasource.name}?useUnicode=true&serverTimezone=GMT%2B8&characterEncoding=utf8
username: yangtangyoupin
password: 5Fn8eWrbYFtAhCZw
redis:
host: 121.43.134.82 #地址
port: 6379 #端口
password: '123456'
timeout: 10000 # 连接超时时间(毫秒)
database: 2 #默认数据库
jedis:
pool:
max-active: 200 # 连接池最大连接数(使用负值表示没有限制)
max-wait: -1 # 连接池最大阻塞等待时间(使用负值表示没有限制)
max-idle: 10 # 连接池中的最大空闲连接
min-idle: 0 # 连接池中的最小空闲连接
time-between-eviction-runs: -1 #逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认-1
second:
database: 3 # 微信accessToken存储库
debug: true
logging:
level:
io.swagger.*: error
com.zbjk.crmeb: debug
org.springframework.boot.autoconfigure: ERROR
config: classpath:logback-spring.xml
file:
path: ./logs
# mybatis 配置
mybatis-plus:
# 配置sql打印日志
configuration:
log-impl:
#swagger 配置
swagger:
basic:
enable: true #是否开启界面
check: false #是否打开验证
username: crmeb #访问swagger的账号
password: crmeb.com #访问swagger的密码

View File

@@ -1,54 +0,0 @@
crmeb:
imagePath: /www/wwwroot/czruitang.com/ # 池州瑞棠商贸服务器图片路径 斜杠结尾
asyncConfig: true #是否同步config表数据到redis
server:
port: 30031
spring:
datasource:
name: yangtangyoupin
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://101.37.101.6:3306/${spring.datasource.name}?useUnicode=true&serverTimezone=GMT%2B8&characterEncoding=utf8
username: yangtangyoupin
password: 5Fn8eWrbYFtAhCZw
redis:
host: 101.37.101.6 #地址
port: 6379 #端口
password: '123456'
timeout: 10000 # 连接超时时间(毫秒)
database: 2 #默认数据库
jedis:
pool:
max-active: 200 # 连接池最大连接数(使用负值表示没有限制)
max-wait: -1 # 连接池最大阻塞等待时间(使用负值表示没有限制)
max-idle: 10 # 连接池中的最大空闲连接
min-idle: 0 # 连接池中的最小空闲连接
time-between-eviction-runs: -1 #逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认-1
second:
database: 3 # 微信accessToken存储库
debug: true
logging:
level:
io.swagger.*: error
com.zbjk.crmeb: debug
org.springframework.boot.autoconfigure: ERROR
config: classpath:logback-spring.xml
file:
path: ./logs
# mybatis 配置
mybatis-plus:
# 配置sql打印日志
configuration:
log-impl:
#swagger 配置
swagger:
basic:
enable: true #是否开启界面
check: false #是否打开验证
username: crmeb #访问swagger的账号
password: crmeb.com #访问swagger的密码

View File

@@ -32,7 +32,7 @@ server:
spring:
profiles:
active: czcf82
active: byjyw149
servlet:
multipart:
max-file-size: 50MB #设置单个文件大小

View File

@@ -22,6 +22,13 @@
<artifactId>crmeb-common</artifactId>
<version>${crmeb-common}</version>
</dependency>
<!-- 单元测试(仅 test 作用域;用于 util 类公式校验等纯函数测试) -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>

View File

@@ -0,0 +1,44 @@
package com.zbkj.service.dao.consignment;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zbkj.common.model.consignment.WaUsers;
import com.zbkj.common.response.ExternalGrabUserResponse;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.Date;
import java.util.List;
/**
* 今日抢单用户 DAO外部免认证
* 通过自定义 SQL 一次性聚合:
* - 今日买单合计 / 笔数INNER JOINHAVING SUM>0
* - 今日卖单合计
* - 昨日卖单笔数
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
* +----------------------------------------------------------------------
*/
@Mapper
public interface ExternalGrabUserDao extends BaseMapper<WaUsers> {
/**
* 列表查询。
*
* @param todayStart 今天 00:00:00
* @param todayEnd 今天 23:59:59
* @param yesterdayStart 昨天 00:00:00
* @param yesterdayEnd 昨天 23:59:59
* @param uid 用户 ID精确可空
* @param mobile 模糊匹配 mobile / username可空
* @param pid 上级 ID精确可空
*/
List<ExternalGrabUserResponse> selectGrabUserList(
@Param("todayStart") Date todayStart,
@Param("todayEnd") Date todayEnd,
@Param("yesterdayStart") Date yesterdayStart,
@Param("yesterdayEnd") Date yesterdayEnd,
@Param("uid") Integer uid,
@Param("mobile") String mobile,
@Param("pid") Integer pid);
}

View File

@@ -0,0 +1,43 @@
package com.zbkj.service.dao.consignment;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zbkj.common.model.consignment.WaUsers;
import com.zbkj.common.response.TeamDailyMemberRow;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.Date;
import java.util.List;
/**
* 团队每日对账日报 DAO外部免认证
* 通过自定义 SQL 一次性聚合每个直推下级的D-1 买单 / D 卖单 / D 买单。
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
* +----------------------------------------------------------------------
*/
@Mapper
public interface TeamReportDao extends BaseMapper<WaUsers> {
/**
* 查询团队成员每日对账原始数据。
*
* @param leaderId 团队长 ID为 null 时返回所有有 pid 的成员,由 Service 按 leader_id 分组
*/
List<TeamDailyMemberRow> selectTeamMemberAggregates(
@Param("leaderId") Integer leaderId,
@Param("dStart") Date dStart,
@Param("dEnd") Date dEnd,
@Param("prevStart") Date prevStart,
@Param("prevEnd") Date prevEnd,
@Param("includeDisabled") Boolean includeDisabled,
@Param("memberIds") List<Integer> memberIds);
/**
* 读取 wa_setting 中某 key 的字符串值(不存在时返回 null
* KV 表无独立 Model使用注解直接查询。
*/
@Select("SELECT `value` FROM wa_setting WHERE `name` = #{name} LIMIT 1")
String selectSettingValue(@Param("name") String name);
}

View File

@@ -0,0 +1,26 @@
package com.zbkj.service.service;
import com.github.pagehelper.PageInfo;
import com.zbkj.common.request.ExternalGrabUserRequest;
import com.zbkj.common.request.PageParamRequest;
import com.zbkj.common.response.ExternalGrabUserResponse;
/**
* 今日抢单用户列表 Service外部免认证
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
* +----------------------------------------------------------------------
*/
public interface ExternalGrabUserService {
/**
* 分页查询当日已发生买单且金额 &gt; 0 的用户列表。
* 排序:今日购买总金额 DESC相同时按 id DESC。
*
* @param request 搜索条件
* @param pageParamRequest 分页参数
* @return PageInfo&lt;ExternalGrabUserResponse&gt;
*/
PageInfo<ExternalGrabUserResponse> list(ExternalGrabUserRequest request,
PageParamRequest pageParamRequest);
}

View File

@@ -0,0 +1,36 @@
package com.zbkj.service.service;
import com.zbkj.common.request.TeamDailyReportRequest;
import com.zbkj.common.response.TeamDailyMultiReportResponse;
import com.zbkj.common.response.TeamDailyReportResponse;
import java.io.IOException;
import java.io.OutputStream;
/**
* 团队每日对账日报 Service外部免认证
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
* +----------------------------------------------------------------------
*/
public interface TeamReportExternalService {
/**
* 查询某团队某日对账数据(要求 leaderId 非空)。
*/
TeamDailyReportResponse getDailyReport(TeamDailyReportRequest request);
/**
* 查询多团队对账数据:
* - leaderId 为空:按团队长分组返回所有团队
* - leaderId 非空teams 仅含该团队
*
* @return 多团队报表(含 grandSummary 与每个团队的子报表)
*/
TeamDailyMultiReportResponse getMultiDailyReport(TeamDailyReportRequest request);
/**
* Excel 导出(仅支持单团队,要求 leaderId 非空)。
*/
TeamDailyReportResponse exportDailyReport(TeamDailyReportRequest request, OutputStream out) throws IOException;
}

View File

@@ -0,0 +1,80 @@
package com.zbkj.service.service.impl;
import cn.hutool.core.util.StrUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zbkj.common.request.ExternalGrabUserRequest;
import com.zbkj.common.request.PageParamRequest;
import com.zbkj.common.response.ExternalGrabUserResponse;
import com.zbkj.service.dao.consignment.ExternalGrabUserDao;
import com.zbkj.service.service.ExternalGrabUserService;
import com.zbkj.service.util.GrabUserFormatter;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.List;
/**
* 今日抢单用户列表 Service 实现(外部免认证)
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
* +----------------------------------------------------------------------
*/
@Service
public class ExternalGrabUserServiceImpl implements ExternalGrabUserService {
private static final ZoneId ZONE_CN = ZoneId.of("Asia/Shanghai");
@Resource
private ExternalGrabUserDao externalGrabUserDao;
@Override
public PageInfo<ExternalGrabUserResponse> list(ExternalGrabUserRequest request,
PageParamRequest pageParamRequest) {
if (request == null) {
request = new ExternalGrabUserRequest();
}
// 时间窗(业务时区 CST
LocalDate today = LocalDate.now(ZONE_CN);
Date todayStart = toDate(today.atStartOfDay());
Date todayEnd = toDate(today.atTime(LocalTime.MAX));
LocalDate yesterday = today.minusDays(1);
Date yesterdayStart = toDate(yesterday.atStartOfDay());
Date yesterdayEnd = toDate(yesterday.atTime(LocalTime.MAX));
// 分页PageHelper 在执行下一条 SQL 时生效)
int page = pageParamRequest != null && pageParamRequest.getPage() > 0 ? pageParamRequest.getPage() : 1;
int limit = pageParamRequest != null && pageParamRequest.getLimit() > 0 ? Math.min(pageParamRequest.getLimit(), 100) : 15;
PageHelper.startPage(page, limit);
List<ExternalGrabUserResponse> rows = externalGrabUserDao.selectGrabUserList(
todayStart, todayEnd, yesterdayStart, yesterdayEnd,
request.getUid(),
StrUtil.trimToNull(request.getMobile()),
request.getPid());
// 后处理:金额格式化、状态/等级文案
for (ExternalGrabUserResponse row : rows) {
row.setMoney(GrabUserFormatter.formatAmount(row.getMoneyRaw()));
row.setCoupon(GrabUserFormatter.formatAmount(row.getCouponRaw()));
row.setSelfBonus(GrabUserFormatter.formatAmount(row.getSelfBonusRaw()));
row.setShareBonus(GrabUserFormatter.formatAmount(row.getShareBonusRaw()));
row.setTodayBuyAmount(GrabUserFormatter.formatAmount(row.getTodayBuyAmountRaw()));
row.setTodaySellAmount(GrabUserFormatter.formatAmount(row.getTodaySellAmountRaw()));
row.setStatusStr(GrabUserFormatter.mapStatus(row.getStatus()));
row.setLevelName(GrabUserFormatter.mapLevelName(row.getLevel()));
}
return new PageInfo<>(rows);
}
private static Date toDate(LocalDateTime dt) {
return Date.from(dt.atZone(ZONE_CN).toInstant());
}
}

View File

@@ -0,0 +1,385 @@
package com.zbkj.service.service.impl;
import cn.hutool.core.util.StrUtil;
import com.zbkj.common.exception.CrmebException;
import com.zbkj.common.model.consignment.WaUsers;
import com.zbkj.common.request.TeamDailyReportRequest;
import com.zbkj.common.response.TeamDailyMemberRow;
import com.zbkj.common.response.TeamDailyMultiReportResponse;
import com.zbkj.common.response.TeamDailyReportResponse;
import com.zbkj.common.response.TeamDailySummary;
import com.zbkj.service.dao.consignment.TeamReportDao;
import com.zbkj.service.dao.consignment.WaUsersDao;
import com.zbkj.service.service.TeamReportExternalService;
import com.zbkj.service.util.TeamReportFormula;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 团队每日对账日报 Service 实现(外部免认证)
*
* 关键设计:
* 1) 费率从 wa_setting 读取service_rate / e_score_rate缺省 0.02 / 0.005
* 2) BigDecimal 全程 HALF_UP 保留 2 位;
* 3) 小计的服务费 / E积分 / 实际收付 由"成员级别已舍入数值"再求和,避免逐行二次舍入;
* 4) 时区:业务时区 Asia/Shanghai。
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
* +----------------------------------------------------------------------
*/
@Service
public class TeamReportExternalServiceImpl implements TeamReportExternalService {
private static final ZoneId ZONE_CN = ZoneId.of("Asia/Shanghai");
private static final DateTimeFormatter DATE_FMT = DateTimeFormatter.ofPattern("yyyy-MM-dd");
private static final BigDecimal DEFAULT_SERVICE_RATE = new BigDecimal("0.02");
private static final BigDecimal DEFAULT_E_SCORE_RATE = new BigDecimal("0.005");
private static final int SCALE = 2;
@Resource
private TeamReportDao teamReportDao;
@Resource
private WaUsersDao waUsersDao;
@Override
public TeamDailyReportResponse getDailyReport(TeamDailyReportRequest request) {
if (request == null || request.getLeaderId() == null) {
throw new CrmebException("团队长 ID 不能为空");
}
return assembleSingleTeam(request);
}
@Override
public TeamDailyMultiReportResponse getMultiDailyReport(TeamDailyReportRequest request) {
if (request == null) request = new TeamDailyReportRequest();
Ctx ctx = prepare(request);
// 拉取原始聚合leaderId 为空时一次拿所有团队成员)
List<TeamDailyMemberRow> rows = teamReportDao.selectTeamMemberAggregates(
request.getLeaderId(), ctx.dStart, ctx.dEnd, ctx.pStart, ctx.pEnd,
request.getIncludeDisabled(),
(request.getMemberIds() != null && !request.getMemberIds().isEmpty())
? request.getMemberIds() : null);
if (rows == null) rows = new ArrayList<>();
// 公式计算
for (TeamDailyMemberRow r : rows) {
TeamReportFormula.applyFormula(r, ctx.serviceRate, ctx.eScoreRate);
r.setRemark("");
}
// 按 leaderId 分组(保持稳定顺序)
Map<Integer, List<TeamDailyMemberRow>> groups = new LinkedHashMap<>();
Set<Integer> leaderIds = new HashSet<>();
for (TeamDailyMemberRow r : rows) {
Integer lid = r.getLeaderId();
if (lid == null || lid <= 0) continue;
groups.computeIfAbsent(lid, k -> new ArrayList<>()).add(r);
leaderIds.add(lid);
}
// 批量拉取团队长信息
Map<Integer, WaUsers> leaderMap = new HashMap<>();
if (!leaderIds.isEmpty()) {
for (WaUsers u : waUsersDao.selectBatchIds(leaderIds)) {
leaderMap.put(u.getId(), u);
}
}
// 组装每个团队子报表
List<TeamDailyReportResponse> teams = new ArrayList<>(groups.size());
TeamDailySummary grand = new TeamDailySummary();
int totalMembers = 0;
for (Map.Entry<Integer, List<TeamDailyMemberRow>> e : groups.entrySet()) {
Integer lid = e.getKey();
List<TeamDailyMemberRow> teamRows = e.getValue();
WaUsers leader = leaderMap.get(lid);
String leaderNickname = leader != null ? leader.getNickname() : null;
String teamCode = leader != null && StrUtil.isNotBlank(leader.getInvite())
? leader.getInvite()
: String.valueOf(lid);
TeamDailySummary teamSummary = TeamReportFormula.aggregateSummary(teamRows);
teams.add(new TeamDailyReportResponse()
.setLeaderId(lid)
.setLeaderNickname(leaderNickname)
.setTeamCode(teamCode)
.setMemberCount(teamRows.size())
.setDate(ctx.d.format(DATE_FMT))
.setPreviousDate(ctx.prev.format(DATE_FMT))
.setServiceRate(ctx.serviceRate)
.setEScoreRate(ctx.eScoreRate)
.setRows(teamRows)
.setSummary(teamSummary));
// 累加 grand summary
grand.setPrevBuy(grand.getPrevBuy().add(teamSummary.getPrevBuy()));
grand.setTodaySell(grand.getTodaySell().add(teamSummary.getTodaySell()));
grand.setTodayBuy(grand.getTodayBuy().add(teamSummary.getTodayBuy()));
grand.setServiceFee(grand.getServiceFee().add(teamSummary.getServiceFee()));
grand.setEScore(grand.getEScore().add(teamSummary.getEScore()));
grand.setActual(grand.getActual().add(teamSummary.getActual()));
totalMembers += teamRows.size();
}
return new TeamDailyMultiReportResponse()
.setDate(ctx.d.format(DATE_FMT))
.setPreviousDate(ctx.prev.format(DATE_FMT))
.setServiceRate(ctx.serviceRate)
.setEScoreRate(ctx.eScoreRate)
.setTeamCount(teams.size())
.setTotalMemberCount(totalMembers)
.setTeams(teams)
.setGrandSummary(grand);
}
@Override
public TeamDailyReportResponse exportDailyReport(TeamDailyReportRequest request, OutputStream out) throws IOException {
if (request == null || request.getLeaderId() == null) {
throw new CrmebException("Excel 导出仅支持单团队,必须指定团队长 ID");
}
TeamDailyReportResponse data = assembleSingleTeam(request);
writeExcel(data, out);
return data;
}
// ------------------------------------------------------------------
// 主流程:单团队装配
// ------------------------------------------------------------------
private TeamDailyReportResponse assembleSingleTeam(TeamDailyReportRequest request) {
// 校验团队长存在
WaUsers leader = waUsersDao.selectById(request.getLeaderId());
if (leader == null) {
throw new CrmebException("团队长不存在");
}
Ctx ctx = prepare(request);
// 拉取原始聚合
List<TeamDailyMemberRow> rows = teamReportDao.selectTeamMemberAggregates(
request.getLeaderId(), ctx.dStart, ctx.dEnd, ctx.pStart, ctx.pEnd,
request.getIncludeDisabled(),
(request.getMemberIds() != null && !request.getMemberIds().isEmpty())
? request.getMemberIds() : null);
if (rows == null) rows = new ArrayList<>();
for (TeamDailyMemberRow r : rows) {
TeamReportFormula.applyFormula(r, ctx.serviceRate, ctx.eScoreRate);
r.setRemark("");
}
TeamDailySummary summary = TeamReportFormula.aggregateSummary(rows);
String teamCode = StrUtil.isNotBlank(leader.getInvite())
? leader.getInvite()
: String.valueOf(leader.getId());
return new TeamDailyReportResponse()
.setLeaderId(leader.getId())
.setLeaderNickname(leader.getNickname())
.setTeamCode(teamCode)
.setMemberCount(rows.size())
.setDate(ctx.d.format(DATE_FMT))
.setPreviousDate(ctx.prev.format(DATE_FMT))
.setServiceRate(ctx.serviceRate)
.setEScoreRate(ctx.eScoreRate)
.setRows(rows)
.setSummary(summary);
}
/** 单/多团队共用的上下文(日期、时间窗、费率) */
private Ctx prepare(TeamDailyReportRequest request) {
LocalDate today = LocalDate.now(ZONE_CN);
LocalDate d;
if (StrUtil.isNotBlank(request.getDate())) {
d = LocalDate.parse(request.getDate(), DATE_FMT);
} else {
d = today.minusDays(1);
}
if (d.isAfter(today)) {
throw new CrmebException("不能查询未来日期");
}
LocalDate prev = d.minusDays(1);
Ctx ctx = new Ctx();
ctx.d = d;
ctx.prev = prev;
ctx.dStart = toDate(d, true);
ctx.dEnd = toDate(d, false);
ctx.pStart = toDate(prev, true);
ctx.pEnd = toDate(prev, false);
ctx.serviceRate = readRate("service_rate", DEFAULT_SERVICE_RATE);
ctx.eScoreRate = readRate("e_score_rate", DEFAULT_E_SCORE_RATE);
return ctx;
}
/** Service 内部上下文 */
private static class Ctx {
LocalDate d;
LocalDate prev;
Date dStart;
Date dEnd;
Date pStart;
Date pEnd;
BigDecimal serviceRate;
BigDecimal eScoreRate;
}
// ------------------------------------------------------------------
// 工具方法
// ------------------------------------------------------------------
private static Date toDate(LocalDate date, boolean start) {
return Date.from((start ? date.atStartOfDay() : date.atTime(LocalTime.MAX))
.atZone(ZONE_CN).toInstant());
}
private BigDecimal readRate(String name, BigDecimal fallback) {
String v = teamReportDao.selectSettingValue(name);
if (StrUtil.isBlank(v)) return fallback;
try {
return new BigDecimal(v.trim());
} catch (Exception e) {
return fallback;
}
}
// ------------------------------------------------------------------
// Excel 导出Apache POI
// ------------------------------------------------------------------
private void writeExcel(TeamDailyReportResponse data, OutputStream out) throws IOException {
try (Workbook wb = new XSSFWorkbook()) {
Sheet sheet = wb.createSheet("团队日报");
// 表头横幅:团队长 昵称 · N 人 · 日期
Row banner = sheet.createRow(0);
Cell bannerCell = banner.createCell(0);
String leaderShown = data.getLeaderNickname() != null && !data.getLeaderNickname().isEmpty()
? data.getLeaderNickname()
: (data.getTeamCode() == null ? "" : data.getTeamCode());
bannerCell.setCellValue(String.format("团队长 %s · %d 人 · %s",
leaderShown, data.getMemberCount(), data.getDate()));
CellStyle bannerStyle = wb.createCellStyle();
Font bannerFont = wb.createFont();
bannerFont.setBold(true);
bannerFont.setFontHeightInPoints((short) 14);
bannerStyle.setFont(bannerFont);
bannerStyle.setAlignment(HorizontalAlignment.CENTER);
bannerCell.setCellStyle(bannerStyle);
sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 8));
// 表头
String[] headers = {
"昵称",
data.getPreviousDate() + " 买单",
data.getDate() + " 卖单",
data.getDate() + " 买单",
"服务费*" + data.getServiceRate().toPlainString(),
"E积分",
"实际收付",
"团队",
"备注"
};
CellStyle headStyle = wb.createCellStyle();
Font headFont = wb.createFont();
headFont.setBold(true);
headStyle.setFont(headFont);
headStyle.setAlignment(HorizontalAlignment.CENTER);
headStyle.setFillForegroundColor(IndexedColors.LIGHT_GREEN.getIndex());
headStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
applyBorders(headStyle);
Row headRow = sheet.createRow(1);
for (int i = 0; i < headers.length; i++) {
Cell cell = headRow.createCell(i);
cell.setCellValue(headers[i]);
cell.setCellStyle(headStyle);
}
// 小计行(紧跟表头)
CellStyle summaryStyle = wb.createCellStyle();
Font summaryFont = wb.createFont();
summaryFont.setBold(true);
summaryFont.setColor(IndexedColors.RED.getIndex());
summaryStyle.setFont(summaryFont);
applyBorders(summaryStyle);
CellStyle moneyStyle = wb.createCellStyle();
moneyStyle.setDataFormat(wb.createDataFormat().getFormat("#,##0.00;-#,##0.00"));
applyBorders(moneyStyle);
CellStyle moneyBoldRedStyle = wb.createCellStyle();
moneyBoldRedStyle.cloneStyleFrom(moneyStyle);
moneyBoldRedStyle.setFont(summaryFont);
Row summaryRow = sheet.createRow(2);
TeamDailySummary s = data.getSummary();
summaryRow.createCell(0).setCellValue("小计");
summaryRow.getCell(0).setCellStyle(summaryStyle);
writeMoney(summaryRow, 1, s.getPrevBuy(), moneyBoldRedStyle);
writeMoney(summaryRow, 2, s.getTodaySell(), moneyBoldRedStyle);
writeMoney(summaryRow, 3, s.getTodayBuy(), moneyBoldRedStyle);
writeMoney(summaryRow, 4, s.getServiceFee(), moneyBoldRedStyle);
writeMoney(summaryRow, 5, s.getEScore(), moneyBoldRedStyle);
writeMoney(summaryRow, 6, s.getActual(), moneyBoldRedStyle);
summaryRow.createCell(7).setCellStyle(summaryStyle);
summaryRow.createCell(8).setCellStyle(summaryStyle);
// 数据行(团队列填团队长昵称)
int rowIdx = 3;
for (TeamDailyMemberRow r : data.getRows()) {
Row row = sheet.createRow(rowIdx++);
row.createCell(0).setCellValue(r.getNickname() == null ? "" : r.getNickname());
writeMoney(row, 1, r.getPrevBuy(), moneyStyle);
writeMoney(row, 2, r.getTodaySell(), moneyStyle);
writeMoney(row, 3, r.getTodayBuy(), moneyStyle);
writeMoney(row, 4, r.getServiceFee(), moneyStyle);
writeMoney(row, 5, r.getEScore(), moneyStyle);
writeMoney(row, 6, r.getActual(), moneyStyle);
row.createCell(7).setCellValue(leaderShown);
// 备注列保留空白(运营手填)
row.createCell(8).setCellValue("");
}
// 列宽
int[] widths = { 14, 14, 14, 14, 16, 12, 14, 8, 20 };
for (int i = 0; i < widths.length; i++) {
sheet.setColumnWidth(i, widths[i] * 256);
}
wb.write(out);
out.flush();
}
}
private void writeMoney(Row row, int col, BigDecimal value, CellStyle style) {
Cell cell = row.createCell(col);
cell.setCellValue(value == null ? 0d : value.doubleValue());
cell.setCellStyle(style);
}
private void applyBorders(CellStyle style) {
style.setBorderTop(BorderStyle.THIN);
style.setBorderBottom(BorderStyle.THIN);
style.setBorderLeft(BorderStyle.THIN);
style.setBorderRight(BorderStyle.THIN);
}
}

View File

@@ -19,9 +19,11 @@ import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zbkj.common.utils.CrmebDateUtil;
import com.zbkj.common.vo.DateLimitUtilVo;
import com.zbkj.common.model.consignment.WaSelfbonusLog;
import com.zbkj.common.model.user.User;
import com.zbkj.common.model.user.UserIntegralRecord;
import com.zbkj.service.dao.UserIntegralRecordDao;
import com.zbkj.service.dao.consignment.WaSelfbonusLogDao;
import com.zbkj.service.service.UserIntegralRecordService;
import com.zbkj.service.service.UserService;
import org.slf4j.Logger;
@@ -33,7 +35,9 @@ import org.springframework.transaction.support.TransactionTemplate;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -62,6 +66,9 @@ public class UserIntegralRecordServiceImpl extends ServiceImpl<UserIntegralRecor
@Autowired
private UserService userService;
@Autowired
private WaSelfbonusLogDao waSelfbonusLogDao;
@Autowired
private TransactionTemplate transactionTemplate;
@@ -155,7 +162,8 @@ public class UserIntegralRecordServiceImpl extends ServiceImpl<UserIntegralRecor
LambdaQueryWrapper<UserIntegralRecord> lqw = Wrappers.lambdaQuery();
lqw.select(UserIntegralRecord::getId, UserIntegralRecord::getTitle, UserIntegralRecord::getBalance, UserIntegralRecord::getIntegral,
UserIntegralRecord::getMark, UserIntegralRecord::getUid, UserIntegralRecord::getUpdateTime,
UserIntegralRecord::getType, UserIntegralRecord::getLinkType, UserIntegralRecord::getStatus, UserIntegralRecord::getCreateTime);
UserIntegralRecord::getType, UserIntegralRecord::getLinkType, UserIntegralRecord::getStatus, UserIntegralRecord::getCreateTime,
UserIntegralRecord::getWaSelfbonusLogid);
lqw.eq(UserIntegralRecord::getStatus, IntegralRecordConstants.INTEGRAL_RECORD_STATUS_COMPLETE);
String nameKey = StrUtil.isNotBlank(request.getNickName()) ? request.getNickName() : request.getKeywords();
@@ -213,9 +221,28 @@ public class UserIntegralRecordServiceImpl extends ServiceImpl<UserIntegralRecor
if (CollUtil.isEmpty(list)) {
return CommonPage.copyPageInfo(page, CollUtil.newArrayList());
}
List<Integer> selfBonusLogIds = list.stream()
.map(UserIntegralRecord::getWaSelfbonusLogid)
.filter(ObjectUtil::isNotNull)
.distinct()
.collect(Collectors.toList());
Map<Integer, BigDecimal> selfBonusIntegralMap = new HashMap<>();
if (CollUtil.isNotEmpty(selfBonusLogIds)) {
waSelfbonusLogDao.selectBatchIds(selfBonusLogIds).forEach(log -> {
if (ObjectUtil.isNotNull(log) && ObjectUtil.isNotNull(log.getMoney())) {
selfBonusIntegralMap.put(log.getId(), log.getMoney().multiply(new BigDecimal("0.5")).setScale(3, RoundingMode.DOWN));
}
});
}
List<UserIntegralRecordResponse> responseList = list.stream().map(i -> {
UserIntegralRecordResponse response = new UserIntegralRecordResponse();
BeanUtils.copyProperties(i, response);
if (ObjectUtil.isNotNull(i.getWaSelfbonusLogid())) {
BigDecimal convertedIntegral = selfBonusIntegralMap.get(i.getWaSelfbonusLogid());
if (ObjectUtil.isNotNull(convertedIntegral)) {
response.setIntegral(convertedIntegral);
}
}
// 获取用户昵称
User user = userService.getById(i.getUid());
if (ObjectUtil.isNotNull(user)) {

View File

@@ -142,6 +142,10 @@ public class UserServiceImpl extends ServiceImpl<UserDao, User> implements UserS
map.put("isPromoter", request.getIsPromoter() ? 1 : 0);
}
if (request.getUid() != null) {
map.put("uid", request.getUid());
}
if (StrUtil.isNotBlank(request.getGroupId())) {
List<Integer> groupIdList = CrmebUtil.stringToArray(request.getGroupId());
map.put("groupIdList", groupIdList);

View File

@@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zbkj.common.exception.CrmebException;
import com.zbkj.common.model.consignment.WaMerchandise;
import com.zbkj.common.model.consignment.WaOrder;
import com.zbkj.common.model.consignment.WaUsers;
import com.zbkj.common.page.CommonPage;
@@ -13,6 +14,7 @@ import com.zbkj.common.request.PageParamRequest;
import com.zbkj.common.request.WaOrderSearchRequest;
import com.zbkj.common.request.WaOrderUpdateRequest;
import com.zbkj.common.response.WaOrderResponse;
import com.zbkj.service.dao.consignment.WaMerchandiseDao;
import com.zbkj.service.dao.consignment.WaOrderDao;
import com.zbkj.service.dao.consignment.WaUsersDao;
import com.zbkj.service.service.WaOrderAdminService;
@@ -20,7 +22,11 @@ import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
/**
@@ -44,6 +50,9 @@ public class WaOrderAdminServiceImpl extends ServiceImpl<WaOrderDao, WaOrder> im
@Resource
private WaUsersDao waUsersDao;
@Resource
private WaMerchandiseDao waMerchandiseDao;
/**
* 分页列表查询
*/
@@ -108,31 +117,58 @@ public class WaOrderAdminServiceImpl extends ServiceImpl<WaOrderDao, WaOrder> im
wrapper.orderByDesc(WaOrder::getCreatedAt);
List<WaOrder> list = waOrderDao.selectList(wrapper);
// 批量收集所需关联 ID避免循环 N+1 查询
Set<Integer> userIds = new HashSet<>();
Set<Integer> merchandiseIds = new HashSet<>();
for (WaOrder o : list) {
if (o.getSellerId() != null && o.getSellerId() > 0) userIds.add(o.getSellerId());
if (o.getBuyerId() != null && o.getBuyerId() > 0) userIds.add(o.getBuyerId());
if (o.getMerchandiseId() != null && o.getMerchandiseId() > 0) merchandiseIds.add(o.getMerchandiseId());
}
Map<Integer, WaUsers> userMap = new HashMap<>();
if (!userIds.isEmpty()) {
for (WaUsers u : waUsersDao.selectBatchIds(userIds)) {
userMap.put(u.getId(), u);
}
}
Map<Integer, WaMerchandise> merchandiseMap = new HashMap<>();
if (!merchandiseIds.isEmpty()) {
for (WaMerchandise m : waMerchandiseDao.selectBatchIds(merchandiseIds)) {
merchandiseMap.put(m.getId(), m);
}
}
List<WaOrderResponse> responseList = list.stream().map(item -> {
WaOrderResponse response = new WaOrderResponse();
BeanUtils.copyProperties(item, response);
// 获取卖家名称
// 卖家名称
if (item.getSellerId() != null && item.getSellerId() > 0) {
WaUsers seller = waUsersDao.selectById(item.getSellerId());
if (seller != null) {
response.setSellerName(seller.getNickname());
}
WaUsers seller = userMap.get(item.getSellerId());
if (seller != null) response.setSellerName(seller.getNickname());
} else {
response.setSellerName("平台");
}
// 获取买家名称
// 买家名称
if (item.getBuyerId() != null && item.getBuyerId() > 0) {
WaUsers buyer = waUsersDao.selectById(item.getBuyerId());
if (buyer != null) {
response.setBuyerName(buyer.getNickname());
WaUsers buyer = userMap.get(item.getBuyerId());
if (buyer != null) response.setBuyerName(buyer.getNickname());
}
// 商品名称 / 图片
if (item.getMerchandiseId() != null && item.getMerchandiseId() > 0) {
WaMerchandise mh = merchandiseMap.get(item.getMerchandiseId());
if (mh != null) {
response.setMerchandiseTitle(mh.getTitle());
response.setMerchandiseImage(mh.getImage());
}
}
return response;
}).collect(Collectors.toList());
return CommonPage.copyPageInfo((PageInfo<WaOrder>) new PageInfo<>(list), responseList);
}
@@ -166,7 +202,16 @@ public class WaOrderAdminServiceImpl extends ServiceImpl<WaOrderDao, WaOrder> im
response.setBuyerName(buyer.getNickname());
}
}
// 商品名称 / 图片
if (order.getMerchandiseId() != null && order.getMerchandiseId() > 0) {
WaMerchandise mh = waMerchandiseDao.selectById(order.getMerchandiseId());
if (mh != null) {
response.setMerchandiseTitle(mh.getTitle());
response.setMerchandiseImage(mh.getImage());
}
}
return response;
}

View File

@@ -0,0 +1,48 @@
package com.zbkj.service.util;
import java.math.BigDecimal;
import java.math.RoundingMode;
/**
* 今日抢单用户列表 — 字段格式化工具。
* 抽出为单独类便于单元测试。
*/
public final class GrabUserFormatter {
public static final int AMOUNT_SCALE = 3;
private GrabUserFormatter() {}
/**
* 金额格式化:保留 3 位小数(与上传参考图一致)。
*/
public static String formatAmount(BigDecimal raw) {
BigDecimal v = raw == null ? BigDecimal.ZERO : raw;
return v.setScale(AMOUNT_SCALE, RoundingMode.HALF_UP).toPlainString();
}
/**
* 用户等级映射;未知等级回退为「普通用户」。
*/
public static String mapLevelName(Integer level) {
if (level == null) return "普通用户";
switch (level) {
case 0:
case 1:
return "普通用户";
case 2:
return "VIP";
case 3:
return "合伙人";
default:
return "等级" + level;
}
}
/**
* 状态文案1=正常 / 其它=禁用。
*/
public static String mapStatus(Integer status) {
return status != null && status == 1 ? "正常" : "禁用";
}
}

View File

@@ -0,0 +1,78 @@
package com.zbkj.service.util;
import com.zbkj.common.response.TeamDailyMemberRow;
import com.zbkj.common.response.TeamDailySummary;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
/**
* 团队每日对账日报 — 公式工具类。
* 设计要点:
* - 所有金额按 HALF_UP 舍入到 2 位;
* - 小计的服务费 / E积分 / 实际收付 由"成员级别已舍入数值"再求和,
* 避免逐行二次舍入。
*
* 抽出为单独类便于单元测试(无需 DB / Spring 上下文)。
*/
public final class TeamReportFormula {
public static final int SCALE = 2;
private TeamReportFormula() {}
/**
* 单成员金额舍入与公式计算。
* 修改入参对象的 prevBuy / todaySell / todayBuy / serviceFee / eScore / actual。
*
* @param row 成员行prevBuy / todaySell / todayBuy 已由 SQL 填充)
* @param serviceRate 服务费率
* @param eScoreRate E 积分率
*/
public static void applyFormula(TeamDailyMemberRow row,
BigDecimal serviceRate,
BigDecimal eScoreRate) {
if (row == null) return;
row.setPrevBuy(scale(row.getPrevBuy()));
row.setTodaySell(scale(row.getTodaySell()));
row.setTodayBuy(scale(row.getTodayBuy()));
BigDecimal serviceFee = scale(row.getTodayBuy().multiply(serviceRate));
BigDecimal eScore = scale(row.getTodayBuy().multiply(eScoreRate));
BigDecimal actual = scale(row.getTodaySell()
.subtract(row.getTodayBuy())
.subtract(serviceFee)
.subtract(eScore));
row.setServiceFee(serviceFee);
row.setEScore(eScore);
row.setActual(actual);
}
/**
* 累加每行已舍入数值得到小计;不再做二次舍入。
*/
public static TeamDailySummary aggregateSummary(List<TeamDailyMemberRow> rows) {
TeamDailySummary s = new TeamDailySummary();
if (rows == null) return s;
for (TeamDailyMemberRow r : rows) {
s.setPrevBuy(s.getPrevBuy().add(nz(r.getPrevBuy())));
s.setTodaySell(s.getTodaySell().add(nz(r.getTodaySell())));
s.setTodayBuy(s.getTodayBuy().add(nz(r.getTodayBuy())));
s.setServiceFee(s.getServiceFee().add(nz(r.getServiceFee())));
s.setEScore(s.getEScore().add(nz(r.getEScore())));
s.setActual(s.getActual().add(nz(r.getActual())));
}
return s;
}
public static BigDecimal scale(BigDecimal v) {
return v == null ? BigDecimal.ZERO.setScale(SCALE)
: v.setScale(SCALE, RoundingMode.HALF_UP);
}
private static BigDecimal nz(BigDecimal v) {
return v == null ? BigDecimal.ZERO : v;
}
}

View File

@@ -0,0 +1,93 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zbkj.service.dao.consignment.ExternalGrabUserDao">
<resultMap id="GrabUserResultMap" type="com.zbkj.common.response.ExternalGrabUserResponse">
<id property="id" column="id"/>
<result property="username" column="username"/>
<result property="nickname" column="nickname"/>
<result property="mobile" column="mobile"/>
<result property="contract" column="contract"/>
<result property="pid" column="pid"/>
<result property="maxOrder" column="max_order"/>
<result property="level" column="level"/>
<result property="status" column="status"/>
<result property="updatedAt" column="updated_at"/>
<result property="moneyRaw" column="money"/>
<result property="couponRaw" column="coupon"/>
<result property="selfBonusRaw" column="self_bonus"/>
<result property="shareBonusRaw" column="share_bonus"/>
<result property="todayBuyAmountRaw" column="today_buy_amount"/>
<result property="todaySellAmountRaw" column="today_sell_amount"/>
<result property="todayBuyCnt" column="today_buy_cnt"/>
<result property="prevSellCnt" column="prev_sell_cnt"/>
</resultMap>
<!--
SQL 设计要点:
1) INNER JOIN buy + HAVING SUM(total_money)>0 把"今日购买总金额>0"过滤直接落到 SQL 层;
2) LEFT JOIN sell / prev 不影响过滤结果集;
3) is_cancel=0 全程过滤已取消订单。
-->
<select id="selectGrabUserList" resultMap="GrabUserResultMap">
SELECT
u.id,
u.username,
u.nickname,
u.mobile,
u.contract,
u.pid,
u.max_order,
u.level,
u.money,
u.coupon,
u.self_bonus,
u.share_bonus,
u.status,
u.updated_at,
COALESCE(buy.amt, 0) AS today_buy_amount,
COALESCE(sell.amt, 0) AS today_sell_amount,
COALESCE(buy.cnt, 0) AS today_buy_cnt,
COALESCE(prev.cnt, 0) AS prev_sell_cnt
FROM wa_users u
INNER JOIN (
SELECT buyer_id AS uid, SUM(total_money) AS amt, COUNT(*) AS cnt
FROM wa_order
WHERE is_cancel = 0
AND pay_time &gt;= #{todayStart}
AND pay_time &lt;= #{todayEnd}
GROUP BY buyer_id
HAVING SUM(total_money) &gt; 0
) buy ON buy.uid = u.id
LEFT JOIN (
SELECT seller_id AS uid, SUM(total_money) AS amt
FROM wa_order
WHERE is_cancel = 0
AND pay_time &gt;= #{todayStart}
AND pay_time &lt;= #{todayEnd}
GROUP BY seller_id
) sell ON sell.uid = u.id
LEFT JOIN (
SELECT seller_id AS uid, COUNT(*) AS cnt
FROM wa_order
WHERE is_cancel = 0
AND pay_time &gt;= #{yesterdayStart}
AND pay_time &lt;= #{yesterdayEnd}
GROUP BY seller_id
) prev ON prev.uid = u.id
<where>
<if test="uid != null">
AND u.id = #{uid}
</if>
<if test="mobile != null and mobile != ''">
AND (u.mobile LIKE CONCAT('%', #{mobile}, '%')
OR u.username LIKE CONCAT('%', #{mobile}, '%'))
</if>
<if test="pid != null">
AND u.pid = #{pid}
</if>
</where>
ORDER BY today_buy_amount DESC, u.id DESC
</select>
</mapper>

View File

@@ -0,0 +1,85 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zbkj.service.dao.consignment.TeamReportDao">
<resultMap id="MemberAggregateResultMap" type="com.zbkj.common.response.TeamDailyMemberRow">
<id property="userId" column="user_id"/>
<result property="nickname" column="nickname"/>
<result property="teamCode" column="team_code"/>
<result property="status" column="status"/>
<result property="leaderId" column="leader_id"/>
<result property="prevBuy" column="prev_buy"/>
<result property="todaySell" column="today_sell"/>
<result property="todayBuy" column="today_buy"/>
</resultMap>
<!--
SQL 设计:
- 一次三 LEFT JOIN 聚合prev / sell / buy
- WHERE u.pid = leaderId 限定团队成员(直推下级)
- includeDisabled=false 时仅取 status=1
- memberIds 非空时再二次过滤
-->
<!--
team-report 聚合查询:
- leaderId 非空仅查该团队长的下级u.pid = leaderId
- leaderId 为空查所有有上级的成员u.pid > 0后续在 Service 按 leader_id 分组
-->
<select id="selectTeamMemberAggregates" resultMap="MemberAggregateResultMap">
SELECT
u.id AS user_id,
u.nickname AS nickname,
u.invite AS team_code,
u.status AS status,
u.pid AS leader_id,
COALESCE(prev.amt, 0) AS prev_buy,
COALESCE(sell.amt, 0) AS today_sell,
COALESCE(buy.amt, 0) AS today_buy
FROM wa_users u
LEFT JOIN (
SELECT buyer_id AS uid, SUM(total_money) AS amt
FROM wa_order
WHERE is_cancel = 0
AND pay_time &gt;= #{prevStart}
AND pay_time &lt;= #{prevEnd}
GROUP BY buyer_id
) prev ON prev.uid = u.id
LEFT JOIN (
SELECT seller_id AS uid, SUM(total_money) AS amt
FROM wa_order
WHERE is_cancel = 0
AND pay_time &gt;= #{dStart}
AND pay_time &lt;= #{dEnd}
GROUP BY seller_id
) sell ON sell.uid = u.id
LEFT JOIN (
SELECT buyer_id AS uid, SUM(total_money) AS amt
FROM wa_order
WHERE is_cancel = 0
AND pay_time &gt;= #{dStart}
AND pay_time &lt;= #{dEnd}
GROUP BY buyer_id
) buy ON buy.uid = u.id
<where>
<choose>
<when test="leaderId != null">
u.pid = #{leaderId}
</when>
<otherwise>
u.pid &gt; 0
</otherwise>
</choose>
<if test="includeDisabled == null or !includeDisabled">
AND u.status = 1
</if>
<if test="memberIds != null and memberIds.size() > 0">
AND u.id IN
<foreach collection="memberIds" item="mid" open="(" separator="," close=")">
#{mid}
</foreach>
</if>
</where>
ORDER BY u.pid ASC, u.id ASC
</select>
</mapper>

View File

@@ -29,6 +29,9 @@
<if test="isPromoter != null and isPromoter !='' or isPromoter == 0 ">
and u.is_promoter = #{isPromoter}
</if>
<if test="uid != null">
and u.uid = #{uid}
</if>
<if test="groupId != null and groupId !='' ">
and u.group_id in
<foreach item="group_id" collection="groupIdList" open="(" separator="," close=")">

View File

@@ -0,0 +1,63 @@
package com.zbkj.service.util;
import org.junit.Test;
import java.math.BigDecimal;
import static org.junit.Assert.assertEquals;
/**
* 今日抢单用户列表 - 格式化工具单元测试。
*/
public class GrabUserFormatterTest {
@Test
public void formatAmount_null_should_be_zero() {
assertEquals("0.000", GrabUserFormatter.formatAmount(null));
}
@Test
public void formatAmount_should_keep_three_decimals() {
assertEquals("0.000", GrabUserFormatter.formatAmount(new BigDecimal("0")));
assertEquals("226.383", GrabUserFormatter.formatAmount(new BigDecimal("226.383")));
assertEquals("100.000", GrabUserFormatter.formatAmount(new BigDecimal("100")));
}
@Test
public void formatAmount_should_round_half_up() {
// 0.0005 → 0.001
assertEquals("0.001", GrabUserFormatter.formatAmount(new BigDecimal("0.0005")));
// 0.0014 → 0.001
assertEquals("0.001", GrabUserFormatter.formatAmount(new BigDecimal("0.0014")));
// 0.0015 → 0.002
assertEquals("0.002", GrabUserFormatter.formatAmount(new BigDecimal("0.0015")));
}
@Test
public void formatAmount_should_handle_negative() {
assertEquals("-1.234", GrabUserFormatter.formatAmount(new BigDecimal("-1.2340")));
}
@Test
public void mapLevelName_known_levels() {
assertEquals("普通用户", GrabUserFormatter.mapLevelName(null));
assertEquals("普通用户", GrabUserFormatter.mapLevelName(0));
assertEquals("普通用户", GrabUserFormatter.mapLevelName(1));
assertEquals("VIP", GrabUserFormatter.mapLevelName(2));
assertEquals("合伙人", GrabUserFormatter.mapLevelName(3));
}
@Test
public void mapLevelName_unknown_levels_fallback() {
assertEquals("等级5", GrabUserFormatter.mapLevelName(5));
assertEquals("等级99", GrabUserFormatter.mapLevelName(99));
}
@Test
public void mapStatus_should_match_spec() {
assertEquals("正常", GrabUserFormatter.mapStatus(1));
assertEquals("禁用", GrabUserFormatter.mapStatus(0));
assertEquals("禁用", GrabUserFormatter.mapStatus(null));
assertEquals("禁用", GrabUserFormatter.mapStatus(2));
}
}

View File

@@ -0,0 +1,155 @@
package com.zbkj.service.util;
import com.zbkj.common.response.TeamDailyMemberRow;
import com.zbkj.common.response.TeamDailySummary;
import org.junit.Test;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
/**
* 团队每日对账日报 公式工具单元测试。
* 覆盖:
* - 上传参考图样例 4 名成员(王珍华 / 柯美燕 / 王兵启 / 胡晓彩)
* - 仅有卖单 / 仅有买单 / 全空 等边界
* - 小计精度:与逐行二次舍入对比
*/
public class TeamReportFormulaTest {
private static final BigDecimal SERVICE_RATE = new BigDecimal("0.02");
private static final BigDecimal E_SCORE_RATE = new BigDecimal("0.005");
/** 王珍华22151 - 21418 - 428.36 - 107.09 = 197.55 */
@Test
public void member_with_buy_and_sell_should_match_doc() {
TeamDailyMemberRow r = new TeamDailyMemberRow()
.setNickname("王珍华")
.setPrevBuy(new BigDecimal("21506"))
.setTodaySell(new BigDecimal("22151"))
.setTodayBuy(new BigDecimal("21418"));
TeamReportFormula.applyFormula(r, SERVICE_RATE, E_SCORE_RATE);
assertEquals(new BigDecimal("428.36"), r.getServiceFee());
assertEquals(new BigDecimal("107.09"), r.getEScore());
assertEquals(new BigDecimal("197.55"), r.getActual());
}
/** 胡晓彩28259 - 27708 - 554.16 - 138.54 = -141.70 */
@Test
public void member_with_negative_actual() {
TeamDailyMemberRow r = new TeamDailyMemberRow()
.setNickname("胡晓彩")
.setPrevBuy(new BigDecimal("27436"))
.setTodaySell(new BigDecimal("28259"))
.setTodayBuy(new BigDecimal("27708"));
TeamReportFormula.applyFormula(r, SERVICE_RATE, E_SCORE_RATE);
assertEquals(new BigDecimal("554.16"), r.getServiceFee());
assertEquals(new BigDecimal("138.54"), r.getEScore());
assertEquals(new BigDecimal("-141.70"), r.getActual());
}
/** 柯美燕 / 王兵启:仅有卖单。服务费/E积分=0实际=卖单。 */
@Test
public void member_only_sell_should_zero_fees() {
TeamDailyMemberRow r = new TeamDailyMemberRow()
.setNickname("柯美燕")
.setPrevBuy(new BigDecimal("22519"))
.setTodaySell(new BigDecimal("23195"))
.setTodayBuy(BigDecimal.ZERO);
TeamReportFormula.applyFormula(r, SERVICE_RATE, E_SCORE_RATE);
assertEquals(new BigDecimal("0.00"), r.getServiceFee());
assertEquals(new BigDecimal("0.00"), r.getEScore());
assertEquals(new BigDecimal("23195.00"), r.getActual());
}
/** 仅有买单:实际收付为负值(-买 - 服务费 - E积分。 */
@Test
public void member_only_buy_should_negative_actual() {
TeamDailyMemberRow r = new TeamDailyMemberRow()
.setTodaySell(BigDecimal.ZERO)
.setTodayBuy(new BigDecimal("1000"));
TeamReportFormula.applyFormula(r, SERVICE_RATE, E_SCORE_RATE);
assertEquals(new BigDecimal("20.00"), r.getServiceFee());
assertEquals(new BigDecimal("5.00"), r.getEScore());
assertEquals(new BigDecimal("-1025.00"), r.getActual());
}
/** Null 字段:当作 0 处理,不抛异常。 */
@Test
public void member_with_null_amounts_should_be_zero() {
TeamDailyMemberRow r = new TeamDailyMemberRow();
TeamReportFormula.applyFormula(r, SERVICE_RATE, E_SCORE_RATE);
assertEquals(new BigDecimal("0.00"), r.getPrevBuy());
assertEquals(new BigDecimal("0.00"), r.getTodaySell());
assertEquals(new BigDecimal("0.00"), r.getTodayBuy());
assertEquals(new BigDecimal("0.00"), r.getServiceFee());
assertEquals(new BigDecimal("0.00"), r.getEScore());
assertEquals(new BigDecimal("0.00"), r.getActual());
}
/** 小计4 名成员全量样例对账。 */
@Test
public void summary_should_match_doc_team_F_sample() {
List<TeamDailyMemberRow> rows = Arrays.asList(
row("王珍华", "21506", "22151", "21418"),
row("柯美燕", "22519", "23195", "0"),
row("王兵启", "34266", "35294", "0"),
row("胡晓彩", "27436", "28259", "27708")
);
rows.forEach(r -> TeamReportFormula.applyFormula(r, SERVICE_RATE, E_SCORE_RATE));
TeamDailySummary s = TeamReportFormula.aggregateSummary(rows);
// 文档样例核对D-1 买单合计 = 105727
assertEquals(new BigDecimal("105727.00"), s.getPrevBuy());
// D 卖单合计 = 108899
assertEquals(new BigDecimal("108899.00"), s.getTodaySell());
// D 买单合计 = 49126
assertEquals(new BigDecimal("49126.00"), s.getTodayBuy());
// 服务费合计428.36 + 0 + 0 + 554.16 = 982.52
assertEquals(new BigDecimal("982.52"), s.getServiceFee());
// E积分合计107.09 + 0 + 0 + 138.54 = 245.63
assertEquals(new BigDecimal("245.63"), s.getEScore());
// 实际收付合计197.55 + 23195 + 35294 + (-141.70) = 58544.85
assertEquals(new BigDecimal("58544.85"), s.getActual());
}
/** 空成员列表:小计全 0不抛异常。 */
@Test
public void summary_empty_rows_should_zero() {
TeamDailySummary s = TeamReportFormula.aggregateSummary(Collections.emptyList());
assertNotNull(s);
assertEquals(BigDecimal.ZERO, s.getPrevBuy());
assertEquals(BigDecimal.ZERO, s.getTodayBuy());
assertEquals(BigDecimal.ZERO, s.getActual());
}
/** 不同费率service_rate=0.03 / e_score_rate=0.01。 */
@Test
public void custom_rates_should_be_applied() {
TeamDailyMemberRow r = new TeamDailyMemberRow()
.setTodaySell(new BigDecimal("0"))
.setTodayBuy(new BigDecimal("1000"));
TeamReportFormula.applyFormula(r, new BigDecimal("0.03"), new BigDecimal("0.01"));
assertEquals(new BigDecimal("30.00"), r.getServiceFee());
assertEquals(new BigDecimal("10.00"), r.getEScore());
assertEquals(new BigDecimal("-1040.00"), r.getActual());
}
private static TeamDailyMemberRow row(String name, String prev, String sell, String buy) {
return new TeamDailyMemberRow()
.setNickname(name)
.setPrevBuy(new BigDecimal(prev))
.setTodaySell(new BigDecimal(sell))
.setTodayBuy(new BigDecimal(buy));
}
}

View File

@@ -0,0 +1,55 @@
# 公司名称:夏盛军商贸
## mysql数据库配置信息
host ip: 39.106.63.33
datasource:
name: yangtangyoupin
username: yangtangyoupin
password: 5Fn8eWrbYFtAhCZw
## 数据删除任务
- 用户数据范围暨**用户id集**wa_users表中的用户id集
- 查询wa_withdraw表中用户id不在用户数据范围内的记录并写一个删除这些数据的sql
### 1) 查询核对 SQL
```sql
-- 统计孤立提现记录数
SELECT COUNT(*) AS orphan_cnt
FROM wa_withdraw w
WHERE NOT EXISTS (
SELECT 1 FROM wa_users u WHERE u.id = w.user_id
);
-- 抽样查看前 100 条,核对是否确实需要清理
SELECT w.*
FROM wa_withdraw w
WHERE NOT EXISTS (
SELECT 1 FROM wa_users u WHERE u.id = w.user_id
)
ORDER BY w.id
LIMIT 100;
```
### 2) 删除 SQL
```sql
DELETE w FROM wa_withdraw w
WHERE NOT EXISTS (
SELECT 1 FROM wa_users u WHERE u.id = w.user_id
);
```
### 3) 操作备注
- 建议在执行前对 wa_withdraw 做一次备份:`CREATE TABLE wa_withdraw_bak_20260423 AS SELECT * FROM wa_withdraw;`
- 建议先跑 `COUNT(*)``LIMIT 100` 人工核对,再执行 `DELETE`
- 全程放入事务中执行,确认无误后再 `COMMIT`
## 相关文件

View File

@@ -0,0 +1,51 @@
# 公司名称:池州瑞棠商贸
## mysql数据库配置信息
host ip: 101.37.101.6
datasource:
name: yangtangyoupin
username: yangtangyoupin
password: 5Fn8eWrbYFtAhCZw
## 数据清理任务
- **数据范围**:用户 id 集(`eb_user.uid``wa_users.id` 一致92738,92827,92861,92909,93090,93140,93150,93157,93175,93194,93201,93210,93211,93212,93219,93220
- wa_users表中id在用户id数据范围的
- eb_user表中uid在用户id数据范围的
- wa_order
- wa_merchandise
- wa_selfbonus_log
- wa_sharebonus_log
- wa_coupon_log
- wa_withdraw
- eb_store_order
- eb_user_integral_record
## 执行脚本
## 相关文件
- 源数据dump文件

View File

@@ -0,0 +1,61 @@
# 公司名称:池州瑞棠商贸
## mysql数据库配置信息
host ip: 101.37.101.6
datasource:
name: yangtangyoupin
username: yangtangyoupin
password: 5Fn8eWrbYFtAhCZw
---
## 数据迁移任务
- **用户id数据范围**92827, 92738, 93140, 93150
- 提取wa_users表中id在用户id数据范围的记录
- 提取eb_user表中uid在用户id数据范围的记录
- wa_merchandise
提取“created_at >= 2026-04-16”并且user_id在用户id数据范围的状态为”未售“的寄售商品删除其余数据
(当前库表字段为 `user_id` 表示卖家,实现时按 `user_id` 与日期、状态`status`=1的条件过滤。
- wa_selfbonus_log
提取 `user_id` 在用户id数据范围内的记录
- wa_sharebonus_log
提取 `user_id` 在用户id数据范围内的记录
- wa_coupon_log
提取 `user_id` 在用户id数据范围内的记录
- eb_user_integral_record
提取用户在数据范围内的记录;表字段为 `uid`(与 `wa_users.id` / `eb_user.uid` 对应),实现按 `uid` 过滤。
---
## 批量 INSERT SQL从 dump 生成)
- 生成文件:`docs/sql/com-czrt6-data-imgration-2_inserts.sql`(含 `SET NAMES utf8mb4;` 及各表 `INSERT`,按依赖顺序:`wa_users``eb_user` → …)。
- 重新生成:`python3 docs/sql/generate_com_czrt6_data_imgration_2_inserts.py [可选: dump.sql路径]`(默认使用下文 dump 路径)。
- **主键/外键**:导入前请备份;若目标库已有相同主键需先处理或改用 `REPLACE` / 调整自增。
- **wa_merchandise**:当前 dump 中满足日期与 `user_id` 的记录均为 **已售status=0**,按文档「未售 status=1」筛选为 **0 行**SQL 中该段仅有说明注释。
## 在目标库执行迁移
```bash
export CZRT6_DB_PASSWORD='(见上文 datasource.password'
python3 docs/sql/run_com_czrt6_data_imgration_2.py
```
- 默认连接:`101.37.101.6` / `yangtangyoupin`(可用 `CZRT6_DB_HOST` 等覆盖)。
- 脚本会 `SET FOREIGN_KEY_CHECKS=0`,按 INSERT 中出现的 **主键** 先删后插(避免他人占用同 `id` 导致冲突),再执行 `com-czrt6-data-imgration-2_inserts.sql` 中全部 `INSERT`
- **已于 2026-04-26 执行成功**`wa_users`/`eb_user` 各 4 行;`wa_selfbonus_log` 142`wa_sharebonus_log` 343`wa_coupon_log` 40`eb_user_integral_record` 174`wa_merchandise` 无 INSERT。
## 相关文件
- 提取数据源 dump`docs/czcf82-yangtangyoupin_2026-04-26_10-25-02_mysql_data.sql`
- 生成 INSERT`docs/sql/generate_com_czrt6_data_imgration_2_inserts.py``docs/sql/com-czrt6-data-imgration-2_inserts.sql`
- 在目标库执行:`docs/sql/run_com_czrt6_data_imgration_2.py`

View File

@@ -0,0 +1,66 @@
# 公司名称:太原树英商贸
## mysql数据库配置信息
host ip: 106.14.132.80
datasource:
name: yangtangyoupin
username: yangtangyoupin
password: 5Fn8eWrbYFtAhCZw
## 数据清理任务
- **数据范围**:用户 id 集(`wa_users`
`92566,92801,92839,93004,92637,92965,93093,93096,93116,92787,93121,93129,92884,93007,93020,93094,93099,93110,92638`
- 保留wa_users表中id在用户id数据范围的 ,删除其余用户数据
- 保留eb_user表中uid在用户id数据范围的 ,删除其余用户数据
- wa_order
清空wa_order表中数据
- wa_merchandise
从源数据dump文件中提取“created_at >= 2026-04-22”并且seller_id或buyer_id在用户id数据范围的寄售商品删除其余数据
(当前库表字段为 `user_id` 表示卖家,实现时按 `user_id` 与日期条件过滤。)
- wa_selfbonus_log
只保留 `user_id` 在用户id数据范围内的记录删除其余数据
- wa_sharebonus_log
只保留 `user_id` 在用户id数据范围内的记录删除其余数据
- wa_coupon_log
只保留 `user_id` 在用户id数据范围内的记录删除其余数据
- wa_withdraw
清空wa_withdraw表中数据
- eb_store_order
清空eb_store_order表中数据
- eb_user_integral_record
只保留用户在名单内的记录;表字段为 `uid`(与 `wa_users.id` / `eb_user.uid` 对应),实现按 `uid` 过滤。
## 执行脚本
- **`wa_merchandise` 批量 INSERT从 dump 筛条件后生成)**
- 生成结果:`docs/sql/wa_merchandise_insert_from_dump_sxsy80.sql`(当前 **18** 行,与 dump 中 `INSERT INTO wa_merchandise` 一致)。
- 重新生成:`python3 docs/sql/generate_wa_merchandise_insert_from_dump.py /path/to/ccd-yangtangyoupin_*.sql`(不传参时默认使用仓库上级 `integral-shop/db/ccd-yangtangyoupin_2026-04-26_10-25-01_mysql_data.sql`)。
- 导入前注意主键冲突:若目标库已有相同 `id`,需先删改或改用 `REPLACE INTO` / 调整自增策略。
- SQL`docs/sql/com-sxsy80-data-cleanup.sql`
- 本机 Homebrew `mysql` 9 客户端不支持 `mysql_native_password`,可用 `pip install pymysql` 后执行:
```bash
export YTYP_DB_PASSWORD='(见上文 datasource.password'
python3 docs/sql/run_com_sxsy80_cleanup.py
```
- 已于 **2026-04-26** 对远程库执行并成功 `COMMIT`(首轮:`wa_merchandise` 按 2026-04-24 条件删除 2114 行;`wa_selfbonus_log` 1592`wa_sharebonus_log` 1399`wa_coupon_log` 171`eb_user_integral_record` 1613`eb_user` 80`wa_users` 80`wa_order` / `wa_withdraw` / `eb_store_order``TRUNCATE`)。
- **2026-04-26 二次**:按文档将 `wa_merchandise` 日期阈值改为 **2026-04-22** 重新执行(见 `docs/sql/com-sxsy80-wa_merchandise-only.sql`),仅影响该表;**删除 0 行**(上轮已按 04-24 清理,现存行均满足「>= 04-22 且卖家在名单」;若 04-2204-23 且卖家在名单的数据曾被误删,需从备份恢复库后再用 04-22 规则全量重跑)。
- **2026-04-26 三次**:按「从源 dump 提取」规则:从 `ccd-yangtangyoupin_2026-04-26_10-25-01_mysql_data.sql` 解析 `created_at >= 2026-04-22``user_id` 在名单内的 **18**`id`,执行 `DELETE ... WHERE id NOT IN (...)`;保留 id 列表见 `docs/sql/wa_merchandise_keep_ids_from_dump_sxsy80.txt`。**删除 0 行**(当前库中 `wa_merchandise` 已仅含上述 id 子集,与 dump 规则一致)。
## 相关文件
- 源数据dump文件 'integral-shop/db/ccd-yangtangyoupin_2026-04-26_10-25-01_mysql_data.sql'

50
docs/com-sxsy80.md Normal file
View File

@@ -0,0 +1,50 @@
## 公司名称: 太原树英商贸, host ip: 106.14.132.80
---
### backend/crmeb-front模块变更
- 1. profile: sxsy80
- 2. profile file: application-sxsy80.yml, mysql和redis主机ip修改
- 3. **PDF合同模板文件路径**pdf/sign_contract_sxsy80.pdf
- 4. 用户PDF合同url地址前缀/落库域名https://sxsy.cichude.com/
- 5. imagePath: /www/wwwroot/sxsy.cichude.com/
### uniapp前端配置变更
- 1. 积分商城domainhttps://sxsy-jf.cichude.com
- 2. 抢购页面跳转地址https://sxsy.cichude.com
- 3. **PDF合同预览文件路径** /static/sign_contract_sxsy80.pdf
---
### backend/crmeb-admin模块变更
- 1. profile: sxsy80
- 2. profile file: application-sxsy80.yml, mysql和redis主机ip修改sync: source-id: shop_14 target-mer-id: 14
### 积分商城后台backend-adminend配置变更
- 1. backend-adminend/.env.development文件中VUE_APP_BASE_API改为https://sxsy-jf.cichude.com
- 2. backend-adminend/.env.production文件中VUE_APP_BASE_API改为https://sxsy-jf.cichude.com
---
### **修改任务**
- 新建分支sxsy80合并czcf82分支的最新代码到该分支并根据上述信息修改相关需要变更项使符合该新公司项目环境
## 相关文件
、、、启动积分商城api服务
cd /www/wwwroot/javaapi
nohup java -Xms128m -Xmx256m -jar miao-front-2.2.jar > front.log & tail -f front.log
、、、
、、、启动积分商城后台api服务
cd /www/wwwroot/javaapi
nohup java -Xms128m -Xmx256m -jar miao-admin-2.2.jar > admin.log & tail -f admin.log
、、、

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,737 @@
-- 池州瑞棠商贸 / com-czrt6-data-imgration-2.md
-- 源 dump: czcf82-yangtangyoupin_2026-04-26_10-25-02_mysql_data.sql
-- 用户范围: [92738, 92827, 93140, 93150]
-- wa_merchandise: created_at >= 2026-04-16 且 user_id 在范围且 status=1未售
-- 执行前请备份;注意外键与主键冲突,按需调整顺序或使用 SET FOREIGN_KEY_CHECKS=0
SET NAMES utf8mb4;
-- ---------- `wa_users` (4 rows) ----------
INSERT INTO `wa_users` VALUES
(92738,93104,'17756627812','胡晓彩','17756627812','9e13831c1275043d00fb5dde39f28d3b','LJvXO2','1','/app/admin/avatar.png','bdu4ra',1,NULL,0.000,1544.000,17113.588,4792.613,0,'2026-04-24 09:23:27','114.103.38.148','2025-11-13 14:41:43','36.61.252.77',NULL,'2025-11-13 14:41:43','2026-04-24 09:23:27',1,NULL,0,'https://czcf.uj345.com/crmebimage/public/user/2026/04/18/e3c0ff944f944a9cbe580fd88fdd1d7be1itbd9eh5.pdf',0,1,NULL,NULL),
(92827,92738,'18956691177','王兵启','18956691177','c742a1d8995ebadbef7016b6f83ffbfa','IuqYhH','1','/app/admin/avatar.png','yijeac',1,NULL,0.000,2376.000,13563.808,6626.224,0,'2026-04-23 12:06:03','112.122.255.122','2025-12-04 19:13:00','220.205.249.43',NULL,'2025-12-04 19:13:00','2026-04-23 12:06:03',1,NULL,0,'https://czcf.uj345.com/crmebimage/public/user/2026/04/18/a0b565773c2d45d39256e1e8c2992450j4w7frgpns.pdf',0,1,NULL,NULL),
(93140,92827,'13635661721','柯美燕','13635661721','ac3ed6421b3b7ca72c57a8c2b6ebebb1','IG9j6q','1','/app/admin/avatar.png','t1tdj8',1,NULL,0.000,0.000,4787.975,0.000,0,'2026-04-23 12:07:23','112.122.255.122','2026-03-23 14:10:31','36.161.161.145',NULL,'2026-03-23 14:10:31','2026-04-23 12:07:23',1,NULL,0,'https://czcf.uj345.com/crmebimage/public/user/2026/04/18/963f7f7b6a294351a20244a706f7b4eb4gorcbhsg3.pdf',0,1,NULL,NULL),
(93150,92738,'13856372733','王珍华','13856372733','be2c21121092d4175b227e1403719b7a','Jr0FNi','1','/app/admin/avatar.png','knadzl',1,NULL,0.000,0.000,4168.197,0.000,0,'2026-04-24 09:38:53','36.161.140.102','2026-03-26 09:13:07','142.171.243.42',NULL,'2026-03-26 09:13:07','2026-04-24 09:38:53',1,NULL,0,'https://czcf.uj345.com/crmebimage/public/user/2026/04/18/748a78ed247b42519b249344c0d3ce4bef7cxiyacx.pdf',0,1,NULL,NULL);
-- ---------- `eb_user` (4 rows) ----------
INSERT INTO `eb_user` VALUES
(92738,'17756627812','5c4ef5c98420f21c3c6ddf62c8d9e0a9','','','','',NULL,'','','胡晓彩','/app/admin/avatar.png','17756627812','36.61.252.77','114.103.36.38',0.00,0.00,927.778,0,0,1,1,92544,'2026-02-16 01:30:28','H5',0,15,0,'',0,'h5','2025-11-13 06:41:43','2026-04-22 02:02:01','2026-04-25 08:08:06',NULL,'/0/',0,NULL,1,'CN',NULL),
(92827,'18956691177','c742a1d8995ebadbef7016b6f83ffbfa','','','','',NULL,'','','王兵启','/app/admin/avatar.png','18956691177','220.205.249.43','220.205.248.11',0.00,0.00,572.957,0,0,1,1,92738,'2026-02-16 01:30:28','H5',0,12,0,'',0,'h5','2025-12-04 11:13:00','2026-04-21 02:11:01','2026-04-23 04:06:51',NULL,'/0/',0,NULL,1,'CN',NULL),
(93140,'13635661721','ac3ed6421b3b7ca72c57a8c2b6ebebb1','','','','',NULL,'','','柯美燕','/app/admin/avatar.png','13635661721','36.161.161.145','36.161.161.145',0.00,0.00,13.982,0,0,1,1,92827,'2026-03-23 06:20:01','H5',0,3,0,'',0,'h5','2026-03-23 06:10:31','2026-04-21 11:06:17','2026-04-23 04:07:51',NULL,'/0/',0,NULL,1,'CN',NULL),
(93150,'13856372733','be2c21121092d4175b227e1403719b7a','','','','',NULL,'','','138****2733','/app/admin/avatar.png','13856372733','142.171.243.42','142.171.243.42',0.00,0.00,2084.094,0,0,1,1,92738,'2026-03-26 01:20:01','H5',0,0,0,'',0,'h5','2026-03-26 01:13:07','2026-04-22 02:58:01','2026-04-24 03:39:27',NULL,'/0/',0,NULL,1,'CN',NULL);
-- ---------- `wa_merchandise` (0 rows) ----------
-- 无匹配行dump 中满足「日期 + user_id 在范围」的寄售商品均为 status=0已售
-- 若业务上「未售」应对应其它字段,请改脚本 filter 后重新 python3 本脚本。
-- ---------- `wa_selfbonus_log` (142 rows) ----------
INSERT INTO `wa_selfbonus_log` VALUES
(33,92738,1,276.300,0.000,276.300,'今日收益','2026-02-19 10:22:17','2026-02-19 10:22:17'),
(36,92827,1,320.877,0.000,320.877,'今日收益','2026-02-19 10:27:47','2026-02-19 10:27:47'),
(88,92738,1,237.557,276.300,513.857,'今日收益','2026-02-20 10:21:47','2026-02-20 10:21:47'),
(97,92827,1,301.248,320.877,622.125,'今日收益','2026-02-20 11:06:44','2026-02-20 11:06:44'),
(133,92738,1,244.684,513.857,758.541,'今日收益','2026-02-23 10:00:26','2026-02-23 10:00:26'),
(142,92827,1,340.418,622.125,962.543,'今日收益','2026-02-23 10:01:35','2026-02-23 10:01:35'),
(207,92738,1,251.543,758.541,1010.084,'今日收益','2026-02-24 10:04:13','2026-02-24 10:04:13'),
(246,92827,1,316.764,962.543,1279.307,'今日收益','2026-02-24 14:59:48','2026-02-24 14:59:48'),
(283,92738,1,253.466,1010.084,1263.550,'今日收益','2026-02-25 10:14:34','2026-02-25 10:14:34'),
(291,92827,1,283.955,1279.307,1563.262,'今日收益','2026-02-25 11:20:10','2026-02-25 11:20:10'),
(316,92738,1,354.843,1263.550,1618.393,'今日收益','2026-02-26 10:01:21','2026-02-26 10:01:21'),
(361,92827,1,267.899,1563.262,1831.161,'今日收益','2026-02-26 12:51:45','2026-02-26 12:51:45'),
(399,92738,1,238.889,1618.393,1857.282,'今日收益','2026-02-27 10:04:50','2026-02-27 10:04:50'),
(403,92827,1,296.815,1831.161,2127.976,'今日收益','2026-02-27 10:05:33','2026-02-27 10:05:33'),
(446,92827,1,287.673,2127.976,2415.649,'今日收益','2026-03-02 10:01:29','2026-03-02 10:01:29'),
(493,92738,1,253.048,1857.282,2110.330,'今日收益','2026-03-02 14:57:17','2026-03-02 14:57:17'),
(525,92827,1,294.994,2415.649,2710.643,'今日收益','2026-03-03 10:10:35','2026-03-03 10:10:35'),
(554,92738,1,261.969,2110.330,2372.299,'今日收益','2026-03-03 13:53:59','2026-03-03 13:53:59'),
(602,92738,1,300.355,2372.299,2672.654,'今日收益','2026-03-04 10:05:17','2026-03-04 10:05:17'),
(611,92827,1,323.003,2710.643,3033.646,'今日收益','2026-03-04 12:45:31','2026-03-04 12:45:31'),
(647,92827,1,313.586,3033.646,3347.232,'今日收益','2026-03-05 10:02:50','2026-03-05 10:02:50'),
(648,92738,1,312.959,2672.654,2985.613,'今日收益','2026-03-05 10:02:58','2026-03-05 10:02:58'),
(701,92738,1,288.050,2985.613,3273.663,'今日收益','2026-03-06 10:01:16','2026-03-06 10:01:16'),
(703,92827,1,285.559,3347.232,3632.791,'今日收益','2026-03-06 10:01:42','2026-03-06 10:01:42'),
(765,92827,1,300.552,3632.791,3933.343,'今日收益','2026-03-09 10:01:43','2026-03-09 10:01:43'),
(767,92738,1,319.257,3273.663,3592.920,'今日收益','2026-03-09 10:02:06','2026-03-09 10:02:06'),
(854,92738,1,316.367,3592.920,3909.287,'今日收益','2026-03-10 10:18:58','2026-03-10 10:18:58'),
(891,92827,1,308.000,3933.343,4241.343,'今日收益','2026-03-10 15:41:35','2026-03-10 15:41:35'),
(914,92738,1,353.801,3909.287,4263.088,'今日收益','2026-03-11 10:03:58','2026-03-11 10:03:58'),
(927,92827,1,312.289,4241.343,4553.632,'今日收益','2026-03-11 10:07:28','2026-03-11 10:07:28'),
(1005,92738,1,359.326,4263.088,4622.414,'今日收益','2026-03-12 12:15:59','2026-03-12 12:15:59'),
(1034,92827,1,370.834,4553.632,4924.466,'今日收益','2026-03-13 10:01:39','2026-03-13 10:01:39'),
(1060,92738,1,257.456,4622.414,4879.870,'今日收益','2026-03-13 10:06:32','2026-03-13 10:06:32'),
(1100,92738,1,369.122,4879.870,5248.992,'今日收益','2026-03-16 10:04:15','2026-03-16 10:04:15'),
(1117,92827,1,378.232,4924.466,5302.698,'今日收益','2026-03-16 10:26:44','2026-03-16 10:26:44'),
(1145,92738,1,333.858,5248.992,5582.850,'今日收益','2026-03-17 10:01:26','2026-03-17 10:01:26'),
(1146,92738,1,337.137,5582.850,5919.987,'今日收益','2026-03-17 10:02:14','2026-03-17 10:02:14'),
(1177,92827,1,384.261,5302.698,5686.959,'今日收益','2026-03-17 14:54:26','2026-03-17 14:54:26'),
(1204,92827,1,401.267,5686.959,6088.226,'今日收益','2026-03-18 10:05:05','2026-03-18 10:05:05'),
(1216,92738,1,367.767,5919.987,6287.754,'今日收益','2026-03-18 10:13:52','2026-03-18 10:13:52'),
(1217,92738,1,362.028,6287.754,6649.782,'今日收益','2026-03-18 10:15:17','2026-03-18 10:15:17'),
(1257,92738,1,300.354,6649.782,6950.136,'今日收益','2026-03-19 10:03:28','2026-03-19 10:03:28'),
(1261,92827,1,372.889,6088.226,6461.115,'今日收益','2026-03-19 10:04:21','2026-03-19 10:04:21'),
(1274,92738,1,242.103,6950.136,7192.239,'今日收益','2026-03-19 10:07:25','2026-03-19 10:07:25'),
(1282,92738,1,256.426,7192.239,7448.665,'今日收益','2026-03-19 10:42:03','2026-03-19 10:42:03'),
(1284,92738,1,206.652,7448.665,7655.317,'今日收益','2026-03-19 10:44:39','2026-03-19 10:44:39'),
(1308,92738,1,305.916,7655.317,7961.233,'今日收益','2026-03-20 10:01:20','2026-03-20 10:01:20'),
(1317,92738,1,216.604,7961.233,8177.837,'今日收益','2026-03-20 10:03:06','2026-03-20 10:03:06'),
(1326,92738,1,284.709,8177.837,8462.546,'今日收益','2026-03-20 10:04:49','2026-03-20 10:04:49'),
(1349,92827,1,310.284,6461.115,6771.399,'今日收益','2026-03-20 10:54:18','2026-03-20 10:54:18'),
(1364,92827,1,297.887,6771.399,7069.286,'今日收益','2026-03-23 10:02:02','2026-03-23 10:02:02'),
(1370,92738,1,204.579,8462.546,8667.125,'今日收益','2026-03-23 10:02:44','2026-03-23 10:02:44'),
(1392,92738,1,228.340,8667.125,8895.465,'今日收益','2026-03-23 10:05:46','2026-03-23 10:05:46'),
(1396,92738,1,375.760,8895.465,9271.225,'今日收益','2026-03-23 10:07:30','2026-03-23 10:07:30'),
(1436,92827,1,289.210,7069.286,7358.496,'今日收益','2026-03-24 10:02:50','2026-03-24 10:02:50'),
(1437,92738,1,243.563,9271.225,9514.788,'今日收益','2026-03-24 10:02:59','2026-03-24 10:02:59'),
(1441,92738,1,264.552,9514.788,9779.340,'今日收益','2026-03-24 10:03:42','2026-03-24 10:03:42'),
(1446,93140,1,203.733,0.000,203.733,'今日收益','2026-03-24 10:04:48','2026-03-24 10:04:48'),
(1506,92738,1,242.677,9779.340,10022.017,'今日收益','2026-03-25 10:04:47','2026-03-25 10:04:47'),
(1514,93140,1,214.257,203.733,417.990,'今日收益','2026-03-25 10:05:50','2026-03-25 10:05:50'),
(1525,92827,1,254.832,7358.496,7613.328,'今日收益','2026-03-25 10:22:51','2026-03-25 10:22:51'),
(1536,92738,1,371.323,10022.017,10393.340,'今日收益','2026-03-25 11:33:09','2026-03-25 11:33:09'),
(1581,93150,1,207.318,0.000,207.318,'今日收益','2026-03-26 10:04:44','2026-03-26 10:04:44'),
(1584,92738,1,285.201,10393.340,10678.541,'今日收益','2026-03-26 10:05:39','2026-03-26 10:05:39'),
(1586,92827,1,237.163,7613.328,7850.491,'今日收益','2026-03-26 10:06:45','2026-03-26 10:06:45'),
(1595,93140,1,227.758,417.990,645.748,'今日收益','2026-03-26 10:08:44','2026-03-26 10:08:44'),
(1617,92738,1,293.757,10678.541,10972.298,'今日收益','2026-03-27 09:59:16','2026-03-27 09:59:16'),
(1631,93150,1,211.460,207.318,418.778,'今日收益','2026-03-27 10:01:43','2026-03-27 10:01:43'),
(1634,92827,1,256.999,7850.491,8107.490,'今日收益','2026-03-27 10:02:06','2026-03-27 10:02:06'),
(1673,93140,1,230.255,645.748,876.003,'今日收益','2026-03-27 13:28:42','2026-03-27 13:28:42'),
(1736,92738,1,278.462,10972.298,11250.760,'今日收益','2026-03-30 12:08:02','2026-03-30 12:08:02'),
(1742,93150,1,204.579,418.778,623.357,'今日收益','2026-03-30 14:15:45','2026-03-30 14:15:45'),
(1750,92827,1,344.311,8107.490,8451.801,'今日收益','2026-03-30 15:12:11','2026-03-30 15:12:11'),
(1752,93140,1,237.163,876.003,1113.166,'今日收益','2026-03-30 15:43:43','2026-03-30 15:43:43'),
(1776,93140,1,248.878,1113.166,1362.044,'今日收益','2026-03-31 10:05:47','2026-03-31 10:05:47'),
(1780,93150,1,226.542,623.357,849.899,'今日收益','2026-03-31 10:06:28','2026-03-31 10:06:28'),
(1783,92738,1,229.019,11250.760,11479.779,'今日收益','2026-03-31 10:07:59','2026-03-31 10:07:59'),
(1813,92827,1,382.715,8451.801,8834.516,'今日收益','2026-03-31 15:36:15','2026-03-31 15:36:15'),
(1829,93150,1,235.733,849.899,1085.632,'今日收益','2026-04-01 10:01:22','2026-04-01 10:01:22'),
(1840,92827,1,376.894,8834.516,9211.410,'今日收益','2026-04-01 10:03:07','2026-04-01 10:03:07'),
(1856,92738,1,283.193,11479.779,11762.972,'今日收益','2026-04-01 10:06:09','2026-04-01 10:06:09'),
(1886,93140,1,233.338,1362.044,1595.382,'今日收益','2026-04-01 19:36:07','2026-04-01 19:36:07'),
(1912,93150,1,206.091,1085.632,1291.723,'今日收益','2026-04-02 10:03:50','2026-04-02 10:03:50'),
(1927,93140,1,259.154,1595.382,1854.536,'今日收益','2026-04-02 10:06:26','2026-04-02 10:06:26'),
(1946,92827,1,377.353,9211.410,9588.763,'今日收益','2026-04-02 15:49:54','2026-04-02 15:49:54'),
(1947,92738,1,299.551,11762.972,12062.523,'今日收益','2026-04-02 15:54:57','2026-04-02 15:54:57'),
(1960,93150,1,210.445,1291.723,1502.168,'今日收益','2026-04-03 10:00:25','2026-04-03 10:00:25'),
(1968,92738,1,300.440,12062.523,12362.963,'今日收益','2026-04-03 10:01:30','2026-04-03 10:01:30'),
(1988,93140,1,250.255,1854.536,2104.791,'今日收益','2026-04-03 10:04:29','2026-04-03 10:04:29'),
(2019,92827,1,335.127,9588.763,9923.890,'今日收益','2026-04-03 15:02:24','2026-04-03 15:02:24'),
(2049,93140,1,215.374,2104.791,2320.165,'今日收益','2026-04-06 10:04:10','2026-04-06 10:04:10'),
(2051,92827,1,322.813,9923.890,10246.703,'今日收益','2026-04-06 10:04:24','2026-04-06 10:04:24'),
(2077,92738,1,317.794,12362.963,12680.757,'今日收益','2026-04-06 10:49:38','2026-04-06 10:49:38'),
(2089,93150,1,209.676,1502.168,1711.844,'今日收益','2026-04-06 11:49:33','2026-04-06 11:49:33'),
(2135,92738,1,221.195,12680.757,12901.952,'今日收益','2026-04-07 10:03:17','2026-04-07 10:03:17'),
(2140,92738,1,278.140,12901.952,13180.092,'今日收益','2026-04-07 10:07:04','2026-04-07 10:07:04'),
(2172,92827,1,310.762,10246.703,10557.465,'今日收益','2026-04-07 10:21:46','2026-04-07 10:21:46'),
(2185,93140,1,211.024,2320.165,2531.189,'今日收益','2026-04-07 14:02:40','2026-04-07 14:02:40'),
(2195,93150,1,205.562,1711.844,1917.406,'今日收益','2026-04-07 14:14:36','2026-04-07 14:14:36'),
(2243,93140,1,328.298,2531.189,2859.487,'今日收益','2026-04-08 10:11:11','2026-04-08 10:11:11'),
(2246,92827,1,229.959,10557.465,10787.424,'今日收益','2026-04-08 10:15:58','2026-04-08 10:15:58'),
(2262,92738,1,310.931,13180.092,13491.023,'今日收益','2026-04-08 11:54:15','2026-04-08 11:54:15'),
(2268,92738,1,225.814,13491.023,13716.837,'今日收益','2026-04-08 13:26:46','2026-04-08 13:26:46'),
(2285,93150,1,212.357,1917.406,2129.763,'今日收益','2026-04-08 15:19:27','2026-04-08 15:19:27'),
(2314,93150,1,206.172,2129.763,2335.935,'今日收益','2026-04-09 10:04:21','2026-04-09 10:04:21'),
(2318,92827,1,335.324,10787.424,11122.748,'今日收益','2026-04-09 10:05:33','2026-04-09 10:05:33'),
(2353,92738,1,230.255,13716.837,13947.092,'今日收益','2026-04-09 10:51:18','2026-04-09 10:51:18'),
(2358,92738,1,278.617,13947.092,14225.709,'今日收益','2026-04-09 13:02:54','2026-04-09 13:02:54'),
(2368,93140,1,235.345,2859.487,3094.832,'今日收益','2026-04-09 14:54:20','2026-04-09 14:54:20'),
(2389,93150,1,224.623,2335.935,2560.558,'今日收益','2026-04-10 10:02:34','2026-04-10 10:02:34'),
(2426,93140,1,246.083,3094.832,3340.915,'今日收益','2026-04-10 11:10:32','2026-04-10 11:10:32'),
(2427,92827,1,339.578,11122.748,11462.326,'今日收益','2026-04-10 11:11:59','2026-04-10 11:11:59'),
(2432,92738,1,229.771,14225.709,14455.480,'今日收益','2026-04-10 12:35:21','2026-04-10 12:35:21'),
(2435,92738,1,286.976,14455.480,14742.456,'今日收益','2026-04-10 13:29:42','2026-04-10 13:29:42'),
(2466,93150,1,237.510,2560.558,2798.068,'今日收益','2026-04-13 10:01:15','2026-04-13 10:01:15'),
(2470,93140,1,250.117,3340.915,3591.032,'今日收益','2026-04-13 10:01:37','2026-04-13 10:01:37'),
(2488,92827,1,360.222,11462.326,11822.548,'今日收益','2026-04-13 10:05:28','2026-04-13 10:05:28'),
(2499,92738,1,272.650,14742.456,15015.106,'今日收益','2026-04-13 10:12:09','2026-04-13 10:12:09'),
(2521,92738,1,244.278,15015.106,15259.384,'今日收益','2026-04-13 16:38:03','2026-04-13 16:38:03'),
(2528,93150,1,239.010,2798.068,3037.078,'今日收益','2026-04-14 09:59:25','2026-04-14 09:59:25'),
(2554,93140,1,244.278,3591.032,3835.310,'今日收益','2026-04-14 10:04:11','2026-04-14 10:04:11'),
(2572,92827,1,366.418,11822.548,12188.966,'今日收益','2026-04-14 11:31:02','2026-04-14 11:31:02'),
(2587,92738,1,251.103,15259.384,15510.487,'今日收益','2026-04-14 15:14:04','2026-04-14 15:14:04'),
(2589,92738,1,250.364,15510.487,15760.851,'今日收益','2026-04-14 15:29:02','2026-04-14 15:29:02'),
(2612,92738,1,261.781,15760.851,16022.632,'今日收益','2026-04-15 10:01:28','2026-04-15 10:01:28'),
(2622,93150,1,209.413,3037.078,3246.491,'今日收益','2026-04-15 10:01:59','2026-04-15 10:01:59'),
(2630,92827,1,357.418,12188.966,12546.384,'今日收益','2026-04-15 10:02:36','2026-04-15 10:02:36'),
(2646,93140,1,266.585,3835.310,4101.895,'今日收益','2026-04-15 10:05:15','2026-04-15 10:05:15'),
(2687,93140,1,253.565,4101.895,4355.460,'今日收益','2026-04-16 10:00:08','2026-04-16 10:00:08'),
(2695,92738,1,278.349,16022.632,16300.981,'今日收益','2026-04-16 10:01:07','2026-04-16 10:01:07'),
(2707,92827,1,342.077,12546.384,12888.461,'今日收益','2026-04-16 10:02:45','2026-04-16 10:02:45'),
(2750,93150,1,212.264,3246.491,3458.755,'今日收益','2026-04-16 14:27:29','2026-04-16 14:27:29'),
(2770,92738,1,261.172,16300.981,16562.153,'今日收益','2026-04-20 10:00:45','2026-04-20 10:00:45'),
(2776,93140,1,207.324,4355.460,4562.784,'今日收益','2026-04-20 10:03:10','2026-04-20 10:03:10'),
(2793,93150,1,280.203,3458.755,3738.958,'今日收益','2026-04-20 14:09:16','2026-04-20 14:09:16'),
(2794,92827,1,332.683,12888.461,13221.144,'今日收益','2026-04-20 14:46:53','2026-04-20 14:46:53'),
(2824,92738,1,274.358,16562.153,16836.511,'今日收益','2026-04-21 10:02:07','2026-04-21 10:02:07'),
(2829,93140,1,225.191,4562.784,4787.975,'今日收益','2026-04-21 10:03:34','2026-04-21 10:03:34'),
(2834,92827,1,342.664,13221.144,13563.808,'今日收益','2026-04-21 10:10:39','2026-04-21 10:10:39'),
(2859,93150,1,215.062,3738.958,3954.020,'今日收益','2026-04-21 14:14:48','2026-04-21 14:14:48'),
(2881,92738,1,277.077,16836.511,17113.588,'今日收益','2026-04-22 10:01:47','2026-04-22 10:01:47'),
(2898,93150,1,214.177,3954.020,4168.197,'今日收益','2026-04-22 10:57:10','2026-04-22 10:57:10');
-- ---------- `wa_sharebonus_log` (343 rows) ----------
INSERT INTO `wa_sharebonus_log` VALUES
(310275,92738,1,81.811,0.000,81.811,'今日收益','2025-12-01 10:03:27','2025-12-01 10:03:27'),
(310381,92738,1,82.516,81.811,164.327,'今日收益','2025-12-02 10:04:00','2025-12-02 10:04:00'),
(310697,92738,1,98.437,164.327,262.764,'今日收益','2025-12-04 10:08:12','2025-12-04 10:08:12'),
(311673,92738,1,95.570,262.764,358.334,'今日收益','2025-12-15 10:02:05','2025-12-15 10:02:05'),
(311812,92738,1,87.198,358.334,445.532,'今日收益','2025-12-15 15:09:36','2025-12-15 15:09:36'),
(311829,92738,1,87.357,445.532,532.889,'今日收益','2025-12-16 10:00:50','2025-12-16 10:00:50'),
(312051,92738,1,85.369,532.889,618.258,'今日收益','2025-12-17 10:06:36','2025-12-17 10:06:36'),
(312072,92738,1,94.475,618.258,712.733,'今日收益','2025-12-17 10:08:43','2025-12-17 10:08:43'),
(312232,92738,1,93.633,712.733,806.366,'今日收益','2025-12-18 10:09:10','2025-12-18 10:09:10'),
(312258,92738,1,130.045,806.366,936.411,'今日收益','2025-12-18 10:19:00','2025-12-18 10:19:00'),
(312295,92738,1,93.669,936.411,1030.080,'今日收益','2025-12-18 14:54:04','2025-12-18 14:54:04'),
(312382,92738,1,144.693,1030.080,1174.773,'今日收益','2025-12-19 10:07:24','2025-12-19 10:07:24'),
(312406,92738,1,107.415,1174.773,1282.188,'今日收益','2025-12-19 10:10:20','2025-12-19 10:10:20'),
(312460,92738,1,83.586,1282.188,1365.774,'今日收益','2025-12-19 15:06:36','2025-12-19 15:06:36'),
(312554,92738,1,83.889,1365.774,1449.663,'今日收益','2025-12-22 10:07:08','2025-12-22 10:07:08'),
(312630,92738,1,100.418,1449.663,1550.081,'今日收益','2025-12-22 11:08:59','2025-12-22 11:08:59'),
(312633,92738,1,107.565,1550.081,1657.646,'今日收益','2025-12-22 11:09:08','2025-12-22 11:09:08'),
(312729,92738,1,82.416,1657.646,1740.062,'今日收益','2025-12-23 10:05:19','2025-12-23 10:05:19'),
(312744,92738,1,92.719,1740.062,1832.781,'今日收益','2025-12-23 10:06:50','2025-12-23 10:06:50'),
(312848,92738,1,98.118,1832.781,1930.899,'今日收益','2025-12-23 17:24:28','2025-12-23 17:24:28'),
(312865,92738,1,83.153,1930.899,2014.052,'今日收益','2025-12-24 10:01:33','2025-12-24 10:01:33'),
(313079,92738,1,140.245,2014.052,2154.297,'今日收益','2025-12-25 10:03:14','2025-12-25 10:03:14'),
(313114,92738,1,81.426,2154.297,2235.723,'今日收益','2025-12-25 10:06:02','2025-12-25 10:06:02'),
(313207,92738,1,99.241,2235.723,2334.964,'今日收益','2025-12-25 13:23:17','2025-12-25 13:23:17'),
(313266,92738,1,91.052,2334.964,2426.016,'今日收益','2025-12-26 10:03:22','2025-12-26 10:03:22'),
(313326,92738,1,104.739,2426.016,2530.755,'今日收益','2025-12-26 10:05:18','2025-12-26 10:05:18'),
(313497,92738,1,129.364,2530.755,2660.119,'今日收益','2025-12-29 10:07:17','2025-12-29 10:07:17'),
(313529,92738,1,83.338,2660.119,2743.457,'今日收益','2025-12-29 10:09:06','2025-12-29 10:09:06'),
(313581,92738,1,94.002,2743.457,2837.459,'今日收益','2025-12-29 14:42:55','2025-12-29 14:42:55'),
(313661,92738,1,94.025,2837.459,2931.484,'今日收益','2025-12-30 10:05:34','2025-12-30 10:05:34'),
(313726,92738,1,128.815,2931.484,3060.299,'今日收益','2025-12-30 10:17:25','2025-12-30 10:17:25'),
(313802,92738,1,90.495,3060.299,3150.794,'今日收益','2025-12-31 10:00:31','2025-12-31 10:00:31'),
(313822,92738,1,93.210,3150.794,3244.004,'今日收益','2025-12-31 10:02:43','2025-12-31 10:02:43'),
(313972,92738,1,138.472,3244.004,3382.476,'今日收益','2025-12-31 13:52:20','2025-12-31 13:52:20'),
(314034,92738,1,111.846,3382.476,3494.322,'今日收益','2026-01-01 10:03:53','2026-01-01 10:03:53'),
(314050,92738,1,115.047,3494.322,3609.369,'今日收益','2026-01-01 10:05:28','2026-01-01 10:05:28'),
(314102,92738,1,94.588,3609.369,3703.957,'今日收益','2026-01-01 10:14:04','2026-01-01 10:14:04'),
(314195,92738,1,121.716,3703.957,3825.673,'今日收益','2026-01-02 10:01:42','2026-01-02 10:01:42'),
(314268,92738,1,105.800,3825.673,3931.473,'今日收益','2026-01-02 10:06:40','2026-01-02 10:06:40'),
(314340,92738,1,95.205,3931.473,4026.678,'今日收益','2026-01-02 10:39:16','2026-01-02 10:39:16'),
(314431,92738,1,100.144,4026.678,4126.822,'今日收益','2026-01-05 10:03:43','2026-01-05 10:03:43'),
(314513,92738,1,118.657,4126.822,4245.479,'今日收益','2026-01-05 10:08:31','2026-01-05 10:08:31'),
(314582,92738,1,89.535,4245.479,4335.014,'今日收益','2026-01-05 15:49:58','2026-01-05 15:49:58'),
(314609,92738,1,122.217,4335.014,4457.231,'今日收益','2026-01-06 10:01:44','2026-01-06 10:01:44'),
(314675,92738,1,112.496,4457.231,4569.727,'今日收益','2026-01-06 10:06:04','2026-01-06 10:06:04'),
(314764,92738,1,85.393,4569.727,4655.120,'今日收益','2026-01-06 12:27:13','2026-01-06 12:27:13'),
(314782,92827,1,93.589,0.000,93.589,'今日收益','2026-01-06 15:31:08','2026-01-06 15:31:08'),
(314787,92827,1,96.111,93.589,189.700,'今日收益','2026-01-07 10:00:24','2026-01-07 10:00:24'),
(314820,92738,1,133.002,4655.120,4788.122,'今日收益','2026-01-07 10:04:27','2026-01-07 10:04:27'),
(314840,92738,1,114.083,4788.122,4902.205,'今日收益','2026-01-07 10:05:19','2026-01-07 10:05:19'),
(314874,92738,1,106.456,4902.205,5008.661,'今日收益','2026-01-07 10:07:32','2026-01-07 10:07:32'),
(314990,92738,1,109.649,5008.661,5118.310,'今日收益','2026-01-08 10:01:22','2026-01-08 10:01:22'),
(314996,92738,1,122.366,5118.310,5240.676,'今日收益','2026-01-08 10:01:33','2026-01-08 10:01:33'),
(315161,92738,1,81.937,5240.676,5322.613,'今日收益','2026-01-08 15:25:39','2026-01-08 15:25:39'),
(315166,92827,1,97.837,189.700,287.537,'今日收益','2026-01-08 15:39:57','2026-01-08 15:39:57'),
(315200,92738,1,114.083,5322.613,5436.696,'今日收益','2026-01-09 10:02:45','2026-01-09 10:02:45'),
(315223,92827,1,94.814,287.537,382.351,'今日收益','2026-01-09 10:04:47','2026-01-09 10:04:47'),
(315293,92738,1,140.760,5436.696,5577.456,'今日收益','2026-01-09 10:10:28','2026-01-09 10:10:28'),
(315345,92738,1,95.168,5577.456,5672.624,'今日收益','2026-01-09 12:59:07','2026-01-09 12:59:07'),
(315388,92738,1,116.094,5672.624,5788.718,'今日收益','2026-01-12 10:01:50','2026-01-12 10:01:50'),
(315418,92827,1,86.035,382.351,468.386,'今日收益','2026-01-12 10:03:34','2026-01-12 10:03:34'),
(315469,92738,1,112.939,5788.718,5901.657,'今日收益','2026-01-12 10:07:09','2026-01-12 10:07:09'),
(315493,92738,1,97.227,5901.657,5998.884,'今日收益','2026-01-12 10:18:02','2026-01-12 10:18:02'),
(315607,92738,1,100.588,5998.884,6099.472,'今日收益','2026-01-13 10:02:13','2026-01-13 10:02:13'),
(315671,92738,1,133.318,6099.472,6232.790,'今日收益','2026-01-13 10:05:10','2026-01-13 10:05:10'),
(315765,92827,1,96.846,468.386,565.232,'今日收益','2026-01-13 15:25:31','2026-01-13 15:25:31'),
(315795,92738,1,103.148,6232.790,6335.938,'今日收益','2026-01-14 10:01:50','2026-01-14 10:01:50'),
(315840,92827,1,91.433,565.232,656.665,'今日收益','2026-01-14 10:04:08','2026-01-14 10:04:08'),
(315873,92738,1,99.288,6335.938,6435.226,'今日收益','2026-01-14 10:06:57','2026-01-14 10:06:57'),
(315898,92738,1,137.724,6435.226,6572.950,'今日收益','2026-01-14 10:10:51','2026-01-14 10:10:51'),
(315957,92738,1,87.717,6572.950,6660.667,'今日收益','2026-01-14 13:17:42','2026-01-14 13:17:42'),
(316016,92738,1,105.224,6660.667,6765.891,'今日收益','2026-01-15 10:02:37','2026-01-15 10:02:37'),
(316036,92738,1,98.352,6765.891,6864.243,'今日收益','2026-01-15 10:03:21','2026-01-15 10:03:21'),
(316048,92738,1,91.561,6864.243,6955.804,'今日收益','2026-01-15 10:04:12','2026-01-15 10:04:12'),
(316088,92738,1,138.356,6955.804,7094.160,'今日收益','2026-01-15 10:06:30','2026-01-15 10:06:30'),
(316170,92827,1,90.349,656.665,747.014,'今日收益','2026-01-15 15:12:30','2026-01-15 15:12:30'),
(316200,92738,1,97.137,7094.160,7191.297,'今日收益','2026-01-16 10:00:51','2026-01-16 10:00:51'),
(316207,92827,1,94.585,747.014,841.599,'今日收益','2026-01-16 10:01:28','2026-01-16 10:01:28'),
(316307,92738,1,98.072,7191.297,7289.369,'今日收益','2026-01-16 10:12:28','2026-01-16 10:12:28'),
(316344,92738,1,144.774,7289.369,7434.143,'今日收益','2026-01-16 10:31:56','2026-01-16 10:31:56'),
(316355,92738,1,96.923,7434.143,7531.066,'今日收益','2026-01-16 11:04:40','2026-01-16 11:04:40'),
(316443,92738,1,124.589,7531.066,7655.655,'今日收益','2026-01-19 10:04:09','2026-01-19 10:04:09'),
(316504,92738,1,109.001,7655.655,7764.656,'今日收益','2026-01-19 10:09:12','2026-01-19 10:09:12'),
(316530,92827,1,97.946,841.599,939.545,'今日收益','2026-01-19 10:14:59','2026-01-19 10:14:59'),
(316535,92738,1,97.310,7764.656,7861.966,'今日收益','2026-01-19 10:15:18','2026-01-19 10:15:18'),
(316616,92738,1,86.203,7861.966,7948.169,'今日收益','2026-01-19 20:11:57','2026-01-19 20:11:57'),
(316653,92827,1,93.798,939.545,1033.343,'今日收益','2026-01-20 10:03:11','2026-01-20 10:03:11'),
(316673,92738,1,114.761,7948.169,8062.930,'今日收益','2026-01-20 10:04:17','2026-01-20 10:04:17'),
(316728,92738,1,86.558,8062.930,8149.488,'今日收益','2026-01-20 10:07:56','2026-01-20 10:07:56'),
(316757,92738,1,85.162,8149.488,8234.650,'今日收益','2026-01-20 10:13:46','2026-01-20 10:13:46'),
(316847,92738,1,89.372,8234.650,8324.022,'今日收益','2026-01-21 10:01:01','2026-01-21 10:01:01'),
(316900,92738,1,107.534,8324.022,8431.556,'今日收益','2026-01-21 10:04:04','2026-01-21 10:04:04'),
(316943,92827,1,94.196,1033.343,1127.539,'今日收益','2026-01-21 10:09:12','2026-01-21 10:09:12'),
(317036,92738,1,87.717,8431.556,8519.273,'今日收益','2026-01-21 14:46:26','2026-01-21 14:46:26'),
(317211,92738,1,110.381,8519.273,8629.654,'今日收益','2026-01-22 10:31:18','2026-01-22 10:31:18'),
(317231,92827,1,97.928,1127.539,1225.467,'今日收益','2026-01-22 12:11:17','2026-01-22 12:11:17'),
(317237,92738,1,91.286,8629.654,8720.940,'今日收益','2026-01-22 12:19:30','2026-01-22 12:19:30'),
(317303,92738,1,92.308,8720.940,8813.248,'今日收益','2026-01-23 10:01:44','2026-01-23 10:01:44'),
(317324,92738,1,148.786,8813.248,8962.034,'今日收益','2026-01-23 10:03:36','2026-01-23 10:03:36'),
(317360,92738,1,140.226,8962.034,9102.260,'今日收益','2026-01-23 10:05:19','2026-01-23 10:05:19'),
(317392,92738,1,82.225,9102.260,9184.485,'今日收益','2026-01-23 10:08:44','2026-01-23 10:08:44'),
(317396,92827,1,99.751,1225.467,1325.218,'今日收益','2026-01-23 10:09:48','2026-01-23 10:09:48'),
(317530,92738,1,130.927,9184.485,9315.412,'今日收益','2026-01-26 10:01:52','2026-01-26 10:01:52'),
(317613,92738,1,155.033,9315.412,9470.445,'今日收益','2026-01-26 10:08:28','2026-01-26 10:08:28'),
(317631,92827,1,96.597,1325.218,1421.815,'今日收益','2026-01-26 10:12:00','2026-01-26 10:12:00'),
(317682,92738,1,92.271,9470.445,9562.716,'今日收益','2026-01-26 10:56:37','2026-01-26 10:56:37'),
(317690,92738,1,84.692,9562.716,9647.408,'今日收益','2026-01-26 11:48:50','2026-01-26 11:48:50'),
(317744,92738,1,145.376,9647.408,9792.784,'今日收益','2026-01-27 10:01:20','2026-01-27 10:01:20'),
(317757,92738,1,94.233,9792.784,9887.017,'今日收益','2026-01-27 10:02:07','2026-01-27 10:02:07'),
(317850,92738,1,133.040,9887.017,10020.057,'今日收益','2026-01-27 10:13:37','2026-01-27 10:13:37'),
(317853,92827,1,95.205,1421.815,1517.020,'今日收益','2026-01-27 10:14:17','2026-01-27 10:14:17'),
(317957,92738,1,87.232,10020.057,10107.289,'今日收益','2026-01-27 15:52:46','2026-01-27 15:52:46'),
(318015,92738,1,159.968,10107.289,10267.257,'今日收益','2026-01-28 10:02:54','2026-01-28 10:02:54'),
(318027,92827,1,93.171,1517.020,1610.191,'今日收益','2026-01-28 10:03:35','2026-01-28 10:03:35'),
(318061,92738,1,97.890,10267.257,10365.147,'今日收益','2026-01-28 10:04:39','2026-01-28 10:04:39'),
(318068,92738,1,117.884,10365.147,10483.031,'今日收益','2026-01-28 10:05:24','2026-01-28 10:05:24'),
(318155,92738,1,86.475,10483.031,10569.506,'今日收益','2026-01-28 14:45:29','2026-01-28 14:45:29'),
(318225,92738,1,83.730,10569.506,10653.236,'今日收益','2026-01-29 10:02:29','2026-01-29 10:02:29'),
(318310,92738,1,154.229,10653.236,10807.465,'今日收益','2026-01-29 10:07:34','2026-01-29 10:07:34'),
(318416,92738,1,132.177,10807.465,10939.642,'今日收益','2026-01-29 15:57:44','2026-01-29 15:57:44'),
(318417,92827,1,98.370,1610.191,1708.561,'今日收益','2026-01-29 16:01:42','2026-01-29 16:01:42'),
(318452,92738,1,82.436,10939.642,11022.078,'今日收益','2026-01-30 10:01:25','2026-01-30 10:01:25'),
(318481,92827,1,95.321,1708.561,1803.882,'今日收益','2026-01-30 10:03:20','2026-01-30 10:03:20'),
(318569,92738,1,130.385,11022.078,11152.463,'今日收益','2026-01-30 10:07:08','2026-01-30 10:07:08'),
(318598,92738,1,81.982,11152.463,11234.445,'今日收益','2026-01-30 10:38:51','2026-01-30 10:38:51'),
(318662,92738,1,99.971,11234.445,11334.416,'今日收益','2026-02-02 10:02:22','2026-02-02 10:02:22'),
(318789,92738,1,149.737,11334.416,11484.153,'今日收益','2026-02-02 10:21:02','2026-02-02 10:21:02'),
(318809,92827,1,94.493,1803.882,1898.375,'今日收益','2026-02-02 10:37:14','2026-02-02 10:37:14'),
(318815,92738,1,161.709,11484.153,11645.862,'今日收益','2026-02-02 11:41:41','2026-02-02 11:41:41'),
(318978,92738,1,90.435,11645.862,11736.297,'今日收益','2026-02-03 10:06:31','2026-02-03 10:06:31'),
(319003,92738,1,103.206,11736.297,11839.503,'今日收益','2026-02-03 10:11:34','2026-02-03 10:11:34'),
(319019,92738,1,154.229,11839.503,11993.732,'今日收益','2026-02-03 10:25:37','2026-02-03 10:25:37'),
(319055,92827,1,101.126,1898.375,1999.501,'今日收益','2026-02-03 14:14:56','2026-02-03 14:14:56'),
(319090,92738,1,85.826,11993.732,12079.558,'今日收益','2026-02-04 10:00:13','2026-02-04 10:00:13'),
(319248,92738,1,104.638,12079.558,12184.196,'今日收益','2026-02-04 10:15:38','2026-02-04 10:15:38'),
(319249,92738,1,144.022,12184.196,12328.218,'今日收益','2026-02-04 10:15:45','2026-02-04 10:15:45'),
(319267,92827,1,97.580,1999.501,2097.081,'今日收益','2026-02-04 10:41:44','2026-02-04 10:41:44'),
(319315,92738,1,82.927,12328.218,12411.145,'今日收益','2026-02-05 10:00:30','2026-02-05 10:00:30'),
(319412,92738,1,148.342,12411.145,12559.487,'今日收益','2026-02-05 10:04:23','2026-02-05 10:04:23'),
(319436,92827,1,100.665,2097.081,2197.746,'今日收益','2026-02-05 10:06:50','2026-02-05 10:06:50'),
(319477,92738,1,100.665,12559.487,12660.152,'今日收益','2026-02-05 10:17:26','2026-02-05 10:17:26'),
(319589,92738,1,92.353,12660.152,12752.505,'今日收益','2026-02-06 10:02:05','2026-02-06 10:02:05'),
(319642,92738,1,143.299,12752.505,12895.804,'今日收益','2026-02-06 10:03:56','2026-02-06 10:03:56'),
(319668,92738,1,84.265,12895.804,12980.069,'今日收益','2026-02-06 10:06:45','2026-02-06 10:06:45'),
(319804,92827,1,88.191,2197.746,2285.937,'今日收益','2026-02-09 10:02:00','2026-02-09 10:02:00'),
(319840,92738,1,153.318,12980.069,13133.387,'今日收益','2026-02-09 10:03:19','2026-02-09 10:03:19'),
(319877,92738,1,92.994,13133.387,13226.381,'今日收益','2026-02-09 10:05:08','2026-02-09 10:05:08'),
(320002,92827,1,96.138,2285.937,2382.075,'今日收益','2026-02-10 10:00:46','2026-02-10 10:00:46'),
(320005,92738,1,95.784,13226.381,13322.165,'今日收益','2026-02-10 10:01:04','2026-02-10 10:01:04'),
(320084,92738,1,141.877,13322.165,13464.042,'今日收益','2026-02-10 10:05:35','2026-02-10 10:05:35'),
(320213,92738,1,104.361,13464.042,13568.403,'今日收益','2026-02-19 10:02:30','2026-02-19 10:02:30'),
(320240,92738,1,128.351,13568.403,13696.754,'今日收益','2026-02-19 10:27:47','2026-02-19 10:27:47'),
(320259,92827,1,99.441,2382.075,2481.516,'今日收益','2026-02-19 18:23:24','2026-02-19 18:23:24'),
(320296,92738,1,120.499,13696.754,13817.253,'今日收益','2026-02-20 11:06:44','2026-02-20 11:06:44'),
(320301,92738,1,100.482,13817.253,13917.735,'今日收益','2026-02-20 11:25:03','2026-02-20 11:25:03'),
(320319,92827,1,102.480,2481.516,2583.996,'今日收益','2026-02-20 15:03:11','2026-02-20 15:03:11'),
(320338,92738,1,136.167,13917.735,14053.902,'今日收益','2026-02-23 10:01:35','2026-02-23 10:01:35'),
(320347,92738,1,97.687,14053.902,14151.589,'今日收益','2026-02-23 10:02:57','2026-02-23 10:02:57'),
(320364,92827,1,107.062,2583.996,2691.058,'今日收益','2026-02-23 11:56:55','2026-02-23 11:56:55'),
(320406,92738,1,98.433,14151.589,14250.022,'今日收益','2026-02-24 10:06:11','2026-02-24 10:06:11'),
(320439,92738,1,126.706,14250.022,14376.728,'今日收益','2026-02-24 14:59:48','2026-02-24 14:59:48'),
(320440,92827,1,114.561,2691.058,2805.619,'今日收益','2026-02-24 15:00:00','2026-02-24 15:00:00'),
(320450,92827,1,137.803,2805.619,2943.422,'今日收益','2026-02-25 10:00:49','2026-02-25 10:00:49'),
(320482,92738,1,113.582,14376.728,14490.310,'今日收益','2026-02-25 11:20:10','2026-02-25 11:20:10'),
(320501,92738,1,93.685,14490.310,14583.995,'今日收益','2026-02-25 14:53:33','2026-02-25 14:53:33'),
(320534,92738,1,106.949,14583.995,14690.944,'今日收益','2026-02-26 10:05:58','2026-02-26 10:05:58'),
(320541,92827,1,108.201,2943.422,3051.623,'今日收益','2026-02-26 10:13:01','2026-02-26 10:13:01'),
(320554,92738,1,107.160,14690.944,14798.104,'今日收益','2026-02-26 12:51:45','2026-02-26 12:51:45'),
(320564,92827,1,84.704,3051.623,3136.327,'今日收益','2026-02-26 16:01:38','2026-02-26 16:01:38'),
(320582,92827,1,93.486,3136.327,3229.813,'今日收益','2026-02-27 10:02:17','2026-02-27 10:02:17'),
(320588,92827,1,98.610,3229.813,3328.423,'今日收益','2026-02-27 10:03:53','2026-02-27 10:03:53'),
(320594,92738,1,118.726,14798.104,14916.830,'今日收益','2026-02-27 10:05:33','2026-02-27 10:05:33'),
(320635,92738,1,115.069,14916.830,15031.899,'今日收益','2026-03-02 10:01:29','2026-03-02 10:01:29'),
(320642,92827,1,113.245,3328.423,3441.668,'今日收益','2026-03-02 10:02:19','2026-03-02 10:02:19'),
(320657,92827,1,89.863,3441.668,3531.531,'今日收益','2026-03-02 10:05:54','2026-03-02 10:05:54'),
(320667,92738,1,82.054,15031.899,15113.953,'今日收益','2026-03-02 10:11:32','2026-03-02 10:11:32'),
(320710,92827,1,118.234,3531.531,3649.765,'今日收益','2026-03-03 10:07:12','2026-03-03 10:07:12'),
(320711,92738,1,117.997,15113.953,15231.950,'今日收益','2026-03-03 10:10:35','2026-03-03 10:10:35'),
(320731,92827,1,101.442,3649.765,3751.207,'今日收益','2026-03-03 10:50:28','2026-03-03 10:50:28'),
(320749,92738,1,162.591,15231.950,15394.541,'今日收益','2026-03-03 22:00:19','2026-03-03 22:00:19'),
(320766,92827,1,107.931,3751.207,3859.138,'今日收益','2026-03-04 10:02:03','2026-03-04 10:02:03'),
(320777,92738,1,106.619,15394.541,15501.160,'今日收益','2026-03-04 10:03:39','2026-03-04 10:03:39'),
(320781,92827,1,116.866,3859.138,3976.004,'今日收益','2026-03-04 10:04:14','2026-03-04 10:04:14'),
(320792,92738,1,159.751,15501.160,15660.911,'今日收益','2026-03-04 10:10:22','2026-03-04 10:10:22'),
(320796,92738,1,129.201,15660.911,15790.112,'今日收益','2026-03-04 12:45:31','2026-03-04 12:45:31'),
(320832,92738,1,125.434,15790.112,15915.546,'今日收益','2026-03-05 10:02:50','2026-03-05 10:02:50'),
(320838,92827,1,116.952,3976.004,4092.956,'今日收益','2026-03-05 10:03:35','2026-03-05 10:03:35'),
(320848,92827,1,112.745,4092.956,4205.701,'今日收益','2026-03-05 10:06:50','2026-03-05 10:06:50'),
(320859,92738,1,157.551,15915.546,16073.097,'今日收益','2026-03-05 10:52:27','2026-03-05 10:52:27'),
(320889,92738,1,114.223,16073.097,16187.320,'今日收益','2026-03-06 10:01:42','2026-03-06 10:01:42'),
(320913,92827,1,128.939,4205.701,4334.640,'今日收益','2026-03-06 10:07:54','2026-03-06 10:07:54'),
(320935,92827,1,113.765,4334.640,4448.405,'今日收益','2026-03-06 12:34:01','2026-03-06 12:34:01'),
(320937,92738,1,157.224,16187.320,16344.544,'今日收益','2026-03-06 14:49:37','2026-03-06 14:49:37'),
(320949,92738,1,120.221,16344.544,16464.765,'今日收益','2026-03-09 10:01:43','2026-03-09 10:01:43'),
(320995,92738,1,88.662,16464.765,16553.427,'今日收益','2026-03-09 12:37:42','2026-03-09 12:37:42'),
(320996,92738,1,141.856,16553.427,16695.283,'今日收益','2026-03-09 12:44:26','2026-03-09 12:44:26'),
(321061,92738,1,141.182,16695.283,16836.465,'今日收益','2026-03-10 11:56:21','2026-03-10 11:56:21'),
(321067,92827,1,132.286,4448.405,4580.691,'今日收益','2026-03-10 13:38:54','2026-03-10 13:38:54'),
(321069,92738,1,118.985,16836.465,16955.450,'今日收益','2026-03-10 14:26:28','2026-03-10 14:26:28'),
(321075,92738,1,123.200,16955.450,17078.650,'今日收益','2026-03-10 15:41:35','2026-03-10 15:41:35'),
(321085,92738,1,94.062,17078.650,17172.712,'今日收益','2026-03-11 10:01:35','2026-03-11 10:01:35'),
(321101,92827,1,130.343,4580.691,4711.034,'今日收益','2026-03-11 10:04:04','2026-03-11 10:04:04'),
(321102,92738,1,139.544,17172.712,17312.256,'今日收益','2026-03-11 10:04:12','2026-03-11 10:04:12'),
(321113,92738,1,124.916,17312.256,17437.172,'今日收益','2026-03-11 10:07:28','2026-03-11 10:07:28'),
(321147,92738,1,139.544,17437.172,17576.716,'今日收益','2026-03-12 10:00:25','2026-03-12 10:00:25'),
(321211,92738,1,91.322,17576.716,17668.038,'今日收益','2026-03-12 16:23:06','2026-03-12 16:23:06'),
(321218,92738,1,148.334,17668.038,17816.372,'今日收益','2026-03-13 10:01:39','2026-03-13 10:01:39'),
(321234,92738,1,91.133,17816.372,17907.505,'今日收益','2026-03-13 10:03:48','2026-03-13 10:03:48'),
(321246,92738,1,143.348,17907.505,18050.853,'今日收益','2026-03-13 10:07:46','2026-03-13 10:07:46'),
(321280,92738,2,-3378.000,18050.853,14672.853,'用户提现','2026-03-14 15:55:10','2026-03-14 15:55:10'),
(321302,92738,1,151.293,14672.853,14824.146,'今日收益','2026-03-16 10:26:44','2026-03-16 10:26:44'),
(321309,92738,1,136.389,14824.146,14960.535,'今日收益','2026-03-16 14:54:12','2026-03-16 14:54:12'),
(321318,92738,1,82.172,14960.535,15042.707,'今日收益','2026-03-16 15:04:29','2026-03-16 15:04:29'),
(321326,92738,1,143.550,15042.707,15186.257,'今日收益','2026-03-17 10:00:56','2026-03-17 10:00:56'),
(321353,92738,1,91.282,15186.257,15277.539,'今日收益','2026-03-17 10:39:37','2026-03-17 10:39:37'),
(321363,92738,1,153.705,15277.539,15431.244,'今日收益','2026-03-17 14:54:26','2026-03-17 14:54:26'),
(321373,92738,2,-738.000,15431.244,14693.244,'用户提现','2026-03-17 16:44:49','2026-03-17 16:44:49'),
(321374,92738,2,-1342.000,14693.244,13351.244,'用户提现','2026-03-17 16:45:06','2026-03-17 16:45:06'),
(321382,92738,1,140.326,13351.244,13491.570,'今日收益','2026-03-18 10:01:12','2026-03-18 10:01:12'),
(321395,92738,1,160.507,13491.570,13652.077,'今日收益','2026-03-18 10:05:05','2026-03-18 10:05:05'),
(321409,92738,1,111.212,13652.077,13763.289,'今日收益','2026-03-18 10:15:23','2026-03-18 10:15:23'),
(321421,92738,2,-1460.000,13763.289,12303.289,'用户提现','2026-03-18 14:22:46','2026-03-18 14:22:46'),
(321438,92738,1,131.966,12303.289,12435.255,'今日收益','2026-03-19 10:01:08','2026-03-19 10:01:08'),
(321447,92738,1,89.158,12435.255,12524.413,'今日收益','2026-03-19 10:02:31','2026-03-19 10:02:31'),
(321455,92738,1,149.156,12524.413,12673.569,'今日收益','2026-03-19 10:04:21','2026-03-19 10:04:21'),
(321488,92738,2,-2011.000,12673.569,10662.569,'用户提现','2026-03-19 16:08:31','2026-03-19 16:08:31'),
(321530,92738,1,93.283,10662.569,10755.852,'今日收益','2026-03-20 10:05:14','2026-03-20 10:05:14'),
(321539,92738,1,118.407,10755.852,10874.259,'今日收益','2026-03-20 10:06:59','2026-03-20 10:06:59'),
(321546,92738,1,124.114,10874.259,10998.373,'今日收益','2026-03-20 10:54:18','2026-03-20 10:54:18'),
(321556,92738,2,-1614.000,10998.373,9384.373,'用户提现','2026-03-20 16:28:35','2026-03-20 16:28:35'),
(321563,92738,1,119.155,9384.373,9503.528,'今日收益','2026-03-23 10:02:02','2026-03-23 10:02:02'),
(321586,92738,1,127.837,9503.528,9631.365,'今日收益','2026-03-23 10:05:06','2026-03-23 10:05:06'),
(321617,92738,2,-1617.000,9631.365,8014.365,'用户提现','2026-03-23 15:27:54','2026-03-23 15:27:54'),
(321621,92738,1,92.105,8014.365,8106.470,'今日收益','2026-03-23 17:30:01','2026-03-23 17:30:01'),
(321630,92738,1,92.755,8106.470,8199.225,'今日收益','2026-03-24 10:01:28','2026-03-24 10:01:28'),
(321640,92738,1,115.684,8199.225,8314.909,'今日收益','2026-03-24 10:02:50','2026-03-24 10:02:50'),
(321650,92827,1,81.493,4711.034,4792.527,'今日收益','2026-03-24 10:04:48','2026-03-24 10:04:48'),
(321684,92738,1,94.243,8314.909,8409.152,'今日收益','2026-03-24 15:01:36','2026-03-24 15:01:36'),
(321690,92738,1,94.868,8409.152,8504.020,'今日收益','2026-03-24 18:53:00','2026-03-24 18:53:00'),
(321717,92738,1,135.622,8504.020,8639.642,'今日收益','2026-03-25 10:05:33','2026-03-25 10:05:33'),
(321720,92827,1,85.703,4792.527,4878.230,'今日收益','2026-03-25 10:05:50','2026-03-25 10:05:50'),
(321731,92738,1,101.933,8639.642,8741.575,'今日收益','2026-03-25 10:22:51','2026-03-25 10:22:51'),
(321736,92738,1,92.545,8741.575,8834.120,'今日收益','2026-03-25 10:36:25','2026-03-25 10:36:25'),
(321787,92738,1,82.927,8834.120,8917.047,'今日收益','2026-03-26 10:04:44','2026-03-26 10:04:44'),
(321791,92738,1,133.268,8917.047,9050.315,'今日收益','2026-03-26 10:05:43','2026-03-26 10:05:43'),
(321792,92738,1,94.865,9050.315,9145.180,'今日收益','2026-03-26 10:06:45','2026-03-26 10:06:45'),
(321801,92827,1,91.103,4878.230,4969.333,'今日收益','2026-03-26 10:08:44','2026-03-26 10:08:44'),
(321823,92738,1,89.420,9145.180,9234.600,'今日收益','2026-03-26 18:58:58','2026-03-26 18:58:58'),
(321834,92738,1,132.022,9234.600,9366.622,'今日收益','2026-03-27 10:01:17','2026-03-27 10:01:17'),
(321838,92738,1,84.584,9366.622,9451.206,'今日收益','2026-03-27 10:01:43','2026-03-27 10:01:43'),
(321841,92738,1,102.799,9451.206,9554.005,'今日收益','2026-03-27 10:02:06','2026-03-27 10:02:06'),
(321856,92738,1,88.676,9554.005,9642.681,'今日收益','2026-03-27 10:08:06','2026-03-27 10:08:06'),
(321880,92827,1,92.102,4969.333,5061.435,'今日收益','2026-03-27 13:28:42','2026-03-27 13:28:42'),
(321898,92738,1,87.977,9642.681,9730.658,'今日收益','2026-03-30 10:03:24','2026-03-30 10:03:24'),
(321903,92738,1,126.148,9730.658,9856.806,'今日收益','2026-03-30 10:06:28','2026-03-30 10:06:28'),
(321950,92738,1,81.832,9856.806,9938.638,'今日收益','2026-03-30 14:15:45','2026-03-30 14:15:45'),
(321957,92738,1,137.724,9938.638,10076.362,'今日收益','2026-03-30 15:12:11','2026-03-30 15:12:11'),
(321960,92827,1,94.865,5061.435,5156.300,'今日收益','2026-03-30 15:43:43','2026-03-30 15:43:43'),
(321962,92738,1,89.735,10076.362,10166.097,'今日收益','2026-03-31 10:00:10','2026-03-31 10:00:10'),
(321984,92827,1,99.551,5156.300,5255.851,'今日收益','2026-03-31 10:05:47','2026-03-31 10:05:47'),
(321988,92738,1,90.617,10166.097,10256.714,'今日收益','2026-03-31 10:06:28','2026-03-31 10:06:28'),
(322015,92738,1,141.856,10256.714,10398.570,'今日收益','2026-03-31 12:26:53','2026-03-31 12:26:53'),
(322022,92738,1,153.086,10398.570,10551.656,'今日收益','2026-03-31 15:36:15','2026-03-31 15:36:15'),
(322033,92738,1,92.427,10551.656,10644.083,'今日收益','2026-04-01 10:00:11','2026-04-01 10:00:11'),
(322038,92738,1,94.293,10644.083,10738.376,'今日收益','2026-04-01 10:01:22','2026-04-01 10:01:22'),
(322049,92738,1,150.758,10738.376,10889.134,'今日收益','2026-04-01 10:03:07','2026-04-01 10:03:07'),
(322088,92738,1,146.545,10889.134,11035.679,'今日收益','2026-04-01 14:55:31','2026-04-01 14:55:31'),
(322095,92827,1,93.335,5255.851,5349.186,'今日收益','2026-04-01 19:36:07','2026-04-01 19:36:07'),
(322106,92738,1,89.420,11035.679,11125.099,'今日收益','2026-04-02 10:02:02','2026-04-02 10:02:02'),
(322120,92738,1,82.436,11125.099,11207.535,'今日收益','2026-04-02 10:03:50','2026-04-02 10:03:50'),
(322123,92738,1,120.672,11207.535,11328.207,'今日收益','2026-04-02 10:04:46','2026-04-02 10:04:46'),
(322135,92827,1,103.662,5349.186,5452.848,'今日收益','2026-04-02 10:06:26','2026-04-02 10:06:26'),
(322152,92738,2,-599.000,11328.207,10729.207,'用户提现','2026-04-02 12:28:46','2026-04-02 12:28:46'),
(322154,92738,1,150.941,10729.207,10880.148,'今日收益','2026-04-02 15:49:54','2026-04-02 15:49:54'),
(322169,92738,1,84.178,10880.148,10964.326,'今日收益','2026-04-03 10:00:25','2026-04-03 10:00:25'),
(322188,92738,1,123.415,10964.326,11087.741,'今日收益','2026-04-03 10:02:40','2026-04-03 10:02:40'),
(322197,92827,1,100.102,5452.848,5552.950,'今日收益','2026-04-03 10:04:29','2026-04-03 10:04:29'),
(322227,92738,1,134.051,11087.741,11221.792,'今日收益','2026-04-03 15:02:24','2026-04-03 15:02:24'),
(322240,92738,2,-601.000,11221.792,10620.792,'用户提现','2026-04-03 22:07:29','2026-04-03 22:07:29'),
(322259,92827,1,86.150,5552.950,5639.100,'今日收益','2026-04-06 10:04:10','2026-04-06 10:04:10'),
(322261,92738,1,129.125,10620.792,10749.917,'今日收益','2026-04-06 10:04:24','2026-04-06 10:04:24'),
(322286,92738,1,123.781,10749.917,10873.698,'今日收益','2026-04-06 10:47:08','2026-04-06 10:47:08'),
(322301,92738,1,83.870,10873.698,10957.568,'今日收益','2026-04-06 11:49:33','2026-04-06 11:49:33'),
(322326,92738,2,-636.000,10957.568,10321.568,'用户提现','2026-04-06 16:27:15','2026-04-06 16:27:15'),
(322335,92738,1,132.999,10321.568,10454.567,'今日收益','2026-04-07 10:00:36','2026-04-07 10:00:36'),
(322384,92738,1,124.305,10454.567,10578.872,'今日收益','2026-04-07 10:21:46','2026-04-07 10:21:46'),
(322397,92827,1,84.410,5639.100,5723.510,'今日收益','2026-04-07 14:02:40','2026-04-07 14:02:40'),
(322406,92738,1,82.225,10578.872,10661.097,'今日收益','2026-04-07 14:14:36','2026-04-07 14:14:36'),
(322418,92738,2,-999.000,10661.097,9662.097,'用户提现','2026-04-07 18:12:22','2026-04-07 18:12:22'),
(322455,92827,1,131.319,5723.510,5854.829,'今日收益','2026-04-08 10:11:11','2026-04-08 10:11:11'),
(322459,92738,1,91.983,9662.097,9754.080,'今日收益','2026-04-08 10:15:58','2026-04-08 10:15:58'),
(322480,92738,2,-1073.000,9754.080,8681.080,'用户提现','2026-04-08 13:20:52','2026-04-08 13:20:52'),
(322490,92738,1,134.859,8681.080,8815.939,'今日收益','2026-04-08 14:46:40','2026-04-08 14:46:40'),
(322499,92738,1,84.943,8815.939,8900.882,'今日收益','2026-04-08 15:19:27','2026-04-08 15:19:27'),
(322529,92738,1,82.469,8900.882,8983.351,'今日收益','2026-04-09 10:04:21','2026-04-09 10:04:21'),
(322533,92738,1,134.130,8983.351,9117.481,'今日收益','2026-04-09 10:05:33','2026-04-09 10:05:33'),
(322561,92738,1,135.259,9117.481,9252.740,'今日收益','2026-04-09 10:25:44','2026-04-09 10:25:44'),
(322571,92738,2,-1018.000,9252.740,8234.740,'用户提现','2026-04-09 12:25:50','2026-04-09 12:25:50'),
(322588,92827,1,94.138,5854.829,5948.967,'今日收益','2026-04-09 14:54:20','2026-04-09 14:54:20'),
(322601,92738,1,96.682,8234.740,8331.422,'今日收益','2026-04-10 10:01:17','2026-04-10 10:01:17'),
(322607,92738,1,89.849,8331.422,8421.271,'今日收益','2026-04-10 10:02:34','2026-04-10 10:02:34'),
(322609,92738,1,92.706,8421.271,8513.977,'今日收益','2026-04-10 10:02:47','2026-04-10 10:02:47'),
(322628,92738,1,130.835,8513.977,8644.812,'今日收益','2026-04-10 10:06:13','2026-04-10 10:06:13'),
(322644,92827,1,98.433,5948.967,6047.400,'今日收益','2026-04-10 11:10:32','2026-04-10 11:10:32'),
(322645,92738,1,135.831,8644.812,8780.643,'今日收益','2026-04-10 11:11:59','2026-04-10 11:11:59'),
(322672,92738,2,-1033.000,8780.643,7747.643,'用户提现','2026-04-10 18:12:40','2026-04-10 18:12:40'),
(322688,92738,1,95.004,7747.643,7842.647,'今日收益','2026-04-13 10:01:15','2026-04-13 10:01:15'),
(322692,92827,1,100.047,6047.400,6147.447,'今日收益','2026-04-13 10:01:37','2026-04-13 10:01:37'),
(322700,92738,1,142.551,7842.647,7985.198,'今日收益','2026-04-13 10:04:09','2026-04-13 10:04:09'),
(322710,92738,1,144.089,7985.198,8129.287,'今日收益','2026-04-13 10:05:28','2026-04-13 10:05:28'),
(322724,92738,1,124.241,8129.287,8253.528,'今日收益','2026-04-13 10:14:29','2026-04-13 10:14:29'),
(322733,92738,2,-1034.000,8253.528,7219.528,'用户提现','2026-04-13 13:06:37','2026-04-13 13:06:37'),
(322736,92738,1,127.491,7219.528,7347.019,'今日收益','2026-04-13 13:16:32','2026-04-13 13:16:32'),
(322754,92738,1,95.604,7347.019,7442.623,'今日收益','2026-04-14 09:59:25','2026-04-14 09:59:25'),
(322771,92738,1,123.113,7442.623,7565.736,'今日收益','2026-04-14 10:02:18','2026-04-14 10:02:18'),
(322780,92827,1,97.711,6147.447,6245.158,'今日收益','2026-04-14 10:04:11','2026-04-14 10:04:11'),
(322782,92738,1,121.781,7565.736,7687.517,'今日收益','2026-04-14 10:04:25','2026-04-14 10:04:25'),
(322798,92738,1,146.567,7687.517,7834.084,'今日收益','2026-04-14 11:31:02','2026-04-14 11:31:02'),
(322801,92738,1,138.803,7834.084,7972.887,'今日收益','2026-04-14 11:44:53','2026-04-14 11:44:53'),
(322811,92738,2,-1003.000,7972.887,6969.887,'用户提现','2026-04-14 14:35:05','2026-04-14 14:35:05'),
(322834,92738,2,-3372.000,6969.887,3597.887,'用户提现','2026-04-15 09:45:19','2026-04-15 09:45:19'),
(322835,92738,1,3372.000,3597.887,6969.887,'提现退还','2026-04-15 09:48:16','2026-04-15 09:48:16'),
(322836,92738,2,-3378.000,6969.887,3591.887,'用户提现','2026-04-15 09:52:14','2026-04-15 09:52:14'),
(322850,92738,1,143.205,3591.887,3735.092,'今日收益','2026-04-15 10:01:49','2026-04-15 10:01:49'),
(322854,92738,1,83.765,3735.092,3818.857,'今日收益','2026-04-15 10:01:59','2026-04-15 10:01:59'),
(322862,92738,1,142.967,3818.857,3961.824,'今日收益','2026-04-15 10:02:36','2026-04-15 10:02:36'),
(322873,92738,1,101.622,3961.824,4063.446,'今日收益','2026-04-15 10:03:20','2026-04-15 10:03:20'),
(322876,92738,1,131.315,4063.446,4194.761,'今日收益','2026-04-15 10:04:01','2026-04-15 10:04:01'),
(322878,92827,1,106.634,6245.158,6351.792,'今日收益','2026-04-15 10:05:15','2026-04-15 10:05:15'),
(322924,92827,1,101.426,6351.792,6453.218,'今日收益','2026-04-16 10:00:08','2026-04-16 10:00:08'),
(322944,92738,1,136.831,4194.761,4331.592,'今日收益','2026-04-16 10:02:45','2026-04-16 10:02:45'),
(322959,92738,1,110.787,4331.592,4442.379,'今日收益','2026-04-16 10:05:28','2026-04-16 10:05:28'),
(322967,92738,1,130.610,4442.379,4572.989,'今日收益','2026-04-16 10:08:41','2026-04-16 10:08:41'),
(322989,92738,2,-557.000,4572.989,4015.989,'用户提现','2026-04-16 14:15:26','2026-04-16 14:15:26'),
(322990,92738,1,84.906,4015.989,4100.895,'今日收益','2026-04-16 14:27:29','2026-04-16 14:27:29'),
(322995,92738,1,137.802,4100.895,4238.697,'今日收益','2026-04-16 15:15:45','2026-04-16 15:15:45'),
(323020,92827,1,82.930,6453.218,6536.148,'今日收益','2026-04-20 10:03:10','2026-04-20 10:03:10'),
(323037,92738,1,112.081,4238.697,4350.778,'今日收益','2026-04-20 14:09:16','2026-04-20 14:09:16'),
(323038,92738,1,133.073,4350.778,4483.851,'今日收益','2026-04-20 14:46:53','2026-04-20 14:46:53'),
(323074,92827,1,90.076,6536.148,6626.224,'今日收益','2026-04-21 10:03:34','2026-04-21 10:03:34'),
(323079,92738,1,137.066,4483.851,4620.917,'今日收益','2026-04-21 10:10:39','2026-04-21 10:10:39'),
(323099,92738,1,86.025,4620.917,4706.942,'今日收益','2026-04-21 14:14:48','2026-04-21 14:14:48'),
(323135,92738,1,85.671,4706.942,4792.613,'今日收益','2026-04-22 10:57:10','2026-04-22 10:57:10');
-- ---------- `wa_coupon_log` (40 rows) ----------
INSERT INTO `wa_coupon_log` VALUES
(255345,92827,1,88.000,0.000,88.000,'今日收益','2025-12-18 23:59:59','2025-12-19 00:05:02'),
(255380,92827,1,88.000,88.000,176.000,'今日收益','2025-12-19 23:59:59','2025-12-20 00:05:02'),
(255412,92827,1,88.000,176.000,264.000,'今日收益','2025-12-22 23:59:59','2025-12-23 00:05:01'),
(255446,92827,1,88.000,264.000,352.000,'今日收益','2025-12-23 23:59:59','2025-12-24 00:05:02'),
(255517,92827,1,88.000,352.000,440.000,'今日收益','2025-12-25 23:59:59','2025-12-26 00:05:02'),
(255552,92827,1,88.000,440.000,528.000,'今日收益','2025-12-26 23:59:59','2025-12-27 00:05:02'),
(255586,92827,1,88.000,528.000,616.000,'今日收益','2025-12-29 23:59:59','2025-12-30 00:05:01'),
(255619,92827,1,88.000,616.000,704.000,'今日收益','2025-12-30 23:59:59','2025-12-31 00:05:01'),
(255654,92827,1,88.000,704.000,792.000,'今日收益','2025-12-31 23:59:59','2026-01-01 00:05:02'),
(255691,92827,1,88.000,792.000,880.000,'今日收益','2026-01-01 23:59:59','2026-01-02 00:05:01'),
(255725,92827,1,88.000,880.000,968.000,'今日收益','2026-01-02 23:59:59','2026-01-03 00:05:02'),
(255759,92827,1,88.000,968.000,1056.000,'今日收益','2026-01-05 23:59:59','2026-01-06 00:05:01'),
(255800,92827,1,88.000,1056.000,1144.000,'今日收益','2026-01-06 23:59:59','2026-01-07 00:05:02'),
(255838,92827,1,88.000,1144.000,1232.000,'今日收益','2026-01-07 23:59:59','2026-01-08 00:05:01'),
(255873,92827,1,88.000,1232.000,1320.000,'今日收益','2026-01-08 23:59:59','2026-01-09 00:05:01'),
(255911,92827,1,88.000,1320.000,1408.000,'今日收益','2026-01-09 23:59:59','2026-01-10 00:05:02'),
(255950,92827,1,88.000,1408.000,1496.000,'今日收益','2026-01-12 23:59:59','2026-01-13 00:05:02'),
(255986,92827,1,88.000,1496.000,1584.000,'今日收益','2026-01-13 23:59:59','2026-01-14 00:05:01'),
(256024,92827,1,88.000,1584.000,1672.000,'今日收益','2026-01-14 23:59:59','2026-01-15 00:05:01'),
(256062,92827,1,88.000,1672.000,1760.000,'今日收益','2026-01-15 23:59:59','2026-01-16 00:05:02'),
(256101,92827,1,88.000,1760.000,1848.000,'今日收益','2026-01-16 23:59:59','2026-01-17 00:05:01'),
(256136,92827,1,88.000,1848.000,1936.000,'今日收益','2026-01-19 23:59:59','2026-01-20 00:05:01'),
(256283,92827,1,88.000,1936.000,2024.000,'今日收益','2026-01-23 23:59:59','2026-01-24 00:05:01'),
(256326,92827,1,88.000,2024.000,2112.000,'今日收益','2026-01-26 23:59:59','2026-01-27 00:05:01'),
(256363,92827,1,88.000,2112.000,2200.000,'今日收益','2026-01-27 23:59:59','2026-01-28 00:05:01'),
(256400,92827,1,88.000,2200.000,2288.000,'今日收益','2026-01-28 23:59:59','2026-01-29 00:05:02'),
(256436,92827,1,88.000,2288.000,2376.000,'今日收益','2026-01-29 23:59:59','2026-01-30 00:05:01'),
(256912,92738,1,88.000,0.000,88.000,'今日收益','2026-03-17 23:59:59','2026-03-18 00:05:00'),
(256917,92738,1,88.000,88.000,176.000,'今日收益','2026-03-18 23:59:59','2026-03-19 00:05:00'),
(256925,92738,1,288.000,176.000,464.000,'今日收益','2026-03-19 23:59:59','2026-03-20 00:05:00'),
(256935,92738,1,188.000,464.000,652.000,'今日收益','2026-03-20 23:59:59','2026-03-21 00:05:00'),
(256946,92738,1,188.000,652.000,840.000,'今日收益','2026-03-23 23:59:59','2026-03-24 00:05:00'),
(256956,92738,1,88.000,840.000,928.000,'今日收益','2026-03-24 23:59:59','2026-03-25 00:05:01'),
(256971,92738,1,88.000,928.000,1016.000,'今日收益','2026-03-25 23:59:59','2026-03-26 00:05:00'),
(257089,92738,1,88.000,1016.000,1104.000,'今日收益','2026-04-07 23:59:59','2026-04-08 00:05:00'),
(257103,92738,1,88.000,1104.000,1192.000,'今日收益','2026-04-08 23:59:59','2026-04-09 00:05:00'),
(257120,92738,1,88.000,1192.000,1280.000,'今日收益','2026-04-09 23:59:59','2026-04-10 00:05:00'),
(257133,92738,1,88.000,1280.000,1368.000,'今日收益','2026-04-10 23:59:59','2026-04-11 00:05:00'),
(257144,92738,1,88.000,1368.000,1456.000,'今日收益','2026-04-13 23:59:59','2026-04-14 00:05:00'),
(257154,92738,1,88.000,1456.000,1544.000,'今日收益','2026-04-14 23:59:59','2026-04-15 00:05:00');
-- ---------- `eb_user_integral_record` (174 rows) ----------
INSERT INTO `eb_user_integral_record` VALUES
(2574,92738,'33','selfbonus',1,'个人奖金奖励',138.150,138,'个人奖金变动奖励奖金金额276.300积分138',3,0,0,'2026-02-19 02:23:00','2026-02-19 02:23:00',33),
(2576,92827,'36','selfbonus',1,'个人奖金奖励',160.438,160,'个人奖金变动奖励奖金金额320.877积分160',3,0,0,'2026-02-19 02:28:00','2026-02-19 02:28:00',36),
(2608,92738,'order53330177150998248328316','order',2,'用户订单付款成功',138.000,0,'订单支付抵扣138积分购买商品',3,0,0,'2026-02-19 14:07:00','2026-02-19 14:07:00',NULL),
(2634,92738,'88','selfbonus',1,'个人奖金奖励',118.778,118,'个人奖金变动奖励奖金金额237.557积分118',3,0,0,'2026-02-20 02:22:00','2026-02-20 02:22:00',88),
(2643,92827,'97','selfbonus',1,'个人奖金奖励',150.624,311,'个人奖金变动奖励奖金金额301.248积分150',3,0,0,'2026-02-20 03:07:00','2026-02-20 03:07:00',97),
(2686,92738,'133','selfbonus',1,'个人奖金奖励',122.342,241,'个人奖金变动奖励奖金金额244.684积分122',3,0,0,'2026-02-23 02:01:00','2026-02-23 02:01:00',133),
(2689,92827,'142','selfbonus',1,'个人奖金奖励',170.209,481,'个人奖金变动奖励奖金金额340.418积分170',3,0,0,'2026-02-23 02:02:00','2026-02-23 02:02:00',142),
(2761,92738,'207','selfbonus',1,'个人奖金奖励',125.771,367,'个人奖金变动奖励奖金金额251.543积分125',3,0,0,'2026-02-24 02:05:00','2026-02-24 02:05:00',207),
(2799,92827,'246','selfbonus',1,'个人奖金奖励',158.382,639,'个人奖金变动奖励奖金金额316.764积分158',3,0,0,'2026-02-24 07:00:00','2026-02-24 07:00:00',246),
(2839,92738,'283','selfbonus',1,'个人奖金奖励',126.733,493,'个人奖金变动奖励奖金金额253.466积分126',3,0,0,'2026-02-25 02:15:00','2026-02-25 02:15:00',283),
(2847,92827,'291','selfbonus',1,'个人奖金奖励',141.977,781,'个人奖金变动奖励奖金金额283.955积分141',3,0,0,'2026-02-25 03:21:00','2026-02-25 03:21:00',291),
(2878,92738,'316','selfbonus',1,'个人奖金奖励',177.421,671,'个人奖金变动奖励奖金金额354.843积分177',3,0,0,'2026-02-26 02:02:00','2026-02-26 02:02:00',316),
(2921,92827,'361','selfbonus',1,'个人奖金奖励',133.949,915,'个人奖金变动奖励奖金金额267.899积分133',3,0,0,'2026-02-26 04:52:00','2026-02-26 04:52:00',361),
(2956,92738,'399','selfbonus',1,'个人奖金奖励',119.444,790,'个人奖金变动奖励奖金金额238.889积分119',3,0,0,'2026-02-27 02:05:00','2026-02-27 02:05:00',399),
(2961,92827,'403','selfbonus',1,'个人奖金奖励',148.407,1063,'个人奖金变动奖励奖金金额296.815积分148',3,0,0,'2026-02-27 02:06:00','2026-02-27 02:06:00',403),
(2990,92738,'order81152177216655907318829','order',2,'用户订单付款成功',16.000,774,'订单支付抵扣16积分购买商品',3,0,0,'2026-02-27 04:30:00','2026-02-27 04:30:00',NULL),
(2991,92738,'order64483177216661181274432','order',2,'用户订单付款成功',198.000,570,'订单支付抵扣198积分购买商品',3,0,0,'2026-02-27 04:31:00','2026-02-27 04:31:00',NULL),
(2992,92738,'order90315177216663203753390','order',2,'用户订单付款成功',6.000,570,'订单支付抵扣6积分购买商品',3,0,0,'2026-02-27 04:31:00','2026-02-27 04:31:00',NULL),
(2993,92738,'order43546177216691840360834','order',2,'用户订单付款成功',40.000,530,'订单支付抵扣40积分购买商品',3,0,0,'2026-02-27 04:36:00','2026-02-27 04:36:00',NULL),
(3029,92827,'446','selfbonus',1,'个人奖金奖励',143.836,1207,'个人奖金变动奖励奖金金额287.673积分143',3,0,0,'2026-03-02 02:02:01','2026-03-02 02:02:01',446),
(3084,92738,'493','selfbonus',1,'个人奖金奖励',126.524,657,'个人奖金变动奖励奖金金额253.048积分126',3,0,0,'2026-03-02 06:58:02','2026-03-02 06:58:02',493),
(3117,92827,'525','selfbonus',1,'个人奖金奖励',147.497,1355,'个人奖金变动奖励奖金金额294.994积分147',3,0,0,'2026-03-03 02:11:00','2026-03-03 02:11:00',525),
(3145,92738,'554','selfbonus',1,'个人奖金奖励',130.984,788,'个人奖金变动奖励奖金金额261.969积分130',3,0,0,'2026-03-03 05:54:02','2026-03-03 05:54:02',554),
(3196,92738,'602','selfbonus',1,'个人奖金奖励',150.177,938,'个人奖金变动奖励奖金金额300.355积分150',3,0,0,'2026-03-04 02:06:02','2026-03-04 02:06:02',602),
(3202,92827,'611','selfbonus',1,'个人奖金奖励',161.501,1516,'个人奖金变动奖励奖金金额323.003积分161',3,0,0,'2026-03-04 04:46:02','2026-03-04 04:46:02',611),
(3203,92827,'611','selfbonus',1,'个人奖金奖励',161.501,1678,'个人奖金变动奖励奖金金额323.003积分161',3,0,0,'2026-03-04 04:46:04','2026-03-04 04:46:04',611),
(3236,92738,'648','selfbonus',1,'个人奖金奖励',156.479,1094,'个人奖金变动奖励奖金金额312.959积分156',3,0,0,'2026-03-05 02:03:01','2026-03-05 02:03:01',648),
(3237,92827,'647','selfbonus',1,'个人奖金奖励',156.793,1835,'个人奖金变动奖励奖金金额313.586积分156',3,0,0,'2026-03-05 02:03:01','2026-03-05 02:03:01',647),
(3299,92827,'703','selfbonus',1,'个人奖金奖励',142.779,1977,'个人奖金变动奖励奖金金额285.559积分142',3,0,0,'2026-03-06 02:02:03','2026-03-06 02:02:03',703),
(3301,92738,'701','selfbonus',1,'个人奖金奖励',144.025,1238,'个人奖金变动奖励奖金金额288.050积分144',3,0,0,'2026-03-06 02:02:03','2026-03-06 02:02:03',701),
(3351,92827,'order56575177278039716981154','order',2,'用户订单付款成功',158.000,1819,'订单支付抵扣158积分购买商品',3,0,0,'2026-03-06 07:00:01','2026-03-06 07:00:01',NULL),
(3352,92827,'order48973177278042001138676','order',2,'用户订单付款成功',280.000,1184,'订单支付抵扣280积分购买商品',3,0,0,'2026-03-06 07:01:01','2026-03-06 07:01:01',NULL),
(3353,92827,'order70907177278045167978700','order',2,'用户订单付款成功',39.000,1184,'订单支付抵扣39积分购买商品',3,0,0,'2026-03-06 07:01:01','2026-03-06 07:01:01',NULL),
(3354,92827,'order36916177278045918468986','order',2,'用户订单付款成功',316.000,1184,'订单支付抵扣316积分购买商品',3,0,0,'2026-03-06 07:01:01','2026-03-06 07:01:01',NULL),
(3355,92827,'order15066177278047415274322','order',2,'用户订单付款成功',40.000,1066,'订单支付抵扣40积分购买商品',3,0,0,'2026-03-06 07:02:01','2026-03-06 07:02:01',NULL),
(3357,92827,'order22712177278048380363920','order',2,'用户订单付款成功',78.000,1066,'订单支付抵扣78积分购买商品',3,0,0,'2026-03-06 07:02:01','2026-03-06 07:02:01',NULL),
(3358,92827,'order75437177278054789222811','order',2,'用户订单付款成功',17.000,551,'订单支付抵扣17积分购买商品',3,0,0,'2026-03-06 07:03:00','2026-03-06 07:03:00',NULL),
(3359,92827,'order17881177278055766426513','order',2,'用户订单付款成功',498.000,551,'订单支付抵扣498积分购买商品',3,0,0,'2026-03-06 07:03:01','2026-03-06 07:03:01',NULL),
(3369,92827,'765','selfbonus',1,'个人奖金奖励',150.276,702,'个人奖金变动奖励奖金金额300.552积分150',3,0,0,'2026-03-09 02:02:01','2026-03-09 02:02:01',765),
(3379,92738,'767','selfbonus',1,'个人奖金奖励',159.628,1398,'个人奖金变动奖励奖金金额319.257积分159',3,0,0,'2026-03-09 02:03:01','2026-03-09 02:03:01',767),
(3471,92738,'854','selfbonus',1,'个人奖金奖励',158.183,1556,'个人奖金变动奖励奖金金额316.367积分158',3,0,0,'2026-03-10 02:19:01','2026-03-10 02:19:01',854),
(3506,92738,'order21693177312544524179804','order',2,'用户订单付款成功',138.000,1418,'订单支付抵扣138积分购买商品',3,0,0,'2026-03-10 06:51:00','2026-03-10 06:51:00',NULL),
(3513,92827,'891','selfbonus',1,'个人奖金奖励',154.000,856,'个人奖金变动奖励奖金金额308.000积分154',3,0,0,'2026-03-10 07:42:01','2026-03-10 07:42:01',891),
(3531,92738,'914','selfbonus',1,'个人奖金奖励',176.900,1595,'个人奖金变动奖励奖金金额353.801积分176',3,0,0,'2026-03-11 02:04:01','2026-03-11 02:04:01',914),
(3555,92827,'927','selfbonus',1,'个人奖金奖励',156.144,1012,'个人奖金变动奖励奖金金额312.289积分156',3,0,0,'2026-03-11 02:08:01','2026-03-11 02:08:01',927),
(3633,92738,'1005','selfbonus',1,'个人奖金奖励',179.663,1775,'个人奖金变动奖励奖金金额359.326积分179',3,0,0,'2026-03-12 04:16:00','2026-03-12 04:16:00',1005),
(3655,92738,'order65105177330346342376245','order',2,'用户订单付款成功',1689.000,86,'订单支付抵扣1689积分购买商品',3,0,0,'2026-03-12 08:18:00','2026-03-12 08:18:00',NULL),
(3661,92827,'1034','selfbonus',1,'个人奖金奖励',185.417,1197,'个人奖金变动奖励奖金金额370.834积分185',3,0,0,'2026-03-13 02:02:01','2026-03-13 02:02:01',1034),
(3687,92738,'1060','selfbonus',1,'个人奖金奖励',128.728,214,'个人奖金变动奖励奖金金额257.456积分128',3,0,0,'2026-03-13 02:07:01','2026-03-13 02:07:01',1060),
(3746,92738,'1100','selfbonus',1,'个人奖金奖励',184.561,399,'个人奖金变动奖励奖金金额369.122积分184',3,0,0,'2026-03-16 02:05:01','2026-03-16 02:05:01',1100),
(3758,92827,'1117','selfbonus',1,'个人奖金奖励',189.116,1386,'个人奖金变动奖励奖金金额378.232积分189',3,0,0,'2026-03-16 02:27:01','2026-03-16 02:27:01',1117),
(3788,92738,'1145','selfbonus',1,'个人奖金奖励',166.929,566,'个人奖金变动奖励奖金金额333.858积分166',3,0,0,'2026-03-17 02:02:01','2026-03-17 02:02:01',1145),
(3795,92738,'1146','selfbonus',1,'个人奖金奖励',168.568,734,'个人奖金变动奖励奖金金额337.137积分168',3,0,0,'2026-03-17 02:03:01','2026-03-17 02:03:01',1146),
(3827,92827,'1177','selfbonus',1,'个人奖金奖励',192.130,1578,'个人奖金变动奖励奖金金额384.261积分192',3,0,0,'2026-03-17 06:55:01','2026-03-17 06:55:01',1177),
(3860,92827,'1204','selfbonus',1,'个人奖金奖励',200.633,1779,'个人奖金变动奖励奖金金额401.267积分200',3,0,0,'2026-03-18 02:06:01','2026-03-18 02:06:01',1204),
(3867,92738,'1216','selfbonus',1,'个人奖金奖励',183.883,918,'个人奖金变动奖励奖金金额367.767积分183',3,0,0,'2026-03-18 02:14:00','2026-03-18 02:14:00',1216),
(3869,92738,'1217','selfbonus',1,'个人奖金奖励',181.014,1099,'个人奖金变动奖励奖金金额362.028积分181',3,0,0,'2026-03-18 02:16:01','2026-03-18 02:16:01',1217),
(3912,92738,'1257','selfbonus',1,'个人奖金奖励',150.177,1250,'个人奖金变动奖励奖金金额300.354积分150',3,0,0,'2026-03-19 02:04:01','2026-03-19 02:04:01',1257),
(3916,92827,'1261','selfbonus',1,'个人奖金奖励',186.444,1966,'个人奖金变动奖励奖金金额372.889积分186',3,0,0,'2026-03-19 02:05:01','2026-03-19 02:05:01',1261),
(3927,92738,'1274','selfbonus',1,'个人奖金奖励',121.051,1371,'个人奖金变动奖励奖金金额242.103积分121',3,0,0,'2026-03-19 02:08:01','2026-03-19 02:08:01',1274),
(3936,92738,'1282','selfbonus',1,'个人奖金奖励',128.213,1499,'个人奖金变动奖励奖金金额256.426积分128',3,0,0,'2026-03-19 02:43:01','2026-03-19 02:43:01',1282),
(3938,92738,'1284','selfbonus',1,'个人奖金奖励',103.326,1602,'个人奖金变动奖励奖金金额206.652积分103',3,0,0,'2026-03-19 02:45:01','2026-03-19 02:45:01',1284),
(3974,92738,'1308','selfbonus',1,'个人奖金奖励',152.958,1755,'个人奖金变动奖励奖金金额305.916积分152',3,0,0,'2026-03-20 02:02:01','2026-03-20 02:02:01',1308),
(3985,92738,'1317','selfbonus',1,'个人奖金奖励',108.302,1863,'个人奖金变动奖励奖金金额216.604积分108',3,0,0,'2026-03-20 02:04:01','2026-03-20 02:04:01',1317),
(3988,92738,'1326','selfbonus',1,'个人奖金奖励',142.354,2006,'个人奖金变动奖励奖金金额284.709积分142',3,0,0,'2026-03-20 02:05:01','2026-03-20 02:05:01',1326),
(4015,92827,'1349','selfbonus',1,'个人奖金奖励',155.142,2121,'个人奖金变动奖励奖金金额310.284积分155',3,0,0,'2026-03-20 02:55:01','2026-03-20 02:55:01',1349),
(4037,92738,'order74425177408743283472486','order',2,'用户订单付款成功',328.000,1678,'订单支付抵扣328积分购买商品',3,0,0,'2026-03-21 10:04:00','2026-03-21 10:04:00',NULL),
(4038,92738,'order43850177408751498176562','order',2,'用户订单付款成功',138.000,1540,'订单支付抵扣138积分购买商品',3,0,0,'2026-03-21 10:06:00','2026-03-21 10:06:00',NULL),
(4039,92738,'order42948177408757558794042','order',2,'用户订单付款成功',138.000,1402,'订单支付抵扣138积分购买商品',3,0,0,'2026-03-21 10:07:00','2026-03-21 10:07:00',NULL),
(4040,92738,'order27637177408766345096957','order',2,'用户订单付款成功',1104.000,298,'订单支付抵扣1104积分购买商品',3,0,0,'2026-03-21 10:08:00','2026-03-21 10:08:00',NULL),
(4041,92738,'order71066177408773069784463','order',2,'用户订单付款成功',198.000,100,'订单支付抵扣198积分购买商品',3,0,0,'2026-03-21 10:09:00','2026-03-21 10:09:00',NULL),
(4049,92738,'1370','selfbonus',1,'个人奖金奖励',102.289,202,'个人奖金变动奖励奖金金额204.579积分102',3,0,0,'2026-03-23 02:03:01','2026-03-23 02:03:01',1370),
(4056,92827,'1364','selfbonus',1,'个人奖金奖励',148.943,2270,'个人奖金变动奖励奖金金额297.887积分148',3,0,0,'2026-03-23 02:03:01','2026-03-23 02:03:01',1364),
(4069,92738,'1392','selfbonus',1,'个人奖金奖励',114.170,316,'个人奖金变动奖励奖金金额228.340积分114',3,0,0,'2026-03-23 02:06:01','2026-03-23 02:06:01',1392),
(4079,92738,'1396','selfbonus',1,'个人奖金奖励',187.880,504,'个人奖金变动奖励奖金金额375.760积分187',3,0,0,'2026-03-23 02:08:01','2026-03-23 02:08:01',1396),
(4115,92738,'1437','selfbonus',1,'个人奖金奖励',121.781,626,'个人奖金变动奖励奖金金额243.563积分121',3,0,0,'2026-03-24 02:03:01','2026-03-24 02:03:01',1437),
(4116,92827,'1436','selfbonus',1,'个人奖金奖励',144.605,2414,'个人奖金变动奖励奖金金额289.210积分144',3,0,0,'2026-03-24 02:03:01','2026-03-24 02:03:01',1436),
(4124,92738,'1441','selfbonus',1,'个人奖金奖励',132.276,758,'个人奖金变动奖励奖金金额264.552积分132',3,0,0,'2026-03-24 02:04:01','2026-03-24 02:04:01',1441),
(4128,93140,'1446','selfbonus',1,'个人奖金奖励',101.866,101,'个人奖金变动奖励奖金金额203.733积分101',3,0,0,'2026-03-24 02:05:00','2026-03-24 02:05:00',1446),
(4192,92738,'1506','selfbonus',1,'个人奖金奖励',121.338,880,'个人奖金变动奖励奖金金额242.677积分121',3,0,0,'2026-03-25 02:05:01','2026-03-25 02:05:01',1506),
(4194,93140,'1514','selfbonus',1,'个人奖金奖励',107.128,208,'个人奖金变动奖励奖金金额214.257积分107',3,0,0,'2026-03-25 02:06:01','2026-03-25 02:06:01',1514),
(4215,92827,'1525','selfbonus',1,'个人奖金奖励',127.416,2542,'个人奖金变动奖励奖金金额254.832积分127',3,0,0,'2026-03-25 02:23:01','2026-03-25 02:23:01',1525),
(4232,92738,'1536','selfbonus',1,'个人奖金奖励',185.661,1065,'个人奖金变动奖励奖金金额371.323积分185',3,0,0,'2026-03-25 03:34:01','2026-03-25 03:34:01',1536),
(4276,93150,'1581','selfbonus',1,'个人奖金奖励',103.659,103,'个人奖金变动奖励奖金金额207.318积分103',3,0,0,'2026-03-26 02:05:01','2026-03-26 02:05:01',1581),
(4280,92738,'1584','selfbonus',1,'个人奖金奖励',142.600,1208,'个人奖金变动奖励奖金金额285.201积分142',3,0,0,'2026-03-26 02:06:01','2026-03-26 02:06:01',1584),
(4283,92827,'1586','selfbonus',1,'个人奖金奖励',118.581,2660,'个人奖金变动奖励奖金金额237.163积分118',3,0,0,'2026-03-26 02:07:01','2026-03-26 02:07:01',1586),
(4287,93140,'1595','selfbonus',1,'个人奖金奖励',113.879,322,'个人奖金变动奖励奖金金额227.758积分113',3,0,0,'2026-03-26 02:09:01','2026-03-26 02:09:01',1595),
(4315,92738,'1617','selfbonus',1,'个人奖金奖励',146.878,1355,'个人奖金变动奖励奖金金额293.757积分146',3,0,0,'2026-03-27 02:00:01','2026-03-27 02:00:01',1617),
(4323,93150,'1631','selfbonus',1,'个人奖金奖励',105.730,209,'个人奖金变动奖励奖金金额211.460积分105',3,0,0,'2026-03-27 02:02:01','2026-03-27 02:02:01',1631),
(4334,92827,'1634','selfbonus',1,'个人奖金奖励',128.499,2789,'个人奖金变动奖励奖金金额256.999积分128',3,0,0,'2026-03-27 02:03:01','2026-03-27 02:03:01',1634),
(4371,93140,'1673','selfbonus',1,'个人奖金奖励',115.127,438,'个人奖金变动奖励奖金金额230.255积分115',3,0,0,'2026-03-27 05:29:01','2026-03-27 05:29:01',1673),
(4379,92827,'order84514177461129994374488','order',2,'用户订单付款成功',138.000,2651,'订单支付抵扣138积分购买商品',3,0,0,'2026-03-27 11:35:00','2026-03-27 11:35:00',NULL),
(4380,92827,'order41479177461133957328078','order',2,'用户订单付款成功',138.000,2513,'订单支付抵扣138积分购买商品',3,0,0,'2026-03-27 11:36:00','2026-03-27 11:36:00',NULL),
(4381,92827,'order98718177461140058776240','order',2,'用户订单付款成功',2484.000,29,'订单支付抵扣2484积分购买商品',3,0,0,'2026-03-27 11:37:00','2026-03-27 11:37:00',NULL),
(4442,92738,'1736','selfbonus',1,'个人奖金奖励',139.231,1494,'个人奖金变动奖励奖金金额278.462积分139',3,0,0,'2026-03-30 04:09:01','2026-03-30 04:09:01',1736),
(4449,93150,'1742','selfbonus',1,'个人奖金奖励',102.289,311,'个人奖金变动奖励奖金金额204.579积分102',3,0,0,'2026-03-30 06:16:01','2026-03-30 06:16:01',1742),
(4456,92827,'1750','selfbonus',1,'个人奖金奖励',172.155,201,'个人奖金变动奖励奖金金额344.311积分172',3,0,0,'2026-03-30 07:13:01','2026-03-30 07:13:01',1750),
(4458,93140,'1752','selfbonus',1,'个人奖金奖励',118.581,556,'个人奖金变动奖励奖金金额237.163积分118',3,0,0,'2026-03-30 07:44:01','2026-03-30 07:44:01',1752),
(4480,93140,'1776','selfbonus',1,'个人奖金奖励',124.439,681,'个人奖金变动奖励奖金金额248.878积分124',3,0,0,'2026-03-31 02:06:01','2026-03-31 02:06:01',1776),
(4484,93150,'1780','selfbonus',1,'个人奖金奖励',113.271,424,'个人奖金变动奖励奖金金额226.542积分113',3,0,0,'2026-03-31 02:07:01','2026-03-31 02:07:01',1780),
(4487,92738,'1783','selfbonus',1,'个人奖金奖励',114.509,1608,'个人奖金变动奖励奖金金额229.019积分114',3,0,0,'2026-03-31 02:08:01','2026-03-31 02:08:01',1783),
(4520,92827,'1813','selfbonus',1,'个人奖金奖励',191.357,392,'个人奖金变动奖励奖金金额382.715积分191',3,0,0,'2026-03-31 07:37:01','2026-03-31 07:37:01',1813),
(4536,93150,'1829','selfbonus',1,'个人奖金奖励',117.866,542,'个人奖金变动奖励奖金金额235.733积分117',3,0,0,'2026-04-01 02:02:01','2026-04-01 02:02:01',1829),
(4552,92827,'1840','selfbonus',1,'个人奖金奖励',188.447,581,'个人奖金变动奖励奖金金额376.894积分188',3,0,0,'2026-04-01 02:04:01','2026-04-01 02:04:01',1840),
(4564,92738,'1856','selfbonus',1,'个人奖金奖励',141.596,1750,'个人奖金变动奖励奖金金额283.193积分141',3,0,0,'2026-04-01 02:07:01','2026-04-01 02:07:01',1856),
(4594,93140,'1886','selfbonus',1,'个人奖金奖励',116.669,797,'个人奖金变动奖励奖金金额233.338积分116',3,0,0,'2026-04-01 11:37:01','2026-04-01 11:37:01',1886),
(4616,93150,'1912','selfbonus',1,'个人奖金奖励',103.045,645,'个人奖金变动奖励奖金金额206.091积分103',3,0,0,'2026-04-02 02:04:01','2026-04-02 02:04:01',1912),
(4636,93140,'1927','selfbonus',1,'个人奖金奖励',129.577,927,'个人奖金变动奖励奖金金额259.154积分129',3,0,0,'2026-04-02 02:07:01','2026-04-02 02:07:01',1927),
(4659,92738,'1947','selfbonus',1,'个人奖金奖励',149.775,1900,'个人奖金变动奖励奖金金额299.551积分149',3,0,0,'2026-04-02 08:04:01','2026-04-02 08:04:01',1947),
(4660,92827,'1946','selfbonus',1,'个人奖金奖励',188.676,769,'个人奖金变动奖励奖金金额377.353积分188',3,0,0,'2026-04-02 08:04:01','2026-04-02 08:04:01',1946),
(4694,93140,'1988','selfbonus',1,'个人奖金奖励',125.127,1052,'个人奖金变动奖励奖金金额250.255积分125',3,0,0,'2026-04-03 02:12:01','2026-04-03 02:12:01',1988),
(4714,92738,'1968','selfbonus',1,'个人奖金奖励',150.220,2050,'个人奖金变动奖励奖金金额300.440积分150',3,0,0,'2026-04-03 02:12:01','2026-04-03 02:12:01',1968),
(4722,93150,'1960','selfbonus',1,'个人奖金奖励',105.222,751,'个人奖金变动奖励奖金金额210.445积分105',3,0,0,'2026-04-03 02:12:01','2026-04-03 02:12:01',1960),
(4729,92738,'order35464177518377840514243','order',2,'用户订单付款成功',2016.000,34,'订单支付抵扣2016积分购买商品',3,0,0,'2026-04-03 02:40:00','2026-04-03 02:40:00',NULL),
(4739,92827,'2019','selfbonus',1,'个人奖金奖励',167.563,937,'个人奖金变动奖励奖金金额335.127积分167',3,0,0,'2026-04-03 07:10:01','2026-04-03 07:10:01',2019),
(4744,92827,'2019','selfbonus',1,'个人奖金奖励',167.563,1105,'个人奖金变动奖励奖金金额335.127积分167',3,0,0,'2026-04-03 07:10:03','2026-04-03 07:10:03',2019),
(4798,92827,'2051','selfbonus',1,'个人奖金奖励',161.406,1266,'个人奖金变动奖励奖金金额322.813积分161',3,0,0,'2026-04-06 02:05:01','2026-04-06 02:05:01',2051),
(4800,93140,'2049','selfbonus',1,'个人奖金奖励',107.687,1160,'个人奖金变动奖励奖金金额215.374积分107',3,0,0,'2026-04-06 02:05:01','2026-04-06 02:05:01',2049),
(4824,92738,'2077','selfbonus',1,'个人奖金奖励',158.897,193,'个人奖金变动奖励奖金金额317.794积分158',3,0,0,'2026-04-06 02:50:01','2026-04-06 02:50:01',2077),
(4835,93150,'2089','selfbonus',1,'个人奖金奖励',104.838,855,'个人奖金变动奖励奖金金额209.676积分104',3,0,0,'2026-04-06 03:50:01','2026-04-06 03:50:01',2089),
(4894,92738,'2135','selfbonus',1,'个人奖金奖励',110.597,303,'个人奖金变动奖励奖金金额221.195积分110',3,0,0,'2026-04-07 02:04:01','2026-04-07 02:04:01',2135),
(4899,92738,'2140','selfbonus',1,'个人奖金奖励',139.070,443,'个人奖金变动奖励奖金金额278.140积分139',3,0,0,'2026-04-07 02:08:01','2026-04-07 02:08:01',2140),
(4929,92827,'2172','selfbonus',1,'个人奖金奖励',155.381,1421,'个人奖金变动奖励奖金金额310.762积分155',3,0,0,'2026-04-07 02:22:01','2026-04-07 02:22:01',2172),
(4942,93140,'2185','selfbonus',1,'个人奖金奖励',105.512,1265,'个人奖金变动奖励奖金金额211.024积分105',3,0,0,'2026-04-07 06:03:00','2026-04-07 06:03:00',2185),
(4952,93150,'2195','selfbonus',1,'个人奖金奖励',102.781,958,'个人奖金变动奖励奖金金额205.562积分102',3,0,0,'2026-04-07 06:15:01','2026-04-07 06:15:01',2195),
(4986,93140,'order26667177560992185495558','order',2,'用户订单付款成功',1188.000,77,'订单支付抵扣1188积分购买商品',3,0,0,'2026-04-08 00:59:00','2026-04-08 00:59:00',NULL),
(5028,93140,'2243','selfbonus',1,'个人奖金奖励',164.149,241,'个人奖金变动奖励奖金金额328.298积分164',3,0,0,'2026-04-08 02:12:01','2026-04-08 02:12:01',2243),
(5029,92827,'2246','selfbonus',1,'个人奖金奖励',114.979,1536,'个人奖金变动奖励奖金金额229.959积分114',3,0,0,'2026-04-08 02:16:01','2026-04-08 02:16:01',2246),
(5052,92738,'2262','selfbonus',1,'个人奖金奖励',155.465,598,'个人奖金变动奖励奖金金额310.931积分155',3,0,0,'2026-04-08 03:55:00','2026-04-08 03:55:00',2262),
(5058,92738,'2268','selfbonus',1,'个人奖金奖励',112.907,711,'个人奖金变动奖励奖金金额225.814积分112',3,0,0,'2026-04-08 05:27:01','2026-04-08 05:27:01',2268),
(5074,93150,'2285','selfbonus',1,'个人奖金奖励',106.178,1064,'个人奖金变动奖励奖金金额212.357积分106',3,0,0,'2026-04-08 07:20:00','2026-04-08 07:20:00',2285),
(5112,93150,'2314','selfbonus',1,'个人奖金奖励',103.086,1167,'个人奖金变动奖励奖金金额206.172积分103',3,0,0,'2026-04-09 02:05:01','2026-04-09 02:05:01',2314),
(5115,92827,'2318','selfbonus',1,'个人奖金奖励',167.662,1704,'个人奖金变动奖励奖金金额335.324积分167',3,0,0,'2026-04-09 02:06:01','2026-04-09 02:06:01',2318),
(5148,92738,'2353','selfbonus',1,'个人奖金奖励',115.127,826,'个人奖金变动奖励奖金金额230.255积分115',3,0,0,'2026-04-09 02:52:01','2026-04-09 02:52:01',2353),
(5152,92738,'2358','selfbonus',1,'个人奖金奖励',139.308,965,'个人奖金变动奖励奖金金额278.617积分139',3,0,0,'2026-04-09 05:03:01','2026-04-09 05:03:01',2358),
(5163,93140,'2368','selfbonus',1,'个人奖金奖励',117.672,359,'个人奖金变动奖励奖金金额235.345积分117',3,0,0,'2026-04-09 06:55:00','2026-04-09 06:55:00',2368),
(5187,93150,'2389','selfbonus',1,'个人奖金奖励',112.311,1280,'个人奖金变动奖励奖金金额224.623积分112',3,0,0,'2026-04-10 02:03:01','2026-04-10 02:03:01',2389),
(5224,93140,'2426','selfbonus',1,'个人奖金奖励',123.041,482,'个人奖金变动奖励奖金金额246.083积分123',3,0,0,'2026-04-10 03:11:01','2026-04-10 03:11:01',2426),
(5225,92827,'2427','selfbonus',1,'个人奖金奖励',169.789,1874,'个人奖金变动奖励奖金金额339.578积分169',3,0,0,'2026-04-10 03:12:01','2026-04-10 03:12:01',2427),
(5230,92738,'2432','selfbonus',1,'个人奖金奖励',114.885,1080,'个人奖金变动奖励奖金金额229.771积分114',3,0,0,'2026-04-10 04:36:01','2026-04-10 04:36:01',2432),
(5233,92738,'2435','selfbonus',1,'个人奖金奖励',143.488,1224,'个人奖金变动奖励奖金金额286.976积分143',3,0,0,'2026-04-10 05:30:01','2026-04-10 05:30:01',2435),
(5283,93140,'2470','selfbonus',1,'个人奖金奖励',125.058,607,'个人奖金变动奖励奖金金额250.117积分125',3,0,0,'2026-04-13 02:02:01','2026-04-13 02:02:01',2470),
(5288,93150,'2466','selfbonus',1,'个人奖金奖励',118.755,1399,'个人奖金变动奖励奖金金额237.510积分118',3,0,0,'2026-04-13 02:02:01','2026-04-13 02:02:01',2466),
(5310,92827,'2488','selfbonus',1,'个人奖金奖励',180.111,2054,'个人奖金变动奖励奖金金额360.222积分180',3,0,0,'2026-04-13 02:06:01','2026-04-13 02:06:01',2488),
(5320,92738,'2499','selfbonus',1,'个人奖金奖励',136.325,1360,'个人奖金变动奖励奖金金额272.650积分136',3,0,0,'2026-04-13 02:13:01','2026-04-13 02:13:01',2499),
(5342,92738,'2521','selfbonus',1,'个人奖金奖励',122.139,1482,'个人奖金变动奖励奖金金额244.278积分122',3,0,0,'2026-04-13 08:39:01','2026-04-13 08:39:01',2521),
(5349,93150,'2528','selfbonus',1,'个人奖金奖励',119.505,1518,'个人奖金变动奖励奖金金额239.010积分119',3,0,0,'2026-04-14 02:00:01','2026-04-14 02:00:01',2528),
(5377,93140,'2554','selfbonus',1,'个人奖金奖励',122.139,729,'个人奖金变动奖励奖金金额244.278积分122',3,0,0,'2026-04-14 02:05:01','2026-04-14 02:05:01',2554),
(5393,92827,'2572','selfbonus',1,'个人奖金奖励',183.209,2237,'个人奖金变动奖励奖金金额366.418积分183',3,0,0,'2026-04-14 03:32:01','2026-04-14 03:32:01',2572),
(5410,92738,'2587','selfbonus',1,'个人奖金奖励',125.551,1608,'个人奖金变动奖励奖金金额251.103积分125',3,0,0,'2026-04-14 07:15:01','2026-04-14 07:15:01',2587),
(5412,92738,'2589','selfbonus',1,'个人奖金奖励',125.182,1733,'个人奖金变动奖励奖金金额250.364积分125',3,0,0,'2026-04-14 07:30:01','2026-04-14 07:30:01',2589),
(5432,93150,'2622','selfbonus',1,'个人奖金奖励',104.706,1623,'个人奖金变动奖励奖金金额209.413积分104',3,0,0,'2026-04-15 02:02:01','2026-04-15 02:02:01',2622),
(5443,92738,'2612','selfbonus',1,'个人奖金奖励',130.890,1864,'个人奖金变动奖励奖金金额261.781积分130',3,0,0,'2026-04-15 02:02:01','2026-04-15 02:02:01',2612),
(5453,92827,'2630','selfbonus',1,'个人奖金奖励',178.709,2416,'个人奖金变动奖励奖金金额357.418积分178',3,0,0,'2026-04-15 02:03:01','2026-04-15 02:03:01',2630),
(5469,92738,'order68661177621871701084953','order',2,'用户订单付款成功',792.000,1072,'订单支付抵扣792积分购买商品',3,0,0,'2026-04-15 02:06:00','2026-04-15 02:06:00',NULL),
(5472,93140,'2646','selfbonus',1,'个人奖金奖励',133.292,862,'个人奖金变动奖励奖金金额266.585积分133',3,0,0,'2026-04-15 02:06:01','2026-04-15 02:06:01',2646),
(5475,92738,'order93193177621884587987279','order',2,'用户订单付款成功',690.000,382,'订单支付抵扣690积分购买商品',3,0,0,'2026-04-15 02:08:00','2026-04-15 02:08:00',NULL),
(5477,93140,'order49083177621885635728466','order',2,'用户订单付款成功',724.000,138,'订单支付抵扣724积分购买商品',3,0,0,'2026-04-15 02:08:00','2026-04-15 02:08:00',NULL),
(5479,92827,'order65878177621896033723311','order',2,'用户订单付款成功',2352.000,64,'订单支付抵扣2352积分购买商品',3,0,0,'2026-04-15 02:10:00','2026-04-15 02:10:00',NULL),
(5532,93140,'2687','selfbonus',1,'个人奖金奖励',126.782,265,'个人奖金变动奖励奖金金额253.565积分126',3,0,0,'2026-04-16 02:01:01','2026-04-16 02:01:01',2687),
(5541,92738,'2695','selfbonus',1,'个人奖金奖励',139.174,521,'个人奖金变动奖励奖金金额278.349积分139',3,0,0,'2026-04-16 02:02:01','2026-04-16 02:02:01',2695),
(5545,92827,'2707','selfbonus',1,'个人奖金奖励',171.038,235,'个人奖金变动奖励奖金金额342.077积分171',3,0,0,'2026-04-16 02:03:01','2026-04-16 02:03:01',2707),
(5621,93150,'2750','selfbonus',1,'个人奖金奖励',106.132,1729,'个人奖金变动奖励奖金金额212.264积分106',3,0,0,'2026-04-16 06:28:00','2026-04-16 06:28:00',2750),
(5673,92738,'2770','selfbonus',1,'个人奖金奖励',130.586,652,'个人奖金变动奖励奖金金额261.172积分130',3,0,0,'2026-04-20 02:01:01','2026-04-20 02:01:01',2770),
(5679,93140,'2776','selfbonus',1,'个人奖金奖励',103.662,369,'个人奖金变动奖励奖金金额207.324积分103',3,0,0,'2026-04-20 02:04:01','2026-04-20 02:04:01',2776),
(5695,93150,'2793','selfbonus',1,'个人奖金奖励',140.101,1869,'个人奖金变动奖励奖金金额280.203积分140',3,0,0,'2026-04-20 06:10:01','2026-04-20 06:10:01',2793),
(5696,92827,'2794','selfbonus',1,'个人奖金奖励',166.341,401,'个人奖金变动奖励奖金金额332.683积分166',3,0,0,'2026-04-20 06:47:01','2026-04-20 06:47:01',2794),
(5729,92738,'2824','selfbonus',1,'个人奖金奖励',137.179,789,'个人奖金变动奖励奖金金额274.358积分137',3,0,0,'2026-04-21 02:03:01','2026-04-21 02:03:01',2824),
(5731,93140,'2829','selfbonus',1,'个人奖金奖励',112.595,481,'个人奖金变动奖励奖金金额225.191积分112',3,0,0,'2026-04-21 02:04:01','2026-04-21 02:04:01',2829),
(5736,92827,'2834','selfbonus',1,'个人奖金奖励',171.332,572,'个人奖金变动奖励奖金金额342.664积分171',3,0,0,'2026-04-21 02:11:01','2026-04-21 02:11:01',2834),
(5761,93150,'2859','selfbonus',1,'个人奖金奖励',107.531,1977,'个人奖金变动奖励奖金金额215.062积分107',3,0,0,'2026-04-21 06:15:01','2026-04-21 06:15:01',2859),
(5770,93140,'order77013177676957691467666','order',2,'用户订单付款成功',468.000,13,'订单支付抵扣468积分购买商品',3,0,0,'2026-04-21 11:07:00','2026-04-21 11:07:00',NULL),
(5780,92738,'2881','selfbonus',1,'个人奖金奖励',138.538,927,'个人奖金变动奖励奖金金额277.077积分138',3,0,0,'2026-04-22 02:02:01','2026-04-22 02:02:01',2881),
(5800,93150,'2898','selfbonus',1,'个人奖金奖励',107.088,2084,'个人奖金变动奖励奖金金额214.177积分107',3,0,0,'2026-04-22 02:58:01','2026-04-22 02:58:01',2898);

View File

@@ -0,0 +1,46 @@
-- 太原树英商贸 / yangtangyoupin 数据清理
-- 依据: docs/com-sxsy80-data-imgration.md
-- 执行前请备份数据库。建议在事务中先 SELECT 核对影响行数后再 COMMIT。
SET NAMES utf8mb4;
START TRANSACTION;
SET FOREIGN_KEY_CHECKS = 0;
-- 订单类:整表清空
TRUNCATE TABLE `wa_order`;
TRUNCATE TABLE `wa_withdraw`;
TRUNCATE TABLE `eb_store_order`;
-- 寄售商品:与迁移文档一致——从源 dump 解析 id 列表(见 wa_merchandise_keep_ids_from_dump_sxsy80.txt删库中不在集合内的行
DELETE FROM `wa_merchandise`
WHERE `id` NOT IN (
163212,163213,163214,163223,163224,163225,163226,163231,163234,163235,163237,163239,163244,163245,163246,163254,163255,163259
);
-- 日志类:仅保留名单内 user_id
DELETE FROM `wa_selfbonus_log`
WHERE `user_id` NOT IN (92566,92801,92839,93004,92637,92965,93093,93096,93116,92787,93121,93129,92884,93007,93020,93094,93099,93110,92638);
DELETE FROM `wa_sharebonus_log`
WHERE `user_id` NOT IN (92566,92801,92839,93004,92637,92965,93093,93096,93116,92787,93121,93129,92884,93007,93020,93094,93099,93110,92638);
DELETE FROM `wa_coupon_log`
WHERE `user_id` NOT IN (92566,92801,92839,93004,92637,92965,93093,93096,93116,92787,93121,93129,92884,93007,93020,93094,93099,93110,92638);
-- 积分记录表实际字段为 uid非 user_id
DELETE FROM `eb_user_integral_record`
WHERE `uid` NOT IN (92566,92801,92839,93004,92637,92965,93093,93096,93116,92787,93121,93129,92884,93007,93020,93094,93099,93110,92638);
-- 商城用户:保留 uid 在名单内
DELETE FROM `eb_user`
WHERE `uid` NOT IN (92566,92801,92839,93004,92637,92965,93093,93096,93116,92787,93121,93129,92884,93007,93020,93094,93099,93110,92638);
-- WA 用户:保留 id 在名单内
DELETE FROM `wa_users`
WHERE `id` NOT IN (92566,92801,92839,93004,92637,92965,93093,93096,93116,92787,93121,93129,92884,93007,93020,93094,93099,93110,92638);
SET FOREIGN_KEY_CHECKS = 1;
COMMIT;

View File

@@ -0,0 +1,12 @@
-- 仅处理 wa_merchandise与 com-sxsy80-data-imgration.md 一致
-- 从源 dump 解析应保留的 id 列表(见 wa_merchandise_keep_ids_from_dump_sxsy80.txt删除库中 id 不在此集合的所有行。
SET NAMES utf8mb4;
START TRANSACTION;
DELETE FROM `wa_merchandise`
WHERE `id` NOT IN (
163212,163213,163214,163223,163224,163225,163226,163231,163234,163235,163237,163239,163244,163245,163246,163254,163255,163259
);
COMMIT;

View File

@@ -0,0 +1,52 @@
#!/usr/bin/env python3
"""从 dump 解析 wa_merchandise 应保留的 id与 com-sxsy80-data-imgration.md 一致)。"""
from __future__ import annotations
import re
import sys
from pathlib import Path
KEEP_USERS = {
92566, 92801, 92839, 93004, 92637, 92965, 93093, 93096, 93116, 92787, 93121, 93129,
92884, 93007, 93020, 93094, 93099, 93110, 92638,
}
CUTOFF = "2026-04-22 00:00:00"
# id, old_id, user_id, title, image, price, is_show, status, created_at, updated_at
ROW_RE = re.compile(
r"\((\d+),(\d+),(\d+),'(?:[^'\\]|\\.)*','(?:[^'\\]|\\.)*',[\d.]+,\d+,\d+,'(\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2})','(\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2})'\)"
)
def main() -> int:
dump = Path(sys.argv[1]) if len(sys.argv) > 1 else Path(__file__).resolve().parents[2].parent / "db" / "ccd-yangtangyoupin_2026-04-26_10-25-01_mysql_data.sql"
if not dump.is_file():
print("dump not found:", dump, file=sys.stderr)
return 1
line = None
with dump.open("r", encoding="utf-8", errors="replace") as f:
for ln in f:
if "INSERT INTO `wa_merchandise`" in ln and "VALUES" in ln:
line = ln
break
if not line:
print("no wa_merchandise INSERT", file=sys.stderr)
return 1
keep: set[int] = set()
for m in ROW_RE.finditer(line):
mid, _old, user_id, created_at, _upd = m.groups()
if created_at >= CUTOFF and int(user_id) in KEEP_USERS:
keep.add(int(mid))
out = Path(__file__).resolve().parent / "wa_merchandise_keep_ids_from_dump_sxsy80.txt"
body = (
"# 从 dump 解析条件created_at >= 2026-04-22 且 user_id 在名单\n"
"# 重新生成python3 docs/sql/extract_wa_merchandise_keep_ids_from_dump.py /path/to/dump.sql\n\n"
+ ",".join(str(i) for i in sorted(keep))
+ "\n"
)
out.write_text(body, encoding="utf-8")
print("wrote", out, "count=", len(keep))
return 0
if __name__ == "__main__":
raise SystemExit(main())

View File

@@ -0,0 +1,218 @@
#!/usr/bin/env python3
"""
依据 docs/com-czrt6-data-imgration-2.md从 dump 生成批量 INSERT SQL。
数据源默认: docs/czcf82-yangtangyoupin_2026-04-26_10-25-02_mysql_data.sql
输出: docs/sql/com-czrt6-data-imgration-2_inserts.sql
"""
from __future__ import annotations
import sys
from pathlib import Path
# 与 com-czrt6-data-imgration-2.md 一致
KEEP_IDS = {92827, 92738, 93140, 93150}
MERCH_CUTOFF = "2026-04-16 00:00:00"
TABLES_ORDER = [
"wa_users",
"eb_user",
"wa_merchandise",
"wa_selfbonus_log",
"wa_sharebonus_log",
"wa_coupon_log",
"eb_user_integral_record",
]
def split_top_level_tuples(values_blob: str) -> list[str]:
out: list[str] = []
i = 0
n = len(values_blob)
while i < n:
if values_blob[i] != "(":
i += 1
continue
depth = 0
in_quote = False
start = i
j = i
while j < n:
c = values_blob[j]
if in_quote:
if c == "'":
if j + 1 < n and values_blob[j + 1] == "'":
j += 2
continue
in_quote = False
j += 1
continue
j += 1
continue
if c == "'":
in_quote = True
j += 1
continue
if c == "(":
depth += 1
elif c == ")":
depth -= 1
if depth == 0:
out.append(values_blob[start : j + 1])
j += 1
break
j += 1
i = j
return out
def split_mysql_fields(inner: str) -> list[str]:
out: list[str] = []
cur: list[str] = []
i = 0
n = len(inner)
while i < n:
c = inner[i]
if c == "'":
cur.append(c)
i += 1
while i < n:
c = inner[i]
cur.append(c)
if c == "'":
if i + 1 < n and inner[i + 1] == "'":
cur.append(inner[i + 1])
i += 2
continue
i += 1
break
i += 1
continue
if c == ",":
out.append("".join(cur).strip())
cur = []
i += 1
continue
cur.append(c)
i += 1
if cur:
out.append("".join(cur).strip())
return out
def unquote_sql_string(raw: str) -> str:
raw = raw.strip()
if raw.startswith("'") and raw.endswith("'"):
return raw[1:-1].replace("''", "'")
return raw
def find_insert_line(dump: Path, table: str) -> str | None:
needle = f"INSERT INTO `{table}` VALUES"
with dump.open("r", encoding="utf-8", errors="replace") as f:
for line in f:
if needle in line:
return line
return None
def values_blob_from_line(line: str, table: str) -> str:
marker = f"INSERT INTO `{table}` VALUES"
idx = line.index(marker) + len(marker)
blob = line[idx:].strip()
if blob.endswith(";"):
blob = blob[:-1].strip()
return blob
def filter_tuples(table: str, tuples: list[str]) -> list[str]:
kept: list[str] = []
for tup in tuples:
inner = tup.strip()[1:-1]
fields = split_mysql_fields(inner)
ok = False
try:
if table == "wa_users":
ok = len(fields) >= 1 and int(fields[0].strip()) in KEEP_IDS
elif table == "eb_user":
ok = len(fields) >= 1 and int(fields[0].strip()) in KEEP_IDS
elif table == "wa_merchandise":
if len(fields) >= 10:
uid = int(fields[2].strip())
status = int(fields[7].strip())
created = unquote_sql_string(fields[8])
ok = (
created >= MERCH_CUTOFF
and uid in KEEP_IDS
and status == 1
)
elif table in ("wa_selfbonus_log", "wa_sharebonus_log", "wa_coupon_log"):
ok = len(fields) >= 2 and int(fields[1].strip()) in KEEP_IDS
elif table == "eb_user_integral_record":
ok = len(fields) >= 2 and int(fields[1].strip()) in KEEP_IDS
except (ValueError, IndexError):
ok = False
if ok:
kept.append(tup.strip())
return kept
def main() -> int:
root = Path(__file__).resolve().parents[2]
dump = (
Path(sys.argv[1]).resolve()
if len(sys.argv) > 1
else root / "docs" / "czcf82-yangtangyoupin_2026-04-26_10-25-02_mysql_data.sql"
)
if not dump.is_file():
print("dump not found:", dump, file=sys.stderr)
return 1
out_path = root / "docs" / "sql" / "com-czrt6-data-imgration-2_inserts.sql"
chunks: list[str] = []
chunks.append(
f"""-- 池州瑞棠商贸 / com-czrt6-data-imgration-2.md
-- 源 dump: {dump.name}
-- 用户范围: {sorted(KEEP_IDS)}
-- wa_merchandise: created_at >= {MERCH_CUTOFF[:10]} 且 user_id 在范围且 status=1未售
-- 执行前请备份;注意外键与主键冲突,按需调整顺序或使用 SET FOREIGN_KEY_CHECKS=0
SET NAMES utf8mb4;
"""
)
stats: list[tuple[str, int]] = []
for table in TABLES_ORDER:
line = find_insert_line(dump, table)
if not line:
chunks.append(f"-- 未找到 INSERT: `{table}`\n\n")
stats.append((table, 0))
continue
blob = values_blob_from_line(line, table)
tuples = split_top_level_tuples(blob)
kept = filter_tuples(table, tuples)
stats.append((table, len(kept)))
chunks.append(f"-- ---------- `{table}` ({len(kept)} rows) ----------\n")
if not kept:
if table == "wa_merchandise":
chunks.append(
"-- 无匹配行dump 中满足「日期 + user_id 在范围」的寄售商品均为 status=0已售\n"
"-- 若业务上「未售」应对应其它字段,请改脚本 filter 后重新 python3 本脚本。\n\n"
)
else:
chunks.append("-- (无匹配行,跳过 INSERT)\n\n")
continue
chunks.append(f"INSERT INTO `{table}` VALUES\n")
chunks.append(",\n".join(kept))
chunks.append(";\n\n")
out_path.write_text("".join(chunks), encoding="utf-8")
print("wrote", out_path)
for t, n in stats:
print(f" {t}: {n}")
return 0
if __name__ == "__main__":
raise SystemExit(main())

View File

@@ -0,0 +1,168 @@
#!/usr/bin/env python3
"""
从 dump 的 INSERT INTO wa_merchandise 中筛出:
created_at >= 2026-04-22 00:00:00 且 user_id 在数据范围
生成批量 INSERT SQL与 docs/com-sxsy80-data-imgration.md 一致)。
用法:
python3 docs/sql/generate_wa_merchandise_insert_from_dump.py [dump.sql路径]
默认 dump: ../../db/ccd-yangtangyoupin_2026-04-26_10-25-01_mysql_data.sql相对仓库根
"""
from __future__ import annotations
import sys
from pathlib import Path
KEEP_USERS = {
92566, 92801, 92839, 93004, 92637, 92965, 93093, 93096, 93116, 92787, 93121, 93129,
92884, 93007, 93020, 93094, 93099, 93110, 92638,
}
CUTOFF = "2026-04-22 00:00:00"
def split_top_level_tuples(values_blob: str) -> list[str]:
out: list[str] = []
i = 0
n = len(values_blob)
while i < n:
if values_blob[i] != "(":
i += 1
continue
depth = 0
in_quote = False
start = i
j = i
while j < n:
c = values_blob[j]
if in_quote:
if c == "'":
if j + 1 < n and values_blob[j + 1] == "'":
j += 2
continue
in_quote = False
j += 1
continue
j += 1
continue
if c == "'":
in_quote = True
j += 1
continue
if c == "(":
depth += 1
elif c == ")":
depth -= 1
if depth == 0:
out.append(values_blob[start : j + 1])
j += 1
break
j += 1
i = j
return out
def split_mysql_fields(inner: str) -> list[str]:
"""inner: 不含最外层括号的字段串"""
out: list[str] = []
cur: list[str] = []
i = 0
n = len(inner)
while i < n:
c = inner[i]
if c == "'":
cur.append(c)
i += 1
while i < n:
c = inner[i]
cur.append(c)
if c == "'":
if i + 1 < n and inner[i + 1] == "'":
cur.append(inner[i + 1])
i += 2
continue
i += 1
break
i += 1
continue
if c == ",":
out.append("".join(cur).strip())
cur = []
i += 1
continue
cur.append(c)
i += 1
if cur:
out.append("".join(cur).strip())
return out
def parse_created_at(fields: list[str]) -> str:
# id, old_id, user_id, title, image, price, is_show, status, created_at, updated_at
raw = fields[8].strip()
if raw.startswith("'") and raw.endswith("'"):
return raw[1:-1].replace("''", "'")
return raw
def parse_user_id(fields: list[str]) -> int:
return int(fields[2].strip())
def main() -> int:
root = Path(__file__).resolve().parents[2]
dump = (
Path(sys.argv[1]).resolve()
if len(sys.argv) > 1
else root.parent / "db" / "ccd-yangtangyoupin_2026-04-26_10-25-01_mysql_data.sql"
)
if not dump.is_file():
print("dump not found:", dump, file=sys.stderr)
return 1
insert_line = None
with dump.open("r", encoding="utf-8", errors="replace") as f:
for line in f:
if "INSERT INTO `wa_merchandise`" in line and "VALUES" in line:
insert_line = line
break
if not insert_line:
print("no INSERT wa_merchandise", file=sys.stderr)
return 1
marker = "VALUES"
idx = insert_line.index(marker) + len(marker)
blob = insert_line[idx:].strip()
if blob.endswith(";"):
blob = blob[:-1].strip()
kept: list[str] = []
for tup in split_top_level_tuples(blob):
inner = tup.strip()[1:-1]
fields = split_mysql_fields(inner)
if len(fields) < 10:
print("skip malformed tuple:", tup[:80], file=sys.stderr)
continue
created = parse_created_at(fields)
uid = parse_user_id(fields)
if created >= CUTOFF and uid in KEEP_USERS:
kept.append(tup.strip())
if not kept:
print("no rows matched", file=sys.stderr)
return 1
out_sql = root / "docs" / "sql" / "wa_merchandise_insert_from_dump_sxsy80.sql"
header = f"""-- 由 generate_wa_merchandise_insert_from_dump.py 生成
-- 源: {dump.name}
-- 条件: created_at >= {CUTOFF} 且 user_id卖家在数据范围{len(kept)} 行)
-- 执行前请确认目标库;若存在主键冲突可先处理或改用 INSERT IGNORE / REPLACE
"""
body = "INSERT INTO `wa_merchandise` VALUES\n" + ",\n".join(kept) + ";\n"
out_sql.write_text(header + body, encoding="utf-8")
print("wrote", out_sql, "rows=", len(kept))
return 0
if __name__ == "__main__":
raise SystemExit(main())

View File

@@ -0,0 +1,238 @@
#!/usr/bin/env python3
"""
在目标库执行 com-czrt6-data-imgration-2 迁移(见 docs/com-czrt6-data-imgration-2.md
1) SET FOREIGN_KEY_CHECKS=0
2) 从 inserts SQL 解析各 INSERT 的主键,按依赖逆序 DELETE避免与 dump 主键冲突,如他人曾占用同 id
3) 再按文件顺序执行 SET NAMES + INSERT
环境变量:
CZRT6_DB_HOST / CZRT6_DB_USER / CZRT6_DB_PASSWORD / CZRT6_DB_NAME
"""
from __future__ import annotations
import os
import re
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parents[2]
SQL_FILE = ROOT / "docs" / "sql" / "com-czrt6-data-imgration-2_inserts.sql"
def split_top_level_tuples(values_blob: str) -> list[str]:
out: list[str] = []
i = 0
n = len(values_blob)
while i < n:
if values_blob[i] != "(":
i += 1
continue
depth = 0
in_quote = False
start = i
j = i
while j < n:
c = values_blob[j]
if in_quote:
if c == "'":
if j + 1 < n and values_blob[j + 1] == "'":
j += 2
continue
in_quote = False
j += 1
continue
j += 1
continue
if c == "'":
in_quote = True
j += 1
continue
if c == "(":
depth += 1
elif c == ")":
depth -= 1
if depth == 0:
out.append(values_blob[start : j + 1])
j += 1
break
j += 1
i = j
return out
def split_mysql_fields(inner: str) -> list[str]:
out: list[str] = []
cur: list[str] = []
i = 0
n = len(inner)
while i < n:
c = inner[i]
if c == "'":
cur.append(c)
i += 1
while i < n:
c = inner[i]
cur.append(c)
if c == "'":
if i + 1 < n and inner[i + 1] == "'":
cur.append(inner[i + 1])
i += 2
continue
i += 1
break
i += 1
continue
if c == ",":
out.append("".join(cur).strip())
cur = []
i += 1
continue
cur.append(c)
i += 1
if cur:
out.append("".join(cur).strip())
return out
def load_executable_statements(path: Path) -> list[str]:
raw = path.read_text(encoding="utf-8")
lines = []
for line in raw.splitlines():
if line.strip().startswith("--"):
continue
lines.append(line)
text = "\n".join(lines)
stmts: list[str] = []
buf: list[str] = []
for line in text.splitlines():
if not line.strip():
continue
buf.append(line)
if line.rstrip().endswith(";"):
stmts.append("\n".join(buf).strip())
buf = []
if buf:
stmts.append("\n".join(buf).strip())
return [s for s in stmts if s and not s.startswith("--")]
def parse_insert_table_and_pks(statement: str) -> tuple[str | None, list[int]]:
m = re.match(r"INSERT INTO `(\w+)` VALUES\s*(.*)\s*;\s*$", statement, re.S | re.I)
if not m:
return None, []
table = m.group(1)
blob = m.group(2).strip()
if blob.endswith(";"):
blob = blob[:-1].strip()
pks: list[int] = []
for tup in split_top_level_tuples(blob):
inner = tup.strip()[1:-1]
fields = split_mysql_fields(inner)
if not fields:
continue
try:
pks.append(int(fields[0].strip()))
except ValueError:
continue
return table, pks
def chunk_in(ids: list[int], size: int = 500) -> list[list[int]]:
return [ids[i : i + size] for i in range(0, len(ids), size)]
def main() -> int:
try:
import pymysql
except ImportError:
print("需要: pip install pymysql", file=sys.stderr)
return 1
host = os.environ.get("CZRT6_DB_HOST", "101.37.101.6")
user = os.environ.get("CZRT6_DB_USER", "yangtangyoupin")
password = os.environ.get("CZRT6_DB_PASSWORD")
database = os.environ.get("CZRT6_DB_NAME", "yangtangyoupin")
if not password:
print("请设置 CZRT6_DB_PASSWORD", file=sys.stderr)
return 1
if not SQL_FILE.is_file():
print("missing", SQL_FILE, file=sys.stderr)
return 1
stmts = load_executable_statements(SQL_FILE)
if not stmts:
print("no statements in", SQL_FILE, file=sys.stderr)
return 1
by_table: dict[str, list[int]] = {}
for sql in stmts:
if not sql.upper().startswith("INSERT"):
continue
tbl, pks = parse_insert_table_and_pks(sql)
if tbl and pks:
by_table[tbl] = pks
# 逆序:先删子表/日志,再 eb_user、wa_users
delete_order = [
"eb_user_integral_record",
"wa_coupon_log",
"wa_sharebonus_log",
"wa_selfbonus_log",
"wa_merchandise",
"eb_user",
"wa_users",
]
pk_col = {"eb_user": "`uid`", "wa_users": "`id`"}
conn = pymysql.connect(
host=host,
user=user,
password=password,
database=database,
charset="utf8mb4",
autocommit=False,
)
try:
with conn.cursor() as cur:
cur.execute("SET NAMES utf8mb4")
cur.execute("SET FOREIGN_KEY_CHECKS=0")
for t in delete_order:
if t not in by_table:
continue
ids = sorted(set(by_table[t]))
col = pk_col.get(t, "`id`")
for chunk in chunk_in(ids):
cl = ",".join(str(x) for x in chunk)
sql = f"DELETE FROM `{t}` WHERE {col} IN ({cl})"
cur.execute(sql)
if cur.rowcount:
print(f"DELETE {t}", cur.rowcount)
for i, sql in enumerate(stmts, 1):
head = sql.split()[0].upper()
cur.execute(sql)
if head == "INSERT":
tbl = re.match(r"INSERT INTO `(\w+)`", sql, re.I)
tname = tbl.group(1) if tbl else "?"
print(f"[{i}] INSERT `{tname}` rowcount={cur.rowcount}")
else:
print(f"[{i}] {head} ok")
conn.commit()
print("COMMIT ok")
except Exception as e:
conn.rollback()
print("ROLLBACK:", e, file=sys.stderr)
raise
finally:
try:
with conn.cursor() as cur:
cur.execute("SET FOREIGN_KEY_CHECKS=1")
conn.commit()
except Exception:
pass
conn.close()
return 0
if __name__ == "__main__":
raise SystemExit(main())

View File

@@ -0,0 +1,88 @@
#!/usr/bin/env python3
"""执行 com-sxsy80-data-cleanup.sql。
需安装: pip install pymysql
连接信息见 docs/com-sxsy80-data-imgration.md通过环境变量传入避免把密码写进仓库
export YTYP_DB_HOST=106.14.132.80
export YTYP_DB_USER=yangtangyoupin
export YTYP_DB_PASSWORD='...'
export YTYP_DB_NAME=yangtangyoupin
python3 docs/sql/run_com_sxsy80_cleanup.py
"""
from __future__ import annotations
import os
import pathlib
import sys
import pymysql
ROOT = pathlib.Path(__file__).resolve().parents[2]
SQL_FILE = ROOT / "docs" / "sql" / "com-sxsy80-data-cleanup.sql"
def load_statements(path: pathlib.Path) -> list[str]:
text = path.read_text(encoding="utf-8")
stmts: list[str] = []
buf: list[str] = []
for line in text.splitlines():
s = line.strip()
if s.startswith("--") or not line.strip():
continue
buf.append(line)
if ";" in line:
chunk = "\n".join(buf).strip()
if chunk:
stmts.append(chunk)
buf = []
if buf:
chunk = "\n".join(buf).strip()
if chunk:
stmts.append(chunk)
return stmts
def main() -> int:
host = os.environ.get("YTYP_DB_HOST", "106.14.132.80")
user = os.environ.get("YTYP_DB_USER", "yangtangyoupin")
password = os.environ.get("YTYP_DB_PASSWORD")
database = os.environ.get("YTYP_DB_NAME", "yangtangyoupin")
if not password:
print("请设置环境变量 YTYP_DB_PASSWORD见脚本头部说明", file=sys.stderr)
return 1
if not SQL_FILE.is_file():
print("missing", SQL_FILE, file=sys.stderr)
return 1
statements = load_statements(SQL_FILE)
conn = pymysql.connect(
host=host,
user=user,
password=password,
database=database,
charset="utf8mb4",
autocommit=False,
)
try:
with conn.cursor() as cur:
for i, sql in enumerate(statements, 1):
cur.execute(sql)
head = sql.split()[0].upper()
if head == "DELETE" and cur.rowcount >= 0:
print(f"[{i}] DELETE … rowcount={cur.rowcount}")
else:
print(f"[{i}] ok")
conn.commit()
print("COMMIT ok")
except Exception as e:
conn.rollback()
print("ROLLBACK:", e, file=sys.stderr)
raise
finally:
conn.close()
return 0
if __name__ == "__main__":
raise SystemExit(main())

View File

@@ -0,0 +1,24 @@
-- 由 generate_wa_merchandise_insert_from_dump.py 生成
-- 源: ccd-yangtangyoupin_2026-04-26_10-25-01_mysql_data.sql
-- 条件: created_at >= 2026-04-22 00:00:00 且 user_id卖家在数据范围共 18 行)
-- 执行前请确认目标库;若存在主键冲突可先处理或改用 INSERT IGNORE / REPLACE
INSERT INTO `wa_merchandise` VALUES
(163212,169703,93004,'鲜锋活力宝','/upload/image/20251118/bc323c55ca713eee8badf5bf358893b7_691c26bd07fc3.jpg',22532.37,1,0,'2026-04-22 14:50:16','2026-04-23 10:00:01'),
(163213,169715,92801,'鲜锋活力宝','/upload/image/20251118/bc323c55ca713eee8badf5bf358893b7_691c26bd07fc3.jpg',35655.95,1,0,'2026-04-22 14:50:52','2026-04-23 10:01:13'),
(163214,169743,92566,'鲜锋活力宝','/upload/image/20251118/bc323c55ca713eee8badf5bf358893b7_691c26bd07fc3.jpg',29788.66,1,0,'2026-04-22 14:51:06','2026-04-23 10:00:00'),
(163223,169735,93007,'鲜锋活力宝','/upload/image/20251118/bc323c55ca713eee8badf5bf358893b7_691c26bd07fc3.jpg',33613.59,1,0,'2026-04-22 15:00:30','2026-04-23 10:01:40'),
(163224,169726,93116,'鲜锋活力宝','/upload/image/20251118/bc323c55ca713eee8badf5bf358893b7_691c26bd07fc3.jpg',34621.99,1,0,'2026-04-22 15:04:45','2026-04-23 10:00:13'),
(163225,169692,92638,'鲜锋活力宝','/upload/image/20251118/bc323c55ca713eee8badf5bf358893b7_691c26bd07fc3.jpg',24784.54,1,0,'2026-04-22 15:05:51','2026-04-23 10:04:15'),
(163226,169708,92787,'鲜锋活力宝','/upload/image/20251118/bc323c55ca713eee8badf5bf358893b7_691c26bd07fc3.jpg',23081.44,1,0,'2026-04-22 15:05:54','2026-04-23 10:00:13'),
(163231,169728,93096,'鲜锋活力宝','/upload/image/20251118/bc323c55ca713eee8badf5bf358893b7_691c26bd07fc3.jpg',26916.09,1,0,'2026-04-22 15:10:21','2026-04-23 10:04:22'),
(163234,169707,92637,'鲜锋活力宝','/upload/image/20251118/bc323c55ca713eee8badf5bf358893b7_691c26bd07fc3.jpg',24404.25,1,0,'2026-04-22 15:22:39','2026-04-23 10:01:00'),
(163235,169693,93121,'鲜锋活力宝','/upload/image/20251118/bc323c55ca713eee8badf5bf358893b7_691c26bd07fc3.jpg',33031.21,1,0,'2026-04-22 15:29:57','2026-04-23 10:00:00'),
(163237,169724,92965,'鲜锋活力宝','/upload/image/20251118/bc323c55ca713eee8badf5bf358893b7_691c26bd07fc3.jpg',23693.45,1,0,'2026-04-22 15:34:45','2026-04-23 10:02:03'),
(163239,169698,92884,'鲜锋活力宝','/upload/image/20251118/bc323c55ca713eee8badf5bf358893b7_691c26bd07fc3.jpg',23904.59,1,0,'2026-04-22 15:34:57','2026-04-23 10:03:01'),
(163244,169700,93093,'鲜锋活力宝','/upload/image/20251118/bc323c55ca713eee8badf5bf358893b7_691c26bd07fc3.jpg',23693.45,1,0,'2026-04-22 16:46:21','2026-04-23 10:01:55'),
(163245,169699,93129,'鲜锋活力宝','/upload/image/20251118/bc323c55ca713eee8badf5bf358893b7_691c26bd07fc3.jpg',23904.59,1,0,'2026-04-22 16:53:43','2026-04-23 10:00:22'),
(163246,169720,92839,'鲜锋活力宝','/upload/image/20251118/bc323c55ca713eee8badf5bf358893b7_691c26bd07fc3.jpg',23081.44,1,0,'2026-04-22 16:57:44','2026-04-23 10:01:35'),
(163254,169741,93020,'鲜锋活力宝','/upload/image/20251118/bc323c55ca713eee8badf5bf358893b7_691c26bd07fc3.jpg',23693.45,1,0,'2026-04-22 17:25:34','2026-04-23 10:00:02'),
(163255,169756,93094,'鲜锋活力宝','/upload/image/20251118/bc323c55ca713eee8badf5bf358893b7_691c26bd07fc3.jpg',40227.74,1,0,'2026-04-22 17:28:19','2026-04-23 10:01:00'),
(163259,169704,93099,'鲜锋活力宝','/upload/image/20251118/bc323c55ca713eee8badf5bf358893b7_691c26bd07fc3.jpg',22939.85,1,0,'2026-04-22 17:43:38','2026-04-23 10:00:02');

View File

@@ -0,0 +1,4 @@
# 从 dump 解析条件created_at >= 2026-04-22 且 user_id 在名单
# 重新生成python3 docs/sql/extract_wa_merchandise_keep_ids_from_dump.py /path/to/dump.sql
163212,163213,163214,163223,163224,163225,163226,163231,163234,163235,163237,163239,163244,163245,163246,163254,163255,163259

Binary file not shown.

Binary file not shown.

Binary file not shown.

59
restart-backend.command Executable file
View File

@@ -0,0 +1,59 @@
#!/bin/bash
# 双击此文件即可在新终端启动 backend
# 1) 杀掉占用 20600 的旧进程
# 2) 用 Maven 把 crmeb-common / crmeb-service 安装到本地 m2这样 crmeb-admin 单模块运行时能找到依赖)
# 3) 进入 crmeb-admin 目录,用完整 GAV 调用 spring-boot:run
set -e
cd "$(dirname "$0")"
PROFILE="${BACKEND_PROFILE:-byjyw149}"
echo "🛑 Stopping any process listening on :20600 ..."
PIDS=$(lsof -t -iTCP:20600 -sTCP:LISTEN 2>/dev/null || true)
if [ -n "$PIDS" ]; then
echo " killing PIDs: $PIDS"
kill -9 $PIDS 2>/dev/null || true
sleep 2
else
echo " no existing process on :20600"
fi
# 自动定位 Java沿用 start-backend.sh 的逻辑)
find_java() {
if /usr/libexec/java_home &>/dev/null; then
echo "$(/usr/libexec/java_home)/bin/java"; return
fi
for p in /opt/homebrew/opt/openjdk*/bin/java /opt/homebrew/opt/openjdk/bin/java \
/usr/local/opt/openjdk*/bin/java /usr/local/opt/openjdk/bin/java; do
[ -x "$p" ] && echo "$p" && return
done
[ -n "$SDKMAN_DIR" ] && [ -x "$SDKMAN_DIR/candidates/java/current/bin/java" ] && \
echo "$SDKMAN_DIR/candidates/java/current/bin/java" && return
command -v java 2>/dev/null
}
JAVA_BIN=$(find_java)
if [ -z "$JAVA_BIN" ]; then
echo "❌ 未找到 Java请先安装 JDK 11brew install openjdk@11"
exit 1
fi
export JAVA_HOME="$(dirname "$(dirname "$JAVA_BIN")")"
echo "☕ Java: $JAVA_BIN"
"$JAVA_BIN" -version
echo ""
cd backend
# 第一步:把依赖模块编译并安装到本地 m2首次执行会下载依赖只在源代码变更后需要重跑
echo "🔧 Step 1: install crmeb-common + crmeb-service to local m2 ..."
echo ""
./mvnw install -pl crmeb-common,crmeb-service -am -Dmaven.test.skip=true -q
# 第二步:进入 crmeb-admin 单模块跑 spring-boot:run避免根 pom 触发 main class 错误)
echo ""
echo "🚀 Step 2: launch crmeb-admin (profile=$PROFILE) ..."
echo ""
cd crmeb-admin
exec ../mvnw \
org.springframework.boot:spring-boot-maven-plugin:2.3.0.RELEASE:run \
-Dmaven.test.skip=true \
-Dspring-boot.run.profiles="$PROFILE"

View File

@@ -6,7 +6,7 @@
// let domain = 'https://jfanyue.szxingming.com'
// let domain = 'https://jf.wenjinhui.com'
// let domain = 'https://jjy-jf.fwxgpt.com'
let domain = 'https://czcf-jf.uj345.com'
let domain = 'https://jf.jinyawen.com'
// let domain = 'https://jf.hapengran.com'
// let domain = 'https://jjy-jf.uj345.com'
// let domain = 'https://ccd-jf.cichude.com'
@@ -17,7 +17,7 @@ module.exports = {
// HTTP_REQUEST_URL:'',
HTTP_REQUEST_URL: domain,
// H5商城地址
HTTP_H5_URL: 'https://czcf-jf.uj345.com',
HTTP_H5_URL: 'https://jf.jinyawen.com',
// #endif
// #ifdef H5
HTTP_REQUEST_URL:domain,

View File

@@ -34,7 +34,7 @@
export default {
data() {
return {
pdfUrl: '/static/sign_contract_czcf82.pdf',
pdfUrl: '/static/sign_contract_byjyw149.pdf',
userId: '',
isMobile: false,
usePdfJs: false,

View File

@@ -338,7 +338,7 @@ export default {
// 跳转到抢购页面
goToRushBuy() {
// #ifdef H5
window.location.href = 'https://czcf.uj345.com/?#/pages/personal/index'
window.location.href = 'https://jinyawen.com/?#/pages/personal/index'
// window.location.href = 'https://ccd.cichude.com/?#/pages/personal/index'
// window.location.href = 'https://shop.wenjinhui.com/?#/pages/personal/index'
//window.location.href = 'https://anyue.szxingming.com/?#/pages/personal/index'
@@ -347,7 +347,7 @@ export default {
// #endif
// #ifndef H5
uni.navigateTo({
url: '/pages/web-view/index?url=' + encodeURIComponent('https://czcf.uj345.com/?#/pages/personal/index')
url: '/pages/web-view/index?url=' + encodeURIComponent('https://jinyawen.com/?#/pages/personal/index')
})
// #endif
},

View File

@@ -16,7 +16,7 @@ export default {
},
onLoad(options) {
const url = options && options.url ? decodeURIComponent(options.url) : '/static/sign_contract_czcf82.pdf'
const url = options && options.url ? decodeURIComponent(options.url) : '/static/sign_contract_byjyw149.pdf'
this.pdfUrl = url
},

View File

@@ -360,7 +360,7 @@ export default {
});
// 返回
setTimeout(() => {
window.location.href = 'https://czcf.uj345.com/?#/pages/rushing/index' + (this.userId ? ('?user_id=' + this.userId) : '')
window.location.href = 'https://jinyawen.com/?#/pages/rushing/index' + (this.userId ? ('?user_id=' + this.userId) : '')
// window.location.href = 'https://shop.wenjinhui.com/?#/pages/rushing/index' + (this.userId ? ('?user_id=' + this.userId) : '')
// window.location.href = 'https://anyue.szxingming.com/?#/pages/rushing/index' + (this.userId ? ('?user_id=' + this.userId) : '')
// window.location.href = 'https://xiashengjun.com/?#/pages/rushing/index' + (this.userId ? ('?user_id=' + this.userId) : '')