feat: 团队订单与管理端订单代码重构、合并
This commit is contained in:
parent
f7d40414c0
commit
e1733e3f47
|
|
@ -8,11 +8,3 @@ export function listRecord(query) {
|
||||||
params: query
|
params: query
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查询团队(部门)余额变动详细(只读)
|
|
||||||
export function getRecord(id) {
|
|
||||||
return request({
|
|
||||||
url: '/ai/record/' + id,
|
|
||||||
method: 'get'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,9 @@ export function listSubteamChargeOrder(query) {
|
||||||
return request({ url: '/subteam/charge-order/list', method: 'get', params: query })
|
return request({ url: '/subteam/charge-order/list', method: 'get', params: query })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 导出:POST /subteam/charge-order/export(与列表相同查询参数 + 创建时间区间) */
|
||||||
|
export const subteamChargeOrderExportUrl = 'subteam/charge-order/export'
|
||||||
|
|
||||||
export function getSubteamChargeOrder(id) {
|
export function getSubteamChargeOrder(id) {
|
||||||
return request({ url: '/subteam/charge-order/' + id, method: 'get' })
|
return request({ url: '/subteam/charge-order/' + id, method: 'get' })
|
||||||
}
|
}
|
||||||
|
|
@ -74,14 +77,17 @@ export function getSubteamUserBalance(id) {
|
||||||
return request({ url: '/subteam/user-balance/' + id, method: 'get' })
|
return request({ url: '/subteam/user-balance/' + id, method: 'get' })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 列表:GET /subteam/consume-stat/list(参数与管理端 ai/data 一致:startDate、endDate、pageNum、pageSize) */
|
||||||
export function listSubteamConsumeStat(query) {
|
export function listSubteamConsumeStat(query) {
|
||||||
return request({ url: '/subteam/consume-stat/list', method: 'get', params: query })
|
return request({ url: '/subteam/consume-stat/list', method: 'get', params: query })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 导出:POST /subteam/consume-stat/export */
|
||||||
|
export const subteamConsumeStatExportUrl = 'subteam/consume-stat/export'
|
||||||
|
|
||||||
export function listSubteamGroupBalance(query) {
|
export function listSubteamGroupBalance(query) {
|
||||||
return request({ url: '/subteam/group-balance/list', method: 'get', params: query })
|
return request({ url: '/subteam/group-balance/list', method: 'get', params: query })
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getSubteamGroupBalance(id) {
|
/** 导出:POST /subteam/group-balance/export(与列表相同查询参数 + 创建时间区间) */
|
||||||
return request({ url: '/subteam/group-balance/' + id, method: 'get' })
|
export const subteamGroupBalanceExportUrl = 'subteam/group-balance/export'
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
|
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="90px">
|
||||||
<el-form-item label="订单号" prop="relationOrderNo">
|
<el-form-item label="关联订单号" prop="relationOrderNo">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="queryParams.relationOrderNo"
|
v-model="queryParams.relationOrderNo"
|
||||||
placeholder="请输入关联(充值/退款)订单号"
|
placeholder="支持模糊查询,充值/退款订单号"
|
||||||
clearable
|
clearable
|
||||||
style="width: 300px"
|
style="width: 240px"
|
||||||
@keyup.enter.native="handleQuery"
|
@keyup.enter.native="handleQuery"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
@ -178,9 +178,11 @@ export default {
|
||||||
this.handleQuery()
|
this.handleQuery()
|
||||||
},
|
},
|
||||||
handleExport() {
|
handleExport() {
|
||||||
this.download('ai/record/export', {
|
this.download(
|
||||||
...this.queryParams
|
'ai/record/export',
|
||||||
}, `record_${new Date().getTime()}.xlsx`)
|
this.addDateRange({ ...this.queryParams }, this.dateRange, 'CreateTime'),
|
||||||
|
`record_${new Date().getTime()}.xlsx`
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,23 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
<el-form v-show="showSearch" ref="queryForm" :model="queryParams" size="small" :inline="true" label-width="88px">
|
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="70px">
|
||||||
<el-form-item label="类型" prop="orderType">
|
<el-form-item label="订单号" prop="orderNum">
|
||||||
<el-select v-model="queryParams.orderType" clearable placeholder="全部">
|
<el-input
|
||||||
<el-option label="充值" :value="0" />
|
v-model="queryParams.orderNum"
|
||||||
<el-option label="退款" :value="1" />
|
placeholder="支持模糊搜索"
|
||||||
</el-select>
|
clearable
|
||||||
|
@keyup.enter.native="handleQuery"
|
||||||
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="订单编号" prop="orderNum">
|
<el-form-item label="类型" prop="orderType">
|
||||||
<el-input v-model="queryParams.orderNum" clearable @keyup.enter.native="handleQuery" />
|
<el-select v-model="queryParams.orderType" placeholder="全部" clearable style="width: 110px">
|
||||||
|
<el-option
|
||||||
|
v-for="item in orderTypeQueryOptions"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="创建时间">
|
<el-form-item label="创建时间">
|
||||||
<el-date-picker
|
<el-date-picker
|
||||||
|
|
@ -24,30 +33,61 @@
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||||||
|
<el-button
|
||||||
|
type="warning"
|
||||||
|
plain
|
||||||
|
icon="el-icon-download"
|
||||||
|
size="mini"
|
||||||
|
@click="handleExport"
|
||||||
|
v-hasPermi="['subteam:charge:export']"
|
||||||
|
>导出</el-button>
|
||||||
|
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<el-row class="mb8"><right-toolbar :show-search.sync="showSearch" @queryTable="getList" /></el-row>
|
|
||||||
<el-table v-loading="loading" :data="list">
|
<el-table v-loading="loading" :data="groupChargeOrderList">
|
||||||
<el-table-column label="ID" prop="id" width="70" />
|
<el-table-column label="订单号" align="center" prop="orderNum" width="200" show-overflow-tooltip />
|
||||||
<el-table-column label="团队" prop="deptName" min-width="100" show-overflow-tooltip />
|
<el-table-column label="类型" align="center" width="120">
|
||||||
<el-table-column label="类型" width="90">
|
<template slot-scope="scope">
|
||||||
<template slot-scope="s">{{ typeLabel(s.row.orderType) }}</template>
|
<span>{{ orderTypeLabel(scope.row.orderType) }}</span>
|
||||||
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="金额" prop="money" width="110" align="right">
|
<el-table-column label="金额(元)" align="center" prop="money" width="120">
|
||||||
<template slot-scope="s"><span>{{ formatMoney(s.row.money) }}</span></template>
|
<template slot-scope="scope">
|
||||||
|
<span>{{ formatTableMoney(scope.row.money) }}</span>
|
||||||
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="积分" prop="amount" width="110" align="right">
|
<el-table-column label="积分" align="center" prop="amount" width="120">
|
||||||
<template slot-scope="s"><span>{{ formatAmount(s.row.amount) }}</span></template>
|
<template slot-scope="scope">
|
||||||
|
<span>{{ formatTableAmount(scope.row.amount) }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="状态" align="center" width="100">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span>{{ statusLabel(scope.row.status) }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="备注" align="center" prop="remark" show-overflow-tooltip />
|
||||||
|
<el-table-column label="创建时间" align="center" prop="createTime" width="150">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span>{{ parseTime(scope.row.createTime) }}</span>
|
||||||
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="时间" width="160"><template slot-scope="s">{{ parseTime(s.row.createTime) }}</template></el-table-column>
|
|
||||||
<el-table-column label="备注" prop="remark" min-width="120" show-overflow-tooltip />
|
|
||||||
</el-table>
|
</el-table>
|
||||||
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" />
|
|
||||||
|
<pagination
|
||||||
|
v-show="total > 0"
|
||||||
|
:total="total"
|
||||||
|
:page.sync="queryParams.pageNum"
|
||||||
|
:limit.sync="queryParams.pageSize"
|
||||||
|
@pagination="getList"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { listSubteamChargeOrder } from '@/api/subteam'
|
import { listSubteamChargeOrder, subteamChargeOrderExportUrl } from '@/api/subteam'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'SubteamChargeOrder',
|
name: 'SubteamChargeOrder',
|
||||||
data() {
|
data() {
|
||||||
|
|
@ -55,42 +95,87 @@ export default {
|
||||||
loading: true,
|
loading: true,
|
||||||
showSearch: true,
|
showSearch: true,
|
||||||
dateRange: [],
|
dateRange: [],
|
||||||
list: [],
|
|
||||||
total: 0,
|
total: 0,
|
||||||
queryParams: { pageNum: 1, pageSize: 10, orderType: undefined, orderNum: undefined }
|
groupChargeOrderList: [],
|
||||||
|
queryParams: {
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
orderNum: null,
|
||||||
|
orderType: null
|
||||||
|
},
|
||||||
|
orderTypeQueryOptions: [
|
||||||
|
{ label: '充值', value: 0 },
|
||||||
|
{ label: '退款', value: 1 }
|
||||||
|
],
|
||||||
|
orderTypeOptions: [
|
||||||
|
{ label: '充值', value: 0 },
|
||||||
|
{ label: '退款', value: 1 },
|
||||||
|
{ label: '手动修改', value: 2 }
|
||||||
|
],
|
||||||
|
statusOptions: [
|
||||||
|
{ label: '进行中', value: 0 },
|
||||||
|
{ label: '已完成', value: 1 },
|
||||||
|
{ label: '失败', value: 2 }
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() { this.getList() },
|
created() {
|
||||||
|
this.getList()
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
formatMoney(value) {
|
formatTableMoney(value) {
|
||||||
if (value == null || value === '') return '—'
|
if (value === null || value === undefined || value === '') {
|
||||||
|
return '—'
|
||||||
|
}
|
||||||
const n = Number(value)
|
const n = Number(value)
|
||||||
if (Number.isNaN(n)) return '—'
|
if (Number.isNaN(n)) {
|
||||||
|
return '—'
|
||||||
|
}
|
||||||
return n.toLocaleString('en-US', { maximumFractionDigits: 2, minimumFractionDigits: 0 })
|
return n.toLocaleString('en-US', { maximumFractionDigits: 2, minimumFractionDigits: 0 })
|
||||||
},
|
},
|
||||||
formatAmount(value) {
|
formatTableAmount(value) {
|
||||||
if (value == null || value === '') return '—'
|
if (value === null || value === undefined || value === '') {
|
||||||
|
return '—'
|
||||||
|
}
|
||||||
const n = Number(value)
|
const n = Number(value)
|
||||||
if (Number.isNaN(n)) return '—'
|
if (Number.isNaN(n)) {
|
||||||
|
return '—'
|
||||||
|
}
|
||||||
return n.toLocaleString('en-US', { maximumFractionDigits: 0 })
|
return n.toLocaleString('en-US', { maximumFractionDigits: 0 })
|
||||||
},
|
},
|
||||||
typeLabel(t) {
|
orderTypeLabel(orderType) {
|
||||||
const m = { 0: '充值', 1: '退款', 2: '手动修改' }
|
const n = orderType !== undefined && orderType !== null ? Number(orderType) : null
|
||||||
return m[t] != null ? m[t] : '—'
|
const hit = this.orderTypeOptions.find(o => o.value === n)
|
||||||
|
return hit ? hit.label : '—'
|
||||||
|
},
|
||||||
|
statusLabel(status) {
|
||||||
|
const n = status !== undefined && status !== null ? Number(status) : null
|
||||||
|
const hit = this.statusOptions.find(o => o.value === n)
|
||||||
|
return hit ? hit.label : '—'
|
||||||
},
|
},
|
||||||
getList() {
|
getList() {
|
||||||
this.loading = true
|
this.loading = true
|
||||||
listSubteamChargeOrder(this.addDateRange(this.queryParams, this.dateRange, 'CreateTime')).then(res => {
|
listSubteamChargeOrder(this.addDateRange(this.queryParams, this.dateRange, 'CreateTime')).then(response => {
|
||||||
this.list = res.rows
|
this.groupChargeOrderList = response.rows
|
||||||
this.total = res.total
|
this.total = response.total
|
||||||
this.loading = false
|
this.loading = false
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
handleQuery() { this.queryParams.pageNum = 1; this.getList() },
|
handleQuery() {
|
||||||
|
this.queryParams.pageNum = 1
|
||||||
|
this.getList()
|
||||||
|
},
|
||||||
resetQuery() {
|
resetQuery() {
|
||||||
this.dateRange = []
|
this.dateRange = []
|
||||||
this.resetForm('queryForm')
|
this.resetForm('queryForm')
|
||||||
this.handleQuery()
|
this.handleQuery()
|
||||||
|
},
|
||||||
|
handleExport() {
|
||||||
|
this.download(
|
||||||
|
subteamChargeOrderExportUrl,
|
||||||
|
this.addDateRange({ ...this.queryParams }, this.dateRange, 'CreateTime'),
|
||||||
|
`group_charge_order_${new Date().getTime()}.xlsx`
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,62 +1,195 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
<el-form ref="queryForm" :model="queryParams" size="small" :inline="true" label-width="96px">
|
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="96px">
|
||||||
<el-form-item label="统计日期" prop="statDate">
|
<el-form-item label="统计日期">
|
||||||
<el-date-picker v-model="queryParams.statDate" type="date" value-format="yyyyMMdd" placeholder="请选择日期" clearable />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="创建时间">
|
|
||||||
<el-date-picker
|
<el-date-picker
|
||||||
v-model="dateRange"
|
v-model="dateRange"
|
||||||
style="width: 240px"
|
|
||||||
value-format="yyyy-MM-dd"
|
|
||||||
type="daterange"
|
type="daterange"
|
||||||
range-separator="-"
|
unlink-panels
|
||||||
|
value-format="yyyy-MM-dd"
|
||||||
|
range-separator="至"
|
||||||
start-placeholder="开始日期"
|
start-placeholder="开始日期"
|
||||||
end-placeholder="结束日期"
|
end-placeholder="结束日期"
|
||||||
|
style="width: 280px"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||||||
|
<el-button
|
||||||
|
type="warning"
|
||||||
|
plain
|
||||||
|
icon="el-icon-download"
|
||||||
|
size="mini"
|
||||||
|
@click="handleExport"
|
||||||
|
v-hasPermi="['subteam:consume:export']"
|
||||||
|
>导出</el-button>
|
||||||
|
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<p class="tip">仅展示当前团队数据;请选择日期后查询。</p>
|
|
||||||
<el-table v-loading="loading" :data="list">
|
<p class="summary-line">
|
||||||
<el-table-column label="日期" prop="dateKey" />
|
<template v-if="summaryState.mode === 'loading'">
|
||||||
<el-table-column label="团队" prop="deptName" />
|
<span> </span>
|
||||||
<el-table-column label="充值积分" prop="rechargeScore" />
|
<span class="summary-prefix">汇总:</span><span class="summary-muted">加载中…</span>
|
||||||
<el-table-column label="消耗积分" prop="score" />
|
</template>
|
||||||
<el-table-column label="成功订单" prop="orderCount" />
|
<template v-else-if="summaryState.mode === 'empty'">
|
||||||
<el-table-column label="Tokens" prop="useTokens" />
|
<span> </span>
|
||||||
|
<span class="summary-prefix">汇总:</span><span class="summary-muted">—</span>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<span> </span>
|
||||||
|
<span class="summary-prefix">汇总:</span>
|
||||||
|
<span class="summary-label">总计</span>
|
||||||
|
<span class="summary-num">{{ summaryState.totalStr }}</span>
|
||||||
|
<span class="summary-label">条记录,实际充值积分</span>
|
||||||
|
<span class="summary-num">{{ summaryState.recharge }}</span>
|
||||||
|
<span class="summary-unit">分</span>
|
||||||
|
<span class="summary-label">,消耗积分</span>
|
||||||
|
<span class="summary-num">{{ summaryState.score }}</span>
|
||||||
|
<span class="summary-unit">分</span>
|
||||||
|
<span class="summary-label">,实际订单数量(成功)</span>
|
||||||
|
<span class="summary-num">{{ summaryState.orders }}</span>
|
||||||
|
<span class="summary-unit">单</span>
|
||||||
|
<span class="summary-label">,三方消耗tokens数量</span>
|
||||||
|
<span class="summary-num">{{ summaryState.tokens }}</span>
|
||||||
|
<span class="summary-unit">。</span>
|
||||||
|
</template>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<el-table v-loading="loading" :data="dataList">
|
||||||
|
<el-table-column label="日期" align="center" prop="dateKey" min-width="110" />
|
||||||
|
<el-table-column
|
||||||
|
label="实际充值积分(充值-退款)"
|
||||||
|
align="center"
|
||||||
|
prop="rechargeScore"
|
||||||
|
min-width="200"
|
||||||
|
:formatter="formatWesternNumber"
|
||||||
|
/>
|
||||||
|
<el-table-column label="消耗积分" align="center" prop="score" width="120" :formatter="formatWesternNumber" />
|
||||||
|
<el-table-column
|
||||||
|
label="实际订单数量(成功)"
|
||||||
|
align="center"
|
||||||
|
prop="orderCount"
|
||||||
|
width="160"
|
||||||
|
:formatter="formatWesternNumber"
|
||||||
|
/>
|
||||||
|
<el-table-column
|
||||||
|
label="三方消耗tokens数量"
|
||||||
|
align="center"
|
||||||
|
prop="useTokens"
|
||||||
|
width="170"
|
||||||
|
:formatter="formatWesternNumber"
|
||||||
|
/>
|
||||||
</el-table>
|
</el-table>
|
||||||
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" />
|
|
||||||
|
<pagination
|
||||||
|
v-show="total>0"
|
||||||
|
:total="total"
|
||||||
|
:page.sync="queryParams.pageNum"
|
||||||
|
:limit.sync="queryParams.pageSize"
|
||||||
|
@pagination="getList"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { listSubteamConsumeStat } from '@/api/subteam'
|
import { listSubteamConsumeStat, subteamConsumeStatExportUrl } from '@/api/subteam'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'SubteamConsumeStat',
|
name: 'SubteamConsumeStat',
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
loading: false,
|
loading: false,
|
||||||
dateRange: [],
|
showSearch: true,
|
||||||
list: [],
|
|
||||||
total: 0,
|
total: 0,
|
||||||
queryParams: { pageNum: 1, pageSize: 10, statDate: null }
|
dataList: [],
|
||||||
|
aggregate: null,
|
||||||
|
dateRange: [],
|
||||||
|
queryParams: {
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
startDate: null,
|
||||||
|
endDate: null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.initDefaultDateRange()
|
||||||
|
this.syncDateRangeToQuery()
|
||||||
|
this.getList()
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
summaryState() {
|
||||||
|
if (this.loading) {
|
||||||
|
return { mode: 'loading' }
|
||||||
|
}
|
||||||
|
const a = this.aggregate
|
||||||
|
if (!a) {
|
||||||
|
return { mode: 'empty' }
|
||||||
|
}
|
||||||
|
const fmt = (v) => this.formatWesternNumberValue(v)
|
||||||
|
const n = a.totalRows != null ? Number(a.totalRows) : 0
|
||||||
|
const totalStr = Number.isNaN(n) ? '0' : n.toLocaleString('en-US')
|
||||||
|
return {
|
||||||
|
mode: 'ok',
|
||||||
|
totalStr,
|
||||||
|
recharge: fmt(a.sumRechargeScore),
|
||||||
|
score: fmt(a.sumScore),
|
||||||
|
orders: fmt(a.sumOrderCount),
|
||||||
|
tokens: fmt(a.sumUseTokens)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getList() {
|
formatWesternNumberValue(cellValue) {
|
||||||
if (!this.queryParams.statDate) {
|
if (cellValue === null || cellValue === undefined || cellValue === '') {
|
||||||
this.list = []
|
return (0).toLocaleString('en-US')
|
||||||
this.total = 0
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
const n = Number(cellValue)
|
||||||
|
if (Number.isNaN(n)) {
|
||||||
|
return (0).toLocaleString('en-US')
|
||||||
|
}
|
||||||
|
return n.toLocaleString('en-US')
|
||||||
|
},
|
||||||
|
formatWesternNumber(row, column, cellValue) {
|
||||||
|
return this.formatWesternNumberValue(cellValue)
|
||||||
|
},
|
||||||
|
buildLastMonthDateRange() {
|
||||||
|
const end = new Date()
|
||||||
|
const start = new Date(end.getTime())
|
||||||
|
start.setMonth(start.getMonth() - 1)
|
||||||
|
return [this.formatYmd(start), this.formatYmd(end)]
|
||||||
|
},
|
||||||
|
formatYmd(d) {
|
||||||
|
const y = d.getFullYear()
|
||||||
|
const m = String(d.getMonth() + 1).padStart(2, '0')
|
||||||
|
const day = String(d.getDate()).padStart(2, '0')
|
||||||
|
return `${y}-${m}-${day}`
|
||||||
|
},
|
||||||
|
initDefaultDateRange() {
|
||||||
|
this.dateRange = this.buildLastMonthDateRange()
|
||||||
|
},
|
||||||
|
syncDateRangeToQuery() {
|
||||||
|
if (Array.isArray(this.dateRange) && this.dateRange.length === 2) {
|
||||||
|
this.queryParams.startDate = this.dateRange[0]
|
||||||
|
this.queryParams.endDate = this.dateRange[1]
|
||||||
|
} else {
|
||||||
|
this.queryParams.startDate = null
|
||||||
|
this.queryParams.endDate = null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getList() {
|
||||||
|
this.syncDateRangeToQuery()
|
||||||
this.loading = true
|
this.loading = true
|
||||||
listSubteamConsumeStat(this.addDateRange(this.queryParams, this.dateRange, 'CreateTime')).then(res => {
|
listSubteamConsumeStat(this.queryParams)
|
||||||
this.list = res.rows
|
.then(response => {
|
||||||
this.total = res.total
|
this.dataList = response.rows || []
|
||||||
|
this.total = response.total != null ? response.total : 0
|
||||||
|
this.aggregate =
|
||||||
|
response.param && response.param.aggregate != null ? response.param.aggregate : null
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
this.loading = false
|
this.loading = false
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
@ -65,15 +198,61 @@ export default {
|
||||||
this.getList()
|
this.getList()
|
||||||
},
|
},
|
||||||
resetQuery() {
|
resetQuery() {
|
||||||
this.dateRange = []
|
this.initDefaultDateRange()
|
||||||
this.resetForm('queryForm')
|
this.resetForm('queryForm')
|
||||||
this.list = []
|
this.queryParams.pageNum = 1
|
||||||
this.total = 0
|
this.syncDateRangeToQuery()
|
||||||
|
this.getList()
|
||||||
|
},
|
||||||
|
handleExport() {
|
||||||
|
this.syncDateRangeToQuery()
|
||||||
|
this.download(
|
||||||
|
subteamConsumeStatExportUrl,
|
||||||
|
{
|
||||||
|
startDate: this.queryParams.startDate,
|
||||||
|
endDate: this.queryParams.endDate
|
||||||
|
},
|
||||||
|
`team_consume_${new Date().getTime()}.xlsx`
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.tip { color: #909399; font-size: 13px; margin-bottom: 12px; }
|
.summary-line {
|
||||||
|
color: #606266;
|
||||||
|
font-size: 13px;
|
||||||
|
margin: 0 0 12px 0;
|
||||||
|
padding-left: 8px;
|
||||||
|
line-height: 1.75;
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-prefix {
|
||||||
|
color: #909399;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-right: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-muted {
|
||||||
|
color: #c0c4cc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-label {
|
||||||
|
color: #606266;
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-unit {
|
||||||
|
color: #909399;
|
||||||
|
font-size: 12px;
|
||||||
|
margin-left: 1px;
|
||||||
|
margin-right: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-num {
|
||||||
|
color: #409eff;
|
||||||
|
font-weight: 600;
|
||||||
|
font-variant-numeric: tabular-nums;
|
||||||
|
margin: 0 2px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,20 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
<el-form v-show="showSearch" ref="queryForm" :model="queryParams" size="small" :inline="true">
|
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="90px">
|
||||||
|
<el-form-item label="关联订单号" prop="relationOrderNo">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.relationOrderNo"
|
||||||
|
placeholder="支持模糊查询,充值/退款订单号"
|
||||||
|
clearable
|
||||||
|
style="width: 240px"
|
||||||
|
@keyup.enter.native="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
<el-form-item label="类型" prop="type">
|
<el-form-item label="类型" prop="type">
|
||||||
<el-select v-model="queryParams.type" clearable placeholder="全部类型" style="width: 180px">
|
<el-select v-model="queryParams.type" clearable placeholder="全部类型" style="width: 112px">
|
||||||
<el-option v-for="item in typeOptions" :key="item.value" :label="item.label" :value="item.value" />
|
<el-option v-for="item in typeOptions" :key="item.value" :label="item.label" :value="item.value" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="关联单号" prop="relationOrderNo">
|
|
||||||
<el-input v-model="queryParams.relationOrderNo" clearable @keyup.enter.native="handleQuery" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="创建时间">
|
<el-form-item label="创建时间">
|
||||||
<el-date-picker
|
<el-date-picker
|
||||||
v-model="dateRange"
|
v-model="dateRange"
|
||||||
|
|
@ -23,31 +29,61 @@
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||||||
|
<el-button
|
||||||
|
type="warning"
|
||||||
|
plain
|
||||||
|
icon="el-icon-download"
|
||||||
|
size="mini"
|
||||||
|
@click="handleExport"
|
||||||
|
v-hasPermi="['subteam:groupBalance:export']"
|
||||||
|
>导出</el-button>
|
||||||
|
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<el-row class="mb8"><right-toolbar :show-search.sync="showSearch" @queryTable="getList" /></el-row>
|
|
||||||
<el-table v-loading="loading" :data="list">
|
<el-table v-loading="loading" :data="recordList">
|
||||||
<el-table-column label="ID" prop="id" width="80" />
|
<el-table-column label="ID" align="center" prop="id" width="100" />
|
||||||
<el-table-column label="关联单号" prop="relationOrderNo" min-width="120" show-overflow-tooltip />
|
<el-table-column label="关联订单号" align="center" prop="relationOrderNo" width="200" show-overflow-tooltip />
|
||||||
<el-table-column label="类型" width="100">
|
<el-table-column label="操作类型" align="center" width="120">
|
||||||
<template slot-scope="s">
|
<template slot-scope="scope">
|
||||||
<span>{{ typeLabel(s.row.type) }}</span>
|
<span>{{ typeLabel(scope.row.type) }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="变更积分" prop="changeAmount" width="120" align="right">
|
<el-table-column
|
||||||
<template slot-scope="s"><span>{{ formatChangeAmount(s.row) }}</span></template>
|
label="变更积分"
|
||||||
|
align="center"
|
||||||
|
prop="changeAmount"
|
||||||
|
width="120"
|
||||||
|
:formatter="formatChangeAmount"
|
||||||
|
/>
|
||||||
|
<el-table-column
|
||||||
|
label="变更后积分"
|
||||||
|
align="center"
|
||||||
|
prop="resultAmount"
|
||||||
|
width="120"
|
||||||
|
:formatter="formatResultAmount"
|
||||||
|
/>
|
||||||
|
<el-table-column label="备注" align="center" prop="remark" />
|
||||||
|
<el-table-column label="创建时间" align="center" prop="createTime" width="160">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span>{{ parseTime(scope.row.createTime) }}</span>
|
||||||
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="变更后积分" prop="resultAmount" width="120" align="right">
|
|
||||||
<template slot-scope="s"><span>{{ formatResultAmount(s.row) }}</span></template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="时间" width="160"><template slot-scope="s">{{ parseTime(s.row.createTime) }}</template></el-table-column>
|
|
||||||
</el-table>
|
</el-table>
|
||||||
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" />
|
|
||||||
|
<pagination
|
||||||
|
v-show="total > 0"
|
||||||
|
:total="total"
|
||||||
|
:page.sync="queryParams.pageNum"
|
||||||
|
:limit.sync="queryParams.pageSize"
|
||||||
|
@pagination="getList"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { listSubteamGroupBalance } from '@/api/subteam'
|
import { listSubteamGroupBalance, subteamGroupBalanceExportUrl } from '@/api/subteam'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'SubteamGroupBalance',
|
name: 'SubteamGroupBalance',
|
||||||
data() {
|
data() {
|
||||||
|
|
@ -55,8 +91,8 @@ export default {
|
||||||
loading: true,
|
loading: true,
|
||||||
showSearch: true,
|
showSearch: true,
|
||||||
dateRange: [],
|
dateRange: [],
|
||||||
list: [],
|
|
||||||
total: 0,
|
total: 0,
|
||||||
|
recordList: [],
|
||||||
typeOptions: [
|
typeOptions: [
|
||||||
{ label: '充值', value: 0 },
|
{ label: '充值', value: 0 },
|
||||||
{ label: '退款', value: 1 },
|
{ label: '退款', value: 1 },
|
||||||
|
|
@ -64,10 +100,17 @@ export default {
|
||||||
{ label: '回收', value: 3 },
|
{ label: '回收', value: 3 },
|
||||||
{ label: '手动修改', value: 4 }
|
{ label: '手动修改', value: 4 }
|
||||||
],
|
],
|
||||||
queryParams: { pageNum: 1, pageSize: 10, type: undefined, relationOrderNo: undefined }
|
queryParams: {
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
relationOrderNo: null,
|
||||||
|
type: null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() { this.getList() },
|
created() {
|
||||||
|
this.getList()
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
formatPointsWestern(value) {
|
formatPointsWestern(value) {
|
||||||
if (value === null || value === undefined || value === '') {
|
if (value === null || value === undefined || value === '') {
|
||||||
|
|
@ -89,8 +132,12 @@ export default {
|
||||||
return String(value)
|
return String(value)
|
||||||
}
|
}
|
||||||
const formatted = Math.abs(n).toLocaleString('en-US', { maximumFractionDigits: 0 })
|
const formatted = Math.abs(n).toLocaleString('en-US', { maximumFractionDigits: 0 })
|
||||||
if (n > 0) return `+${formatted}`
|
if (n > 0) {
|
||||||
if (n < 0) return `-${formatted}`
|
return `+${formatted}`
|
||||||
|
}
|
||||||
|
if (n < 0) {
|
||||||
|
return `-${formatted}`
|
||||||
|
}
|
||||||
return '0'
|
return '0'
|
||||||
},
|
},
|
||||||
formatResultAmount(row) {
|
formatResultAmount(row) {
|
||||||
|
|
@ -103,17 +150,27 @@ export default {
|
||||||
},
|
},
|
||||||
getList() {
|
getList() {
|
||||||
this.loading = true
|
this.loading = true
|
||||||
listSubteamGroupBalance(this.addDateRange(this.queryParams, this.dateRange, 'CreateTime')).then(res => {
|
listSubteamGroupBalance(this.addDateRange(this.queryParams, this.dateRange, 'CreateTime')).then(response => {
|
||||||
this.list = res.rows
|
this.recordList = response.rows
|
||||||
this.total = res.total
|
this.total = response.total
|
||||||
this.loading = false
|
this.loading = false
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
handleQuery() { this.queryParams.pageNum = 1; this.getList() },
|
handleQuery() {
|
||||||
|
this.queryParams.pageNum = 1
|
||||||
|
this.getList()
|
||||||
|
},
|
||||||
resetQuery() {
|
resetQuery() {
|
||||||
this.dateRange = []
|
this.dateRange = []
|
||||||
this.resetForm('queryForm')
|
this.resetForm('queryForm')
|
||||||
this.handleQuery()
|
this.handleQuery()
|
||||||
|
},
|
||||||
|
handleExport() {
|
||||||
|
this.download(
|
||||||
|
subteamGroupBalanceExportUrl,
|
||||||
|
this.addDateRange({ ...this.queryParams }, this.dateRange, 'CreateTime'),
|
||||||
|
`group_balance_record_${new Date().getTime()}.xlsx`
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,12 +6,10 @@ import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import com.ruoyi.common.annotation.Log;
|
import com.ruoyi.common.annotation.Log;
|
||||||
import com.ruoyi.common.core.controller.BaseController;
|
import com.ruoyi.common.core.controller.BaseController;
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
|
||||||
import com.ruoyi.common.enums.BusinessType;
|
import com.ruoyi.common.enums.BusinessType;
|
||||||
import com.ruoyi.ai.domain.AiGroupBalanceChangeRecord;
|
import com.ruoyi.ai.domain.AiGroupBalanceChangeRecord;
|
||||||
import com.ruoyi.ai.service.IAiGroupBalanceChangeRecordService;
|
import com.ruoyi.ai.service.IAiGroupBalanceChangeRecordService;
|
||||||
|
|
@ -55,14 +53,4 @@ public class AiGroupBalanceChangeRecordController extends BaseController
|
||||||
ExcelUtil<AiGroupBalanceChangeRecord> util = new ExcelUtil<AiGroupBalanceChangeRecord>(AiGroupBalanceChangeRecord.class);
|
ExcelUtil<AiGroupBalanceChangeRecord> util = new ExcelUtil<AiGroupBalanceChangeRecord>(AiGroupBalanceChangeRecord.class);
|
||||||
util.exportExcel(response, list, "团队(部门)余额变动数据");
|
util.exportExcel(response, list, "团队(部门)余额变动数据");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取团队(部门)余额变动详细信息
|
|
||||||
*/
|
|
||||||
@PreAuthorize("@ss.hasPermi('ai:record:query')")
|
|
||||||
@GetMapping(value = "/{id}")
|
|
||||||
public AjaxResult getInfo(@PathVariable("id") Long id)
|
|
||||||
{
|
|
||||||
return success(aiGroupBalanceChangeRecordService.selectAiGroupBalanceChangeRecordById(id));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,27 +1,28 @@
|
||||||
package com.ruoyi.web.controller.subteam;
|
package com.ruoyi.web.controller.subteam;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import com.ruoyi.ai.domain.AiChargeRefundOrder;
|
import com.ruoyi.ai.domain.AiChargeRefundOrder;
|
||||||
|
import com.ruoyi.ai.service.IAiChargeRefundOrderService;
|
||||||
|
import com.ruoyi.common.annotation.Log;
|
||||||
import com.ruoyi.common.core.controller.BaseController;
|
import com.ruoyi.common.core.controller.BaseController;
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
import com.ruoyi.common.core.page.TableDataInfo;
|
import com.ruoyi.common.core.page.TableDataInfo;
|
||||||
import com.ruoyi.system.service.subteam.ISubteamDataQueryService;
|
import com.ruoyi.common.enums.BusinessType;
|
||||||
|
import com.ruoyi.common.utils.poi.ExcelUtil;
|
||||||
import com.ruoyi.system.service.subteam.ISubteamScopeService;
|
import com.ruoyi.system.service.subteam.ISubteamScopeService;
|
||||||
import com.ruoyi.ai.service.IAiChargeRefundOrderService;
|
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/subteam/charge-order")
|
@RequestMapping("/subteam/charge-order")
|
||||||
public class SubteamChargeOrderController extends BaseController {
|
public class SubteamChargeOrderController extends BaseController {
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private ISubteamDataQueryService subteamDataQueryService;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ISubteamScopeService subteamScopeService;
|
private ISubteamScopeService subteamScopeService;
|
||||||
|
|
||||||
|
|
@ -32,10 +33,19 @@ public class SubteamChargeOrderController extends BaseController {
|
||||||
@GetMapping("/list")
|
@GetMapping("/list")
|
||||||
public TableDataInfo list(AiChargeRefundOrder query) {
|
public TableDataInfo list(AiChargeRefundOrder query) {
|
||||||
startPage();
|
startPage();
|
||||||
List<AiChargeRefundOrder> list = subteamDataQueryService.selectChargeRefundOrders(query);
|
List<AiChargeRefundOrder> list = aiChargeRefundOrderService.selectAiChargeRefundOrderListForCurrentSubteam(query);
|
||||||
return getDataTable(list);
|
return getDataTable(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PreAuthorize("@ss.hasPermi('subteam:charge:export')")
|
||||||
|
@Log(title = "团队充值记录", businessType = BusinessType.EXPORT)
|
||||||
|
@PostMapping("/export")
|
||||||
|
public void export(HttpServletResponse response, AiChargeRefundOrder query) {
|
||||||
|
List<AiChargeRefundOrder> list = aiChargeRefundOrderService.selectAiChargeRefundOrderListForCurrentSubteam(query);
|
||||||
|
ExcelUtil<AiChargeRefundOrder> util = new ExcelUtil<AiChargeRefundOrder>(AiChargeRefundOrder.class);
|
||||||
|
util.exportExcel(response, list, "团队充值退款订单数据");
|
||||||
|
}
|
||||||
|
|
||||||
@PreAuthorize("@ss.hasPermi('subteam:charge:query')")
|
@PreAuthorize("@ss.hasPermi('subteam:charge:query')")
|
||||||
@GetMapping("/{id}")
|
@GetMapping("/{id}")
|
||||||
public AjaxResult getInfo(@PathVariable Long id) {
|
public AjaxResult getInfo(@PathVariable Long id) {
|
||||||
|
|
|
||||||
|
|
@ -1,32 +1,78 @@
|
||||||
package com.ruoyi.web.controller.subteam;
|
package com.ruoyi.web.controller.subteam;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import com.ruoyi.ai.domain.AiVideoReportData;
|
import com.ruoyi.ai.domain.AiVideoReportData;
|
||||||
|
import com.ruoyi.ai.domain.request.GroupReportDataRequest;
|
||||||
|
import com.ruoyi.ai.domain.vo.SubteamConsumeStatExportRow;
|
||||||
|
import com.ruoyi.ai.domain.vo.TeamDailyConsumeAggregateVO;
|
||||||
|
import com.ruoyi.ai.service.IAiVideoReportDataService;
|
||||||
|
import com.ruoyi.common.annotation.Log;
|
||||||
|
import com.ruoyi.common.constant.HttpStatus;
|
||||||
import com.ruoyi.common.core.controller.BaseController;
|
import com.ruoyi.common.core.controller.BaseController;
|
||||||
import com.ruoyi.common.core.page.TableDataInfo;
|
import com.ruoyi.common.core.page.TableDataInfo;
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.enums.BusinessType;
|
||||||
import com.ruoyi.system.service.subteam.ISubteamDataQueryService;
|
import com.ruoyi.common.utils.poi.ExcelUtil;
|
||||||
|
import com.ruoyi.system.service.subteam.ISubteamScopeService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 团队后台「消耗统计」:与管理端 /ai/data 同一套 Service / Mapper,仅强制限定为当前登录人所属团队。
|
||||||
|
*/
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/subteam/consume-stat")
|
@RequestMapping("/subteam/consume-stat")
|
||||||
public class SubteamConsumeStatController extends BaseController {
|
public class SubteamConsumeStatController extends BaseController {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ISubteamDataQueryService subteamDataQueryService;
|
private IAiVideoReportDataService aiVideoReportDataService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ISubteamScopeService subteamScopeService;
|
||||||
|
|
||||||
@PreAuthorize("@ss.hasPermi('subteam:consume:list')")
|
@PreAuthorize("@ss.hasPermi('subteam:consume:list')")
|
||||||
@GetMapping("/list")
|
@GetMapping("/list")
|
||||||
public TableDataInfo list(AiVideoReportData query) {
|
public TableDataInfo list(@ModelAttribute GroupReportDataRequest query) {
|
||||||
if (StringUtils.isEmpty(query.getStatDate())) {
|
GroupReportDataRequest scoped = applyTeamScope(query);
|
||||||
return getDataTable(java.util.Collections.emptyList());
|
TeamDailyConsumeAggregateVO aggregate = aiVideoReportDataService.selectTeamDailyConsumeAggregate(scoped);
|
||||||
|
List<AiVideoReportData> list = aiVideoReportDataService.selectTeamDailyConsumeListPaged(scoped);
|
||||||
|
TableDataInfo rsp = new TableDataInfo();
|
||||||
|
rsp.setCode(HttpStatus.SUCCESS);
|
||||||
|
rsp.setMsg("查询成功");
|
||||||
|
rsp.setRows(list);
|
||||||
|
rsp.setTotal(aggregate.getTotalRows());
|
||||||
|
Map<String, Object> param = new HashMap<>(2);
|
||||||
|
param.put("aggregate", aggregate);
|
||||||
|
rsp.setParam(param);
|
||||||
|
return rsp;
|
||||||
}
|
}
|
||||||
startPage();
|
|
||||||
List<AiVideoReportData> list = subteamDataQueryService.selectTeamDailyConsume(query.getStatDate());
|
@PreAuthorize("@ss.hasPermi('subteam:consume:export')")
|
||||||
return getDataTable(list);
|
@Log(title = "团队消耗统计", businessType = BusinessType.EXPORT)
|
||||||
|
@PostMapping("/export")
|
||||||
|
public void export(HttpServletResponse response, @ModelAttribute GroupReportDataRequest query) {
|
||||||
|
if (query != null) {
|
||||||
|
query.setPageNum(null);
|
||||||
|
query.setPageSize(null);
|
||||||
|
}
|
||||||
|
GroupReportDataRequest scoped = applyTeamScope(query);
|
||||||
|
List<AiVideoReportData> list = aiVideoReportDataService.selectTeamDailyConsumeList(scoped);
|
||||||
|
List<SubteamConsumeStatExportRow> rows = list.stream().map(SubteamConsumeStatExportRow::from).collect(Collectors.toList());
|
||||||
|
ExcelUtil<SubteamConsumeStatExportRow> util = new ExcelUtil<>(SubteamConsumeStatExportRow.class);
|
||||||
|
util.exportExcel(response, rows, "团队消耗统计");
|
||||||
|
}
|
||||||
|
|
||||||
|
private GroupReportDataRequest applyTeamScope(GroupReportDataRequest query) {
|
||||||
|
GroupReportDataRequest q = query == null ? new GroupReportDataRequest() : query;
|
||||||
|
q.setDeptId(subteamScopeService.currentTeamDeptId());
|
||||||
|
return q;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,45 +1,62 @@
|
||||||
package com.ruoyi.web.controller.subteam;
|
package com.ruoyi.web.controller.subteam;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
import com.ruoyi.common.annotation.Log;
|
||||||
|
import com.ruoyi.common.enums.BusinessType;
|
||||||
import com.ruoyi.ai.domain.AiGroupBalanceChangeRecord;
|
import com.ruoyi.ai.domain.AiGroupBalanceChangeRecord;
|
||||||
import com.ruoyi.ai.service.IAiGroupBalanceChangeRecordService;
|
import com.ruoyi.ai.service.IAiGroupBalanceChangeRecordService;
|
||||||
import com.ruoyi.common.core.controller.BaseController;
|
import com.ruoyi.common.core.controller.BaseController;
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
|
||||||
import com.ruoyi.common.core.page.TableDataInfo;
|
import com.ruoyi.common.core.page.TableDataInfo;
|
||||||
import com.ruoyi.system.service.subteam.ISubteamDataQueryService;
|
import com.ruoyi.common.utils.poi.ExcelUtil;
|
||||||
import com.ruoyi.system.service.subteam.ISubteamScopeService;
|
import com.ruoyi.system.service.subteam.ISubteamScopeService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 团队后台:本团队总积分变动。列表/导出与 {@link com.ruoyi.ai.controller.AiGroupBalanceChangeRecordController} 同源,
|
||||||
|
* 使用 {@link IAiGroupBalanceChangeRecordService},仅通过 {@link ISubteamScopeService} 限定当前团队 deptId。
|
||||||
|
*/
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/subteam/group-balance")
|
@RequestMapping("/subteam/group-balance")
|
||||||
public class SubteamGroupBalanceController extends BaseController {
|
public class SubteamGroupBalanceController extends BaseController {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ISubteamDataQueryService subteamDataQueryService;
|
private IAiGroupBalanceChangeRecordService aiGroupBalanceChangeRecordService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ISubteamScopeService subteamScopeService;
|
private ISubteamScopeService subteamScopeService;
|
||||||
|
|
||||||
@Autowired
|
/** 固定本团队,并禁止用团队名称条件跨团队过滤 */
|
||||||
private IAiGroupBalanceChangeRecordService aiGroupBalanceChangeRecordService;
|
private void applyTeamScope(AiGroupBalanceChangeRecord query) {
|
||||||
|
query.setDeptId(subteamScopeService.currentTeamDeptId());
|
||||||
|
query.setDeptName(null);
|
||||||
|
}
|
||||||
|
|
||||||
@PreAuthorize("@ss.hasPermi('subteam:groupBalance:list')")
|
@PreAuthorize("@ss.hasPermi('subteam:groupBalance:list')")
|
||||||
@GetMapping("/list")
|
@GetMapping("/list")
|
||||||
public TableDataInfo list(AiGroupBalanceChangeRecord query) {
|
public TableDataInfo list(AiGroupBalanceChangeRecord query) {
|
||||||
|
applyTeamScope(query);
|
||||||
startPage();
|
startPage();
|
||||||
List<AiGroupBalanceChangeRecord> list = subteamDataQueryService.selectGroupBalanceRecords(query);
|
List<AiGroupBalanceChangeRecord> list = aiGroupBalanceChangeRecordService.selectAiGroupBalanceChangeRecordList(query);
|
||||||
return getDataTable(list);
|
return getDataTable(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
@PreAuthorize("@ss.hasPermi('subteam:groupBalance:query')")
|
/**
|
||||||
@GetMapping("/{id}")
|
* 导出本团队积分变动(与管理端 /ai/record/export 同源逻辑,不含团队名称列)
|
||||||
public AjaxResult getInfo(@PathVariable Long id) {
|
*/
|
||||||
subteamScopeService.assertGroupBalanceRecordBelongsToTeam(id);
|
@PreAuthorize("@ss.hasPermi('subteam:groupBalance:export')")
|
||||||
return success(aiGroupBalanceChangeRecordService.selectAiGroupBalanceChangeRecordById(id));
|
@Log(title = "团队积分变动", businessType = BusinessType.EXPORT)
|
||||||
|
@PostMapping("/export")
|
||||||
|
public void export(HttpServletResponse response, AiGroupBalanceChangeRecord query) {
|
||||||
|
applyTeamScope(query);
|
||||||
|
List<AiGroupBalanceChangeRecord> list = aiGroupBalanceChangeRecordService.selectAiGroupBalanceChangeRecordList(query);
|
||||||
|
ExcelUtil<AiGroupBalanceChangeRecord> util = new ExcelUtil<AiGroupBalanceChangeRecord>(AiGroupBalanceChangeRecord.class);
|
||||||
|
util.hideColumn("deptName");
|
||||||
|
util.exportExcel(response, list, "团队积分变动");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,10 +9,17 @@ import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
|
|
||||||
|
import lombok.AccessLevel;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
import com.ruoyi.common.annotation.Excel;
|
import com.ruoyi.common.annotation.Excel;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 团队(部门)充值退款订单对象 ai_charge_refund_order
|
* 团队(部门)充值退款订单对象 ai_charge_refund_order
|
||||||
*
|
*
|
||||||
|
|
@ -81,4 +88,22 @@ public class AiChargeRefundOrder implements Serializable {
|
||||||
/** 状态:0-进行中 1-已完成 2-失败 */
|
/** 状态:0-进行中 1-已完成 2-失败 */
|
||||||
@Excel(name = "状态", readConverterExp = "0=进行中,1=已完成,2=失败")
|
@Excel(name = "状态", readConverterExp = "0=进行中,1=已完成,2=失败")
|
||||||
private Integer status;
|
private Integer status;
|
||||||
|
|
||||||
|
/** 请求参数(若依日期范围:params.beginCreateTime / params.endCreateTime) */
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_EMPTY)
|
||||||
|
@TableField(exist = false)
|
||||||
|
@Getter(AccessLevel.NONE)
|
||||||
|
@Setter(AccessLevel.NONE)
|
||||||
|
private Map<String, Object> params;
|
||||||
|
|
||||||
|
public Map<String, Object> getParams() {
|
||||||
|
if (params == null) {
|
||||||
|
params = new HashMap<>();
|
||||||
|
}
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setParams(Map<String, Object> params) {
|
||||||
|
this.params = params;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
package com.ruoyi.ai.domain.vo;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import com.ruoyi.common.annotation.Excel;
|
||||||
|
import com.ruoyi.ai.domain.AiVideoReportData;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 团队后台消耗统计导出行(不含团队 ID / 名称列)。
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class SubteamConsumeStatExportRow implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Excel(name = "日期", sort = 1)
|
||||||
|
private String dateKey;
|
||||||
|
|
||||||
|
@Excel(name = "实际充值积分(充值-退款)", sort = 2)
|
||||||
|
private BigDecimal rechargeScore;
|
||||||
|
|
||||||
|
@Excel(name = "消耗积分", sort = 3)
|
||||||
|
private BigDecimal score;
|
||||||
|
|
||||||
|
@Excel(name = "实际订单数量(成功)", sort = 4)
|
||||||
|
private Long orderCount;
|
||||||
|
|
||||||
|
@Excel(name = "三方消耗tokens数量", sort = 5)
|
||||||
|
private Long useTokens;
|
||||||
|
|
||||||
|
public static SubteamConsumeStatExportRow from(AiVideoReportData s) {
|
||||||
|
SubteamConsumeStatExportRow r = new SubteamConsumeStatExportRow();
|
||||||
|
r.setDateKey(s.getDateKey());
|
||||||
|
r.setRechargeScore(s.getRechargeScore());
|
||||||
|
r.setScore(s.getScore());
|
||||||
|
r.setOrderCount(s.getOrderCount());
|
||||||
|
r.setUseTokens(s.getUseTokens());
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -39,12 +39,6 @@ public interface AiVideoReportDataMapper extends BaseMapper<AiVideoReportData> {
|
||||||
@Param("offset") int offset,
|
@Param("offset") int offset,
|
||||||
@Param("limit") int limit);
|
@Param("limit") int limit);
|
||||||
|
|
||||||
/**
|
|
||||||
* 按团队部门、日期聚合(团队后台消耗统计)
|
|
||||||
*/
|
|
||||||
List<AiVideoReportData> selectTeamDailyConsumeByDeptId(@Param("statDate") String statDate,
|
|
||||||
@Param("deptId") Long deptId);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 近 N 日(含)按 date_key 日维度汇总消耗积分与成功订单数
|
* 近 N 日(含)按 date_key 日维度汇总消耗积分与成功订单数
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,11 @@ public interface IAiChargeRefundOrderService {
|
||||||
*/
|
*/
|
||||||
List<AiChargeRefundOrder> selectAiChargeRefundOrderList(AiChargeRefundOrder aiChargeRefundOrder);
|
List<AiChargeRefundOrder> selectAiChargeRefundOrderList(AiChargeRefundOrder aiChargeRefundOrder);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 团队后台:仅当前登录部门,其它条件与 {@link #selectAiChargeRefundOrderList} 相同
|
||||||
|
*/
|
||||||
|
List<AiChargeRefundOrder> selectAiChargeRefundOrderListForCurrentSubteam(AiChargeRefundOrder aiChargeRefundOrder);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 新增团队(部门)充值退款订单
|
* 新增团队(部门)充值退款订单
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -39,11 +39,6 @@ public interface IAiVideoReportDataService {
|
||||||
/** 团队每日消耗分页列表(依赖 query 中的 pageNum/pageSize,Service 内写入 offset)。 */
|
/** 团队每日消耗分页列表(依赖 query 中的 pageNum/pageSize,Service 内写入 offset)。 */
|
||||||
List<AiVideoReportData> selectTeamDailyConsumeListPaged(GroupReportDataRequest query);
|
List<AiVideoReportData> selectTeamDailyConsumeListPaged(GroupReportDataRequest query);
|
||||||
|
|
||||||
/**
|
|
||||||
* 团队每日消耗(按部门 ID,团队后台)
|
|
||||||
*/
|
|
||||||
List<AiVideoReportData> selectTeamDailyConsumeByDeptId(String statDate, Long deptId);
|
|
||||||
|
|
||||||
void updateReportDataWhenInsertAiOrder(AiOrder order);
|
void updateReportDataWhenInsertAiOrder(AiOrder order);
|
||||||
|
|
||||||
void updateReportDataWhenInsertChargeRefundOrder(AiChargeRefundOrder order);
|
void updateReportDataWhenInsertChargeRefundOrder(AiChargeRefundOrder order);
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ import com.ruoyi.common.utils.DateUtils;
|
||||||
import com.ruoyi.common.utils.SecurityUtils;
|
import com.ruoyi.common.utils.SecurityUtils;
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
import com.ruoyi.common.utils.uuid.IdUtils;
|
import com.ruoyi.common.utils.uuid.IdUtils;
|
||||||
|
import com.ruoyi.system.service.subteam.ISubteamScopeService;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
|
@ -35,6 +36,9 @@ public class AiChargeRefundOrderServiceImpl implements IAiChargeRefundOrderServi
|
||||||
@Autowired
|
@Autowired
|
||||||
private IAiVideoReportDataService aiVideoReportDataService;
|
private IAiVideoReportDataService aiVideoReportDataService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ISubteamScopeService subteamScopeService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询团队(部门)充值退款订单
|
* 查询团队(部门)充值退款订单
|
||||||
*
|
*
|
||||||
|
|
@ -57,6 +61,14 @@ public class AiChargeRefundOrderServiceImpl implements IAiChargeRefundOrderServi
|
||||||
return aiChargeRefundOrderMapper.selectAiChargeRefundOrderList(aiChargeRefundOrder);
|
return aiChargeRefundOrderMapper.selectAiChargeRefundOrderList(aiChargeRefundOrder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<AiChargeRefundOrder> selectAiChargeRefundOrderListForCurrentSubteam(AiChargeRefundOrder aiChargeRefundOrder) {
|
||||||
|
Long deptId = subteamScopeService.currentTeamDeptId();
|
||||||
|
aiChargeRefundOrder.setDeptId(deptId);
|
||||||
|
aiChargeRefundOrder.setDeptName(null);
|
||||||
|
return selectAiChargeRefundOrderList(aiChargeRefundOrder);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 新增团队(部门)充值退款订单
|
* 新增团队(部门)充值退款订单
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -80,11 +80,6 @@ public class AiVideoReportDataServiceImpl implements IAiVideoReportDataService {
|
||||||
query.getStartDate(), query.getEndDate(), query.getDeptId(), offset, pageSize);
|
query.getStartDate(), query.getEndDate(), query.getDeptId(), offset, pageSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<AiVideoReportData> selectTeamDailyConsumeByDeptId(String statDate, Long deptId) {
|
|
||||||
return aiVideoReportDataMapper.selectTeamDailyConsumeByDeptId(statDate, deptId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateReportDataWhenInsertAiOrder(AiOrder order) {
|
public void updateReportDataWhenInsertAiOrder(AiOrder order) {
|
||||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH");
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH");
|
||||||
|
|
|
||||||
|
|
@ -2,17 +2,8 @@ package com.ruoyi.system.service.subteam;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import com.ruoyi.ai.domain.AiBalanceChangeRecord;
|
import com.ruoyi.ai.domain.AiBalanceChangeRecord;
|
||||||
import com.ruoyi.ai.domain.AiChargeRefundOrder;
|
|
||||||
import com.ruoyi.ai.domain.AiGroupBalanceChangeRecord;
|
|
||||||
import com.ruoyi.ai.domain.AiVideoReportData;
|
|
||||||
|
|
||||||
public interface ISubteamDataQueryService {
|
public interface ISubteamDataQueryService {
|
||||||
|
|
||||||
List<AiChargeRefundOrder> selectChargeRefundOrders(AiChargeRefundOrder query);
|
|
||||||
|
|
||||||
List<AiBalanceChangeRecord> selectUserBalanceRecords(AiBalanceChangeRecord query);
|
List<AiBalanceChangeRecord> selectUserBalanceRecords(AiBalanceChangeRecord query);
|
||||||
|
|
||||||
List<AiGroupBalanceChangeRecord> selectGroupBalanceRecords(AiGroupBalanceChangeRecord query);
|
|
||||||
|
|
||||||
List<AiVideoReportData> selectTeamDailyConsume(String statDate);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,5 @@ public interface ISubteamScopeService {
|
||||||
|
|
||||||
void assertChargeRefundBelongsToTeam(Long orderPkId);
|
void assertChargeRefundBelongsToTeam(Long orderPkId);
|
||||||
|
|
||||||
void assertGroupBalanceRecordBelongsToTeam(Long recordId);
|
|
||||||
|
|
||||||
void assertAiBalanceRecordVisible(Long recordId, Long teamDeptId);
|
void assertAiBalanceRecordVisible(Long recordId, Long teamDeptId);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,14 +4,7 @@ import java.util.List;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import com.ruoyi.ai.domain.AiBalanceChangeRecord;
|
import com.ruoyi.ai.domain.AiBalanceChangeRecord;
|
||||||
import com.ruoyi.ai.domain.AiChargeRefundOrder;
|
|
||||||
import com.ruoyi.ai.domain.AiGroupBalanceChangeRecord;
|
|
||||||
import com.ruoyi.ai.domain.AiVideoReportData;
|
|
||||||
import com.ruoyi.ai.mapper.AiBalanceChangeRecordMapper;
|
import com.ruoyi.ai.mapper.AiBalanceChangeRecordMapper;
|
||||||
import com.ruoyi.ai.mapper.AiChargeRefundOrderMapper;
|
|
||||||
import com.ruoyi.ai.mapper.AiGroupBalanceChangeRecordMapper;
|
|
||||||
import com.ruoyi.ai.service.IAiVideoReportDataService;
|
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
|
||||||
import com.ruoyi.system.service.subteam.ISubteamDataQueryService;
|
import com.ruoyi.system.service.subteam.ISubteamDataQueryService;
|
||||||
import com.ruoyi.system.service.subteam.ISubteamScopeService;
|
import com.ruoyi.system.service.subteam.ISubteamScopeService;
|
||||||
|
|
||||||
|
|
@ -21,44 +14,12 @@ public class SubteamDataQueryServiceImpl implements ISubteamDataQueryService {
|
||||||
@Autowired
|
@Autowired
|
||||||
private ISubteamScopeService subteamScopeService;
|
private ISubteamScopeService subteamScopeService;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private AiChargeRefundOrderMapper aiChargeRefundOrderMapper;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private AiBalanceChangeRecordMapper aiBalanceChangeRecordMapper;
|
private AiBalanceChangeRecordMapper aiBalanceChangeRecordMapper;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private AiGroupBalanceChangeRecordMapper aiGroupBalanceChangeRecordMapper;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private IAiVideoReportDataService aiVideoReportDataService;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<AiChargeRefundOrder> selectChargeRefundOrders(AiChargeRefundOrder query) {
|
|
||||||
Long deptId = subteamScopeService.currentTeamDeptId();
|
|
||||||
query.setDeptId(deptId);
|
|
||||||
return aiChargeRefundOrderMapper.selectAiChargeRefundOrderList(query);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<AiBalanceChangeRecord> selectUserBalanceRecords(AiBalanceChangeRecord query) {
|
public List<AiBalanceChangeRecord> selectUserBalanceRecords(AiBalanceChangeRecord query) {
|
||||||
Long deptId = subteamScopeService.currentTeamDeptId();
|
Long deptId = subteamScopeService.currentTeamDeptId();
|
||||||
return aiBalanceChangeRecordMapper.selectAiBalanceChangeRecordListByAiUserDept(query, deptId);
|
return aiBalanceChangeRecordMapper.selectAiBalanceChangeRecordListByAiUserDept(query, deptId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<AiGroupBalanceChangeRecord> selectGroupBalanceRecords(AiGroupBalanceChangeRecord query) {
|
|
||||||
Long deptId = subteamScopeService.currentTeamDeptId();
|
|
||||||
query.setDeptId(deptId);
|
|
||||||
return aiGroupBalanceChangeRecordMapper.selectAiGroupBalanceChangeRecordList(query);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<AiVideoReportData> selectTeamDailyConsume(String statDate) {
|
|
||||||
if (StringUtils.isEmpty(statDate)) {
|
|
||||||
return java.util.Collections.emptyList();
|
|
||||||
}
|
|
||||||
Long deptId = subteamScopeService.currentTeamDeptId();
|
|
||||||
return aiVideoReportDataService.selectTeamDailyConsumeByDeptId(statDate, deptId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,9 @@ package com.ruoyi.system.service.subteam.impl;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import com.ruoyi.ai.domain.AiChargeRefundOrder;
|
import com.ruoyi.ai.domain.AiChargeRefundOrder;
|
||||||
import com.ruoyi.ai.domain.AiGroupBalanceChangeRecord;
|
|
||||||
import com.ruoyi.ai.domain.AiOrder;
|
import com.ruoyi.ai.domain.AiOrder;
|
||||||
import com.ruoyi.ai.domain.AiBalanceChangeRecord;
|
import com.ruoyi.ai.domain.AiBalanceChangeRecord;
|
||||||
import com.ruoyi.ai.mapper.AiChargeRefundOrderMapper;
|
import com.ruoyi.ai.mapper.AiChargeRefundOrderMapper;
|
||||||
import com.ruoyi.ai.mapper.AiGroupBalanceChangeRecordMapper;
|
|
||||||
import com.ruoyi.ai.mapper.AiOrderMapper;
|
import com.ruoyi.ai.mapper.AiOrderMapper;
|
||||||
import com.ruoyi.ai.mapper.AiBalanceChangeRecordMapper;
|
import com.ruoyi.ai.mapper.AiBalanceChangeRecordMapper;
|
||||||
import com.ruoyi.common.core.domain.entity.AiUser;
|
import com.ruoyi.common.core.domain.entity.AiUser;
|
||||||
|
|
@ -30,9 +28,6 @@ public class SubteamScopeServiceImpl implements ISubteamScopeService {
|
||||||
@Autowired
|
@Autowired
|
||||||
private AiChargeRefundOrderMapper aiChargeRefundOrderMapper;
|
private AiChargeRefundOrderMapper aiChargeRefundOrderMapper;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private AiGroupBalanceChangeRecordMapper aiGroupBalanceChangeRecordMapper;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private AiBalanceChangeRecordMapper aiBalanceChangeRecordMapper;
|
private AiBalanceChangeRecordMapper aiBalanceChangeRecordMapper;
|
||||||
|
|
||||||
|
|
@ -84,15 +79,6 @@ public class SubteamScopeServiceImpl implements ISubteamScopeService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void assertGroupBalanceRecordBelongsToTeam(Long recordId) {
|
|
||||||
Long teamDeptId = currentTeamDeptId();
|
|
||||||
AiGroupBalanceChangeRecord r = aiGroupBalanceChangeRecordMapper.selectById(recordId);
|
|
||||||
if (r == null || r.getDeptId() == null || !teamDeptId.equals(r.getDeptId())) {
|
|
||||||
throw new ServiceException("无权查看该记录");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void assertAiBalanceRecordVisible(Long recordId, Long teamDeptId) {
|
public void assertAiBalanceRecordVisible(Long recordId, Long teamDeptId) {
|
||||||
AiBalanceChangeRecord r = aiBalanceChangeRecordMapper.selectById(recordId);
|
AiBalanceChangeRecord r = aiBalanceChangeRecordMapper.selectById(recordId);
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
<if test="money != null "> and o.money = #{money}</if>
|
<if test="money != null "> and o.money = #{money}</if>
|
||||||
<if test="amount != null "> and o.amount = #{amount}</if>
|
<if test="amount != null "> and o.amount = #{amount}</if>
|
||||||
<if test="status != null "> and o.status = #{status}</if>
|
<if test="status != null "> and o.status = #{status}</if>
|
||||||
|
<if test="params != null and params.beginCreateTime != null and params.beginCreateTime != ''">
|
||||||
|
and date_format(o.create_time,'%Y%m%d') >= date_format(#{params.beginCreateTime},'%Y%m%d')
|
||||||
|
</if>
|
||||||
|
<if test="params != null and params.endCreateTime != null and params.endCreateTime != ''">
|
||||||
|
and date_format(o.create_time,'%Y%m%d') <= date_format(#{params.endCreateTime},'%Y%m%d')
|
||||||
|
</if>
|
||||||
</where>
|
</where>
|
||||||
order by o.id desc
|
order by o.id desc
|
||||||
</select>
|
</select>
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
<select id="selectAiGroupBalanceChangeRecordList" parameterType="AiGroupBalanceChangeRecord" resultMap="AiGroupBalanceChangeRecordResult">
|
<select id="selectAiGroupBalanceChangeRecordList" parameterType="AiGroupBalanceChangeRecord" resultMap="AiGroupBalanceChangeRecordResult">
|
||||||
<include refid="selectAiGroupBalanceChangeRecordVo"/>
|
<include refid="selectAiGroupBalanceChangeRecordVo"/>
|
||||||
<where>
|
<where>
|
||||||
<if test="relationOrderNo != null and relationOrderNo != ''"> and r.relation_order_no = #{relationOrderNo}</if>
|
<if test="relationOrderNo != null and relationOrderNo != ''"> and r.relation_order_no like concat('%', #{relationOrderNo}, '%')</if>
|
||||||
<if test="deptId != null "> and r.dept_id = #{deptId}</if>
|
<if test="deptId != null "> and r.dept_id = #{deptId}</if>
|
||||||
<if test="deptName != null and deptName != ''"> and d.dept_name like concat('%', #{deptName}, '%')</if>
|
<if test="deptName != null and deptName != ''"> and d.dept_name like concat('%', #{deptName}, '%')</if>
|
||||||
<if test="type != null "> and r.type = #{type}</if>
|
<if test="type != null "> and r.type = #{type}</if>
|
||||||
|
|
|
||||||
|
|
@ -105,22 +105,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
LIMIT #{limit} OFFSET #{offset}
|
LIMIT #{limit} OFFSET #{offset}
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select id="selectTeamDailyConsumeByDeptId" resultMap="AiVideoReportDataResult">
|
|
||||||
select substr(vrd.date_key, 1, 10) as date_key,
|
|
||||||
vrd.dept_id,
|
|
||||||
d.dept_name,
|
|
||||||
sum(vrd.recharge_score) as recharge_score,
|
|
||||||
sum(vrd.score) as score,
|
|
||||||
sum(vrd.order_count) as order_count,
|
|
||||||
sum(vrd.use_tokens) as use_tokens
|
|
||||||
from ai_video_report_data vrd
|
|
||||||
left join sys_dept d on d.dept_id = vrd.dept_id
|
|
||||||
where vrd.date_key like concat(#{statDate}, '%')
|
|
||||||
and vrd.dept_id = #{deptId}
|
|
||||||
group by substr(vrd.date_key, 1, 10), vrd.dept_id, d.dept_name
|
|
||||||
order by substr(vrd.date_key, 1, 10) desc, vrd.dept_id desc
|
|
||||||
</select>
|
|
||||||
|
|
||||||
<select id="selectDeptVideoMetricsBetween" resultType="com.ruoyi.system.domain.subteam.SubteamVideoMetrics">
|
<select id="selectDeptVideoMetricsBetween" resultType="com.ruoyi.system.domain.subteam.SubteamVideoMetrics">
|
||||||
select ifnull(sum(vrd.score), 0) as consumeScore, ifnull(sum(vrd.order_count), 0) as orderCount
|
select ifnull(sum(vrd.score), 0) as consumeScore, ifnull(sum(vrd.order_count), 0) as orderCount
|
||||||
from ai_video_report_data vrd where vrd.dept_id = #{deptId}
|
from ai_video_report_data vrd where vrd.dept_id = #{deptId}
|
||||||
|
|
|
||||||
|
|
@ -81,6 +81,8 @@ values('团队充值记录', @subteamRoot, '4', 'charge-order', 'subteam/chargeO
|
||||||
SELECT @m3 := LAST_INSERT_ID();
|
SELECT @m3 := LAST_INSERT_ID();
|
||||||
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
|
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
|
||||||
values('充值记录查询', @m3, '1', '#', '', 1, 0, 'F', '0', '0', 'subteam:charge:query', '#', 'admin', sysdate(), '', null, '');
|
values('充值记录查询', @m3, '1', '#', '', 1, 0, 'F', '0', '0', 'subteam:charge:query', '#', 'admin', sysdate(), '', null, '');
|
||||||
|
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
|
||||||
|
values('充值记录导出', @m3, '2', '#', '', 1, 0, 'F', '0', '0', 'subteam:charge:export', '#', 'admin', sysdate(), '', null, '');
|
||||||
|
|
||||||
-- 用户余额变动(门户 ai_user)
|
-- 用户余额变动(门户 ai_user)
|
||||||
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
|
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
|
||||||
|
|
@ -201,3 +203,24 @@ ALTER TABLE `byteai`.`ai_dept_ark_config`
|
||||||
|
|
||||||
ALTER TABLE `byteai`.`ai_video_report_data`
|
ALTER TABLE `byteai`.`ai_video_report_data`
|
||||||
ADD COLUMN `recharge_score` decimal(14, 2) NULL AFTER `user_id`;
|
ADD COLUMN `recharge_score` decimal(14, 2) NULL AFTER `user_id`;
|
||||||
|
|
||||||
|
-- 团队端「团队积分变动」导出权限(组件 ai/groupchargeorder/index,接口 POST /ai/group/chargeorder/record/export)
|
||||||
|
INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
|
||||||
|
SELECT '团队积分变动导出', m.menu_id, 6, '#', '', 1, 0, 'F', '0', '0', 'ai:groupChargeOrder:record:export', '#', 'admin', sysdate(), '', null, '与 ai:groupChargeOrder:list 同页,单独控制导出'
|
||||||
|
FROM sys_menu m
|
||||||
|
WHERE m.perms = 'ai:groupChargeOrder:list' AND m.menu_type = 'C'
|
||||||
|
LIMIT 1;
|
||||||
|
|
||||||
|
-- 团队后台「团队余额变动」导出(组件 subteam/groupBalance/index,接口 POST /subteam/group-balance/export)
|
||||||
|
INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
|
||||||
|
SELECT '团队余额变动导出', m.menu_id, 2, '#', '', 1, 0, 'F', '0', '0', 'subteam:groupBalance:export', '#', 'admin', sysdate(), '', null, '与 subteam:groupBalance:list 同页'
|
||||||
|
FROM sys_menu m
|
||||||
|
WHERE m.perms = 'subteam:groupBalance:list' AND m.menu_type = 'C'
|
||||||
|
LIMIT 1;
|
||||||
|
|
||||||
|
-- 团队后台「团队消耗统计」导出(组件 subteam/consumeStat/index,接口 POST /subteam/consume-stat/export)
|
||||||
|
INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
|
||||||
|
SELECT '消耗统计导出', m.menu_id, 2, '#', '', 1, 0, 'F', '0', '0', 'subteam:consume:export', '#', 'admin', sysdate(), '', null, '与 subteam:consume:list 同页'
|
||||||
|
FROM sys_menu m
|
||||||
|
WHERE m.perms = 'subteam:consume:list' AND m.menu_type = 'C' AND m.path = 'consume-stat'
|
||||||
|
LIMIT 1;
|
||||||
Loading…
Reference in New Issue