123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822 |
- <template>
- <a-card :bordered="false" :body-style="{ 'padding-bottom': '20px' }" class="mb-2">
- <a-form ref="searchFormRef" name="advanced_search" :model="searchFormState" class="ant-advanced-search-form">
- <a-row :gutter="24">
- <a-col :span="6">
- <a-form-item label="门店" name="orgId">
- <a-tree-select
- v-model:value="searchFormState.orgId"
- show-search
- style="width: 100%"
- :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
- placeholder="请选择门店"
- allow-clear
- multiple
- tree-default-expand-all
- :tree-data="treeData"
- :field-names="{
- children: 'children',
- label: 'name',
- value: 'id'
- }"
- selectable="false"
- />
- </a-form-item>
- </a-col>
- <a-col :span="6">
- <a-form-item label="日期段" name="times">
- <a-range-picker
- style="width: 100%;"
- v-model:value="searchFormState.times"
- format="YYYY-MM-DD"
- :placeholder="['开始时间', '结束时间']"
- @change="onRangeChange"
- />
- </a-form-item>
- </a-col>
- <a-col :span="6">
- <a-button type="primary" html-type="submit" @click="refresh()">查询</a-button>
- <a-button style="margin: 0 8px" @click="reset">重置</a-button>
- <a-button @click="exportTotal">
- <template #icon>
- <export-outlined/>
- </template>
- 导出
- </a-button>
- </a-col>
- </a-row>
- </a-form>
- </a-card>
- <a-row>
- <a-col :span="8" style="margin-bottom: 10px;">
- <a-card style="height: 180px">
- <a-statistic title="消费金额" :value="consumerCount"/>
- <a-statistic title="订单数" :value="consumerOrderCount"/>
- </a-card>
- </a-col>
- <a-col :span="8" style="margin-bottom: 10px; margin-left: 20px">
- <a-card style="height: 180px">
- <a-statistic title="注册会员数" :value="userCount"/>
- <!-- <a-statistic title="订单数" :value="rechargeOrderCount"/>-->
- </a-card>
- </a-col>
- <a-col :span="7" style="margin-bottom: 10px; margin-left: 20px;">
- <a-card style="height: 180px">
- <a-statistic title="账户余额" :value="accountBalance"/>
- <a-statistic title="代金券余额" :value="voucherBalance"/>
- </a-card>
- </a-col>
- </a-row>
- <a-card :bordered="false">
- <div style="display:flex;justify-content:space-between" id="totalDiv">
- <span id="totalSpan">
- <left-outlined :style="{fontSize:'13px',color:'#C9C9C9',cursor:'pointer'}" @click="prePage" v-show="leftFlag"/>
- </span>
- <span>
- <right-outlined style="width:1.5em;height:1.5em;color:#C9C9C9;cursor:pointer" @click="nextPage" v-show="rightFlag"/>
- </span>
- </div>
- </a-card>
- <!-- <a-card :bordered="false" :body-style="{ 'padding-bottom': '20px' }" class="mb-2">
- <div id="main" style="height: 340px"></div>
- </a-card>-->
- <a-card :bordered="false" :body-style="{ 'padding-bottom': '20px' }" class="mb-2">
- <div id="main2" style="height: 340px"></div>
- </a-card>
- <a-card :bordered="false" :body-style="{ 'padding-bottom': '20px' }" class="mb-2">
- <a-table
- ref="table"
- :columns="columns4"
- :data-source = "data4"
- bordered
- :row-key="(record) => record.id"
- >
- </a-table>
- </a-card>
- <a-card :bordered="false">
- <a-tabs v-model:activeKey="activeKey" @change="clickTab(value)">
- <a-tab-pane key="1">
- <template #tab>
- <span>
- <red-envelope-outlined />
- 消费列表
- </span>
- </template>
- <div id="printForm1">
- <a-table
- ref="table"
- :columns="columns1"
- :data-source = "data1"
- bordered
- :row-key="(record) => record.id"
- >
- <template #bodyCell="{ column, record }">
- <template v-if="column.dataIndex === 'consumptionOperate'">
- <a-tag
- :color="
- record.consumptionOperate === '1'
- ? 'orange'
- : record.consumptionOperate === '2'
- ? 'green'
- : record.consumptionOperate === '3'
- ? 'cyan'
- : 'purple'
- "
- >
- {{ $TOOL.dictTypeData('consumption_operate', record.consumptionOperate) }}
- </a-tag>
- </template>
- </template>
- </a-table>
- </div>
- </a-tab-pane>
- <a-tab-pane key="2">
- <template #tab>
- <span>
- <HddOutlined />
- 优惠券列表
- </span>
- </template>
- <div id="printForm2">
- <a-table
- ref="table"
- :columns="columns2"
- :data-source = "data2"
- bordered
- :row-key="(record) => record.id"
- >
- <template #bodyCell="{ column, record }">
- <template v-if="column.dataIndex === 'couponStatus'">
- <a-tag
- :color="
- record.couponStatus === '0'
- ? '#87d068'
- : record.couponStatus === '1'
- ? '#f50'
- : '#f50'
- "
- >
- {{ $TOOL.dictTypeData('is_destroy', record.couponStatus) }}
- </a-tag>
- </template>
- </template>
- </a-table>
- </div>
- </a-tab-pane>
- <a-tab-pane key="3">
- <template #tab>
- <span>
- <ScheduleOutlined />
- 会员列表
- </span>
- </template>
- <div id="printForm3">
- <a-table
- ref="table"
- :columns="columns3"
- :data-source = "data3"
- bordered
- :row-key="(record) => record.id"
- >
- </a-table>
- </div>
- </a-tab-pane>
- </a-tabs>
- </a-card>
- </template>
- <script setup name="customerinfo">
- import bizOrgApi from '@/api/biz/bizOrgApi'
- import downloadUtil from '@/utils/downloadUtil'
- import consumptionRecordApi from '@/api/biz/consumptionRecordApi'
- import bizCouponRecordApi from '@/api/biz/bizCouponRecordApi'
- import bizUserApi from '@/api/biz/bizUserApi'
- import { onMounted } from 'vue'
- import orgApi from '@/api/biz/bizOrgApi'
- import * as echarts from 'echarts'
- //消费
- const consumerCount = ref(0)
- const consumerOrderCount = ref(0)
- //充值统计数量
- const rechargeCount = ref(0)
- const rechargeOrderCount = ref(0)
- //会员
- const userCount = ref(0)
- //账户余额&代金券余额
- const accountBalance = ref(0)
- const voucherBalance = ref(0)
- const treeData = ref([])
- const activeKey = ref('1');
- const searchFormRef = ref()
- let searchFormState = reactive({})
- const data1 = ref([])
- const data2 = ref([])
- const data3 = ref([])
- const data4 = ref([])
- const data5 = ref([])
- const dayTime = ref()
- const zhibiao = ref()
- const fuhe = ref()
- const typeTitle = ref()
- //三条数据一页
- const echartsPage = ref(7)
- //当前显示页数
- const currentPage = ref(1)
- // 共有多少页
- const totalPage = ref(0)
- const leftFlag = ref(false)
- const rightFlag = ref(false)
- onMounted(() => {
- //金额汇总
- loadData1();
- loadData3();
- clickTab()
- // 获取机构树并加入顶级
- bizOrgApi.orgTreeSelector().then((res) => {
- treeData.value = res
- })
- //折线图
- customer();
- //各个门店消费统计
- loadData4()
- })
- const onRangeChange = (value, dateString) => {
- console.log('Formatted Selected Time: ', dateString);
- searchFormState.startTime = dateString[0]
- searchFormState.endTime = dateString[1]
- delete searchFormState.times
- };
- const table = ref()
- const formRef = ref()
- const toolConfig = { refresh: true, height: true, columnSetting: true, striped: false }
- const columns1 = [
- {
- title: '会员姓名',
- dataIndex: 'userName',
- align: 'center',
- },
- {
- title: '会员手机号',
- dataIndex: 'phone',
- align: 'center',
- },
- {
- title: '消费操作',
- dataIndex: 'consumptionOperate',
- align: 'center'
- },
- {
- title: '消费金额',
- dataIndex: 'consumptionMoney',
- align: 'center'
- },
- {
- title: '账户余额',
- dataIndex: 'newAccountBalance',
- align: 'center'
- },
- {
- title: '代金券余额',
- dataIndex: 'newVoucherBalance',
- align: 'center'
- },
- {
- title: '消费时间',
- dataIndex: 'consumptionTime',
- align: 'center'
- },
- {
- title: '会员编码',
- dataIndex: 'userCode',
- align: 'center'
- },
- {
- title: '消费门店',
- dataIndex: 'orgName',
- align: 'center'
- },
- ]
- const columns2 = [
- {
- title: '优惠券编码',
- dataIndex: 'couponNo',
- align: 'center',
- },
- {
- title: '优惠券生成时间',
- dataIndex: 'time',
- align: 'center',
- },
- {
- title: '是否核销',
- dataIndex: 'couponStatus',
- align: 'center'
- },
- {
- title: '有效期开始时间',
- dataIndex: 'startTime',
- align: 'center'
- },
- {
- title: '有效期截止时间',
- dataIndex: 'endTime',
- align: 'center'
- },
- {
- title: '核销人',
- dataIndex: 'destroyUserName',
- align: 'center'
- },
- {
- title: '核销时间',
- dataIndex: 'destroyTime',
- align: 'center'
- },
- {
- title: '核销门店',
- dataIndex: 'destroyOrgName',
- align: 'center'
- },
- ]
- const columns3 = [
- {
- title: '会员编码',
- dataIndex: 'userReferralCode',
- align: 'center',
- },
- {
- title: '手机号',
- dataIndex: 'phone',
- align: 'center',
- },
- {
- title: '姓名',
- dataIndex: 'name',
- align: 'center',
- },
- {
- title: '账户余额',
- dataIndex: 'accountBalance',
- align: 'center',
- },
- {
- title: '代金券余额',
- dataIndex: 'voucherBalance',
- align: 'center',
- },
- {
- title: '注册时间',
- dataIndex: 'createTime',
- align: 'center',
- },
- /*{
- title: '门店',
- dataIndex: 'orgName',
- align: 'center',
- },*/
- ]
- const columns4 = [
- {
- title: '门店名称',
- dataIndex: 'name',
- align: 'center'
- },
- {
- title: '门店编码',
- dataIndex: 'code',
- align: 'center'
- },
- {
- title: '消费',
- children: [
- {
- title: '订单数',
- dataIndex: 'orderCount',
- align: 'center',
- },
- {
- title: '账户消费金额',
- dataIndex: 'accountMoney',
- align: 'center',
- },
- {
- title: '代金券消费金额',
- dataIndex: 'voucherMoney',
- align: 'center',
- },
- ]
- },
- /*{
- title: '注册会员数',
- dataIndex: 'userCount',
- align: 'center'
- },*/
- ]
- const selectedRowKeys = ref([])
- // 列表选择配置
- const options = {
- // columns数字类型字段加入 needTotal: true 可以勾选自动算账
- alert: {
- show: true,
- clear: () => {
- selectedRowKeys.value = ref([])
- }
- },
- rowSelection: {
- onChange: (selectedRowKey, selectedRows) => {
- selectedRowKeys.value = selectedRowKey
- }
- }
- }
- const totalMoney = ref(0)
- //各个门店消费记录
- const loadData4 = () => {
- const orgId = ref('')
- if(searchFormState.orgId == null || searchFormState.orgId== '' || searchFormState.orgId== 'undefined' ){
- }else{
- for(let i = 0;i<searchFormState.orgId.length;i++){
- orgId.value = orgId.value + searchFormState.orgId[i]+","
- }
- orgId.value = orgId.value.slice(0,orgId.value.length-1)
- }
- const param = {
- "orgId":orgId.value,
- "consumptionTimeBegin":searchFormState.startTime,
- "consumptionTimeEnd":searchFormState.endTime
- }
- consumptionRecordApi.queryEachStore(param).then((data)=>{
- data4.value = data.dataList
- })
- }
- //导出
- const exportTotal = () => {
- const orgId = ref('')
- if(searchFormState.orgId == null || searchFormState.orgId== '' || searchFormState.orgId== 'undefined' ){
- }else{
- for(let i = 0;i<searchFormState.orgId.length;i++){
- orgId.value = orgId.value + searchFormState.orgId[i]+","
- }
- orgId.value = orgId.value.slice(0,orgId.value.length-1)
- }
- const param = {
- "orgId":orgId.value,
- "consumptionTimeBegin":searchFormState.startTime,
- "consumptionTimeEnd":searchFormState.endTime
- }
- consumptionRecordApi.exportRecord(param).then((res)=>{
- downloadUtil.resultDownload(res)
- })
- }
- //会员折线图
- const customer = () => {
- const orgId = ref('')
- if(searchFormState.orgId == null || searchFormState.orgId== '' || searchFormState.orgId== 'undefined' ){
- }else{
- for(let i = 0;i<searchFormState.orgId.length;i++){
- orgId.value = orgId.value + searchFormState.orgId[i]+","
- }
- orgId.value = orgId.value.slice(0,orgId.value.length-1)
- }
- const param = {
- "orgId":orgId.value,
- "customerName":searchFormState.customerName,
- "startTime":searchFormState.startTime,
- "endTime":searchFormState.endTime
- }
- consumptionRecordApi.queryConsumptionChart(param).then((res)=>{
- const xAxis = res.dateTime
- let series = [
- {
- name: '消费金额',
- type: 'line',
- //stack: '总量',
- showSymbol: false,
- itemStyle: {
- normal: {
- color: '#00FF00', //折线点自定义
- lineStyle: {
- color: '#00FF00'
- }
- }
- },
- data: res.consumptionMoney
- },
- {
- name: '订单数',
- type: 'line',
- //stack: '总量',
- showSymbol: false,
- data: res.consumptionCount
- },
- {
- name: '会员',
- type: 'line',
- //stack: '总量',
- showSymbol: false,
- itemStyle: {
- normal: {
- color: '#FAD337', //折线点自定义
- lineStyle: {
- color: '#FAD337'
- }
- }
- },
- data: res.userCount
- },
- ]
- drow("main2",xAxis, series)
- })
- }
- const drow = (id, xAxis, series) => {
- let myChart = echarts.init(document.getElementById(id))
- let option = {
- color: ['#1890FF', '#52C41A'],
- title: {
- //text: '会话量',
- },
- tooltip: {
- trigger: 'axis',
- },
- grid: {
- left: '40px',
- right: '40px',
- top: '50px',
- bottom: '30px'
- },
- legend: {
- itemWidth: 20, // 图例图形宽度
- itemHeight: 4,
- icon: 'roundRect',
- },
- xAxis: {
- type: 'category',
- boundaryGap: false, //x轴两边不留空白
- axisLabel: {
- color: 'rgba(0, 0, 0, 0.65)',
- },
- axisLine: {
- lineStyle: {
- color: '#D9D9D9',
- },
- },
- axisTick: {
- lineStyle: {
- color: '#D9D9D9',
- },
- },
- data: xAxis,
- },
- yAxis: {
- axisLine: {
- show: false,
- lineStyle: {
- color: 'rgba(0, 0, 0, 0.65)',
- },
- },
- splitLine: {
- lineStyle: {
- color: ['#E8E8E8'],
- type: 'dashed',
- },
- },
- axisLabel: {
- color: 'rgba(0, 0, 0, 0.65)',
- },
- axisTick: {
- show: false,
- lineStyle: { color: 'rgb(150,150,150)' }, //y轴坐标刻度颜色(与axisLabel.textStyle是相同的效果)
- },
- type: 'value',
- },
- series: series
- }
- myChart.setOption(option)
- }
- //消费金额值统计
- const loadData1 = () => {
- const orgId = ref('')
- if(searchFormState.orgId == null || searchFormState.orgId== '' || searchFormState.orgId== 'undefined' ){
- }else{
- for(let i = 0;i<searchFormState.orgId.length;i++){
- orgId.value = orgId.value + searchFormState.orgId[i]+","
- }
- orgId.value = orgId.value.slice(0,orgId.value.length-1)
- }
- const param = {
- "orgId":orgId.value,
- "consumptionTimeBegin":searchFormState.startTime,
- "consumptionTimeEnd":searchFormState.endTime
- }
- consumptionRecordApi.queryRecordTotal(param).then((data) => {
- consumerCount.value = '¥ ' + data.orderMoney
- consumerOrderCount.value = data.orderCount
- })
- }
- //账户余额值统计
- const loadData3 = () => {
- const orgId = ref('')
- if(searchFormState.orgId == null || searchFormState.orgId== '' || searchFormState.orgId== 'undefined' ){
- }else{
- for(let i = 0;i<searchFormState.orgId.length;i++){
- orgId.value = orgId.value + searchFormState.orgId[i]+","
- }
- orgId.value = orgId.value.slice(0,orgId.value.length-1)
- }
- const param = {
- "orgId":orgId.value,
- "consumptionTimeBegin":searchFormState.startTime,
- "consumptionTimeEnd":searchFormState.endTime
- }
- consumptionRecordApi.queryBalanceTotal(param).then((data)=>{
- userCount.value = data.userCount
- accountBalance.value = data.accountBalance
- voucherBalance.value = data.voucherBalance
- })
- }
- //切换
- const clickTab = () => {
- consumptionPage()
- userPage()
- couponPage()
- }
- const consumptionPage = () =>{
- const orgId = ref('')
- if(searchFormState.orgId == null || searchFormState.orgId== '' || searchFormState.orgId== 'undefined' ){
- }else{
- for(let i = 0;i<searchFormState.orgId.length;i++){
- orgId.value = orgId.value + searchFormState.orgId[i]+","
- }
- orgId.value = orgId.value.slice(0,orgId.value.length-1)
- }
- const param = {
- "orgId":orgId.value,
- "consumptionTimeBegin":searchFormState.startTime,
- "consumptionTimeEnd":searchFormState.endTime,
- "consumptionOperate":'3,4'
- }
- consumptionRecordApi.consumptionRecordPage(param).then((data) => {
- data1.value = data.records
- })
- }
- //会员列表
- const userPage = () => {
- const orgId = ref('')
- if(searchFormState.orgId == null || searchFormState.orgId== '' || searchFormState.orgId== 'undefined' ){
- }else{
- for(let i = 0;i<searchFormState.orgId.length;i++){
- orgId.value = orgId.value + searchFormState.orgId[i]+","
- }
- orgId.value = orgId.value.slice(0,orgId.value.length-1)
- }
- const param = {
- "orgId":orgId.value,
- "beginTime":searchFormState.startTime,
- "endTime":searchFormState.endTime
- }
- bizUserApi.memberPage(param).then((res) => {
- data3.value = res.records
- })
- }
- //优惠券列表
- const couponPage = () => {
- const orgId = ref('')
- if(searchFormState.orgId == null || searchFormState.orgId== '' || searchFormState.orgId== 'undefined' ){
- }else{
- for(let i = 0;i<searchFormState.orgId.length;i++){
- orgId.value = orgId.value + searchFormState.orgId[i]+","
- }
- orgId.value = orgId.value.slice(0,orgId.value.length-1)
- }
- const param = {
- "orgId":orgId.value,
- "beginTime":searchFormState.startTime,
- "endTime":searchFormState.endTime
- }
- bizCouponRecordApi.bizCouponRecordPage(param).then((data) => {
- data2.value = data.records
- })
- }
- //查询
- const refresh = () => {
- loadData1();
- loadData3();
- clickTab()
- loadData4()
- }
- //导出
- const exportReport = () => {
- if(activeKey.value == '1'){
- searchFormState.queryFlag = '1'
- console.log("searchFormState.queryFlag:"+searchFormState.queryFlag)
- reportApi.exportReport(searchFormState).then((res) => {
- downloadUtil.resultDownload(res)
- })
- }
- }
- // 重置
- const reset = () => {
- searchFormRef.value.resetFields()
- searchFormState.times = []
- searchFormState.startTime = null
- searchFormState.endTime = null
- searchFormState.orgId = []
- }
- </script>
- <style lang="less" scoped>
- .ant-table-thead > tr > th {
- text-align: center;
- }
- .dashboard-analysis-iconGroup {
- i {
- margin-left: 16px;
- color: rgba(0, 0, 0, .45);
- cursor: pointer;
- transition: color .32s;
- color: black;
- height: 20px;
- }
- }
- #totalDiv #totalSpan{
- svg{
- width: 1.5em;
- height: 1.5em;
- }
- }
- </style>
|