From e890f87ea274436461aacca1391bb9717240f210 Mon Sep 17 00:00:00 2001 From: zxl <763096477@qq.com> Date: 星期四, 04 九月 2025 14:21:39 +0800 Subject: [PATCH] 商家端订单列表 --- manager/src/views/customer/index.vue | 358 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 335 insertions(+), 23 deletions(-) diff --git a/manager/src/views/customer/index.vue b/manager/src/views/customer/index.vue index 0076c30..b4dffa6 100644 --- a/manager/src/views/customer/index.vue +++ b/manager/src/views/customer/index.vue @@ -68,6 +68,7 @@ @on-selection-change="showSelect" > <template slot-scope="{ row, index }" slot="action"> + <Button type="info" size="small" style="margin-right: 5px" @click="openInfo(row)">鏌ョ湅璇︽儏</Button> <Button type="info" size="small" style="margin-right: 5px" @click="openEdit(row)">缂栬緫鏍囩</Button> <Button type="error" size="small" style="margin-right: 5px" @click="joinBlack(row)">鍔犲叆榛戝悕鍗�</Button> </template> @@ -87,6 +88,98 @@ ></Page> </Row> + <Modal + v-model="showCustomerInfo" + :title="modelTitle" + width="850" + :mask-closable="false" + > + + <!-- 涓诲唴瀹瑰尯 --> + <Tabs v-model="activeTab" @on-click="handleTabChange"> + <TabPane label="鍩虹璧勬枡" name="basic"> + <div class="customer-detail"> + <div class="avatar-section"> + <Avatar :src="customerInfo.face" size="large" /> + <div class="basic-info"> + <h3>{{ customerInfo.nickName || '寰俊鐢ㄦ埛' }}</h3> + <p>ID: {{ customerInfo.id }}</p> + <p>鐢ㄦ埛鍚�: {{ customerInfo.username }}</p> + </div> + </div> + + <Divider /> + <div class="detail-grid"> + <div class="detail-row"> + <span class="detail-label">鎬у埆锛�</span> + <span class="detail-value">{{ customerInfo.sex === 0 ? "濂�" : "鐢�"}}</span> + </div> + <div class="detail-row"> + <span class="detail-label">鍦板尯锛�</span> + <span class="detail-value">{{ customerInfo.region || '鏈缃�' }}</span> + </div> + <div class="detail-row"> + <span class="detail-label">鎵嬫満鍙凤細</span> + <span class="detail-value">{{ customerInfo.mobile || '鏈粦瀹�' }}</span> + </div> + <div class="detail-row"> + <span class="detail-label">褰撳墠绉垎锛�</span> + <span class="detail-value">{{ customerInfo.point }}</span> + </div> + <div class="detail-row"> + <span class="detail-label">鎬荤Н鍒嗭細</span> + <span class="detail-value">{{ customerInfo.totalPoint }}</span> + </div> + <div class="detail-row"> + <span class="detail-label">璐﹀彿鐘舵�侊細</span> + <span class="detail-value"> + <Tag :color="customerInfo.disabled ? 'error' : 'success'"> + {{ customerInfo.disabled ? '宸茬鐢�' : '姝e父' }} + </Tag> + </span> + </div> + <div class="detail-row"> + <span class="detail-label">鏄惁鍏宠仈搴楅摵锛�</span> + <span class="detail-value">{{ customerInfo.haveStore ? '鏄�' : '鍚�' }}</span> + </div> + <div class="detail-row"> + <span class="detail-label">娉ㄥ唽鏃堕棿锛�</span> + <span class="detail-value">{{ customerInfo.createTime }}</span> + </div> + <div class="detail-row"> + <span class="detail-label">鏈�鍚庣櫥褰曟椂闂达細</span> + <span class="detail-value">{{ customerInfo.lastLoginDate }}</span> + </div> + </div> + <div v-if="customerInfo.customerTagList && customerInfo.customerTagList.length > 0" class="tags-section"> + <h4>鐢ㄦ埛鏍囩</h4> + <div> + <Tag v-for="tag in customerInfo.customerTagList" :key="tag" color="default" style="margin-right: 8px;"> + {{ tag }} + </Tag> + </div> + </div> + </div> + </TabPane> + <TabPane label="瑙嗛娴忚鍘嗗彶" name="history"> + <watch-history + ref="watchHistoryRef" + :memberId="customerInfo.id" + key="history"/> + </TabPane> + <TabPane label="琛屼负鍒嗘瀽" name="actionAnalyse" > + <div class="chart-container"> + <div ref="chart" class="chart-content"></div> + </div> + </TabPane> + </Tabs> + + + <div slot="footer"> + <Button type="primary" @click="showCustomerInfo = false">鍏抽棴</Button> + </div> + </Modal> +<!-- 鏍囩寮圭獥--> <Modal v-model="showCustomerTag" :title="modelTitle" @@ -125,15 +218,49 @@ <script> import JsonExcel from "vue-json-excel"; -import {getCustomerList,addCustomerTag,saveCustomerTagById,getTagList,getStoreSelectOptions} from "@/api/customer"; +import {memberActionAnalyse,getCustomerList,addCustomerTag,saveCustomerTagById,getTagList,getStoreSelectOptions,getCustomerInfo} from "@/api/customer"; +import {addCustomerBlackByPC} from "@/api/customer-black.js" +import WatchHistory from "./WatchHistory.vue"; +import * as echarts from 'echarts'; export default { name:"customer", components:{ - "download-excel": JsonExcel, + WatchHistory, + "download-excel": JsonExcel + }, + data(){ return{ + myChart: null, + activeTab: 'basic', // 褰撳墠婵�娲荤殑鏍囩椤� + userId: '', // 褰撳墠鏌ョ湅鐨勭敤鎴稩D + + customerInfo: { + birthday: null, + blackId: null, + clientEnum: null, + createTime: "", + customerTagList: [], + disabled: true, + experience: null, + face: "", + gradeId: null, + haveStore: false, + id: "", + lastLoginDate: "", + mobile: null, + nickName: "", + openId: null, + point: 10, + region: "", + regionId: "", + sex: 0, + storeId: null, + totalPoint: 0, + username: "" + }, loading: false, // 琛ㄥ崟鍔犺浇鐘舵�� //鏌ヨ瀹㈡埛鍒楄〃璇锋眰鍙傛暟 searchForm:{ @@ -224,8 +351,9 @@ selectCount: 0, // 宸查�夋暟閲� selectList: [], // 宸查�夋暟鎹垪琛� + //瀹㈡埛璇︽儏瀵硅瘽妗�--- + showCustomerInfo:false, //瀹㈡埛鏍囩瀵硅瘽妗�--- - showCustomerTag:false, submitLoading:false, selectLoading:false, @@ -243,14 +371,113 @@ }, //鍟嗗涓嬫媺妗嗘暟鎹� selectOptions:[], - storeSelectLoading: false + storeSelectLoading: false, + + //榛戝悕鍗曡姹傚璞� + blackParam:{ + storeId:'', + userId:'', + }, + + } }, + mounted(){ this.init(); }, methods:{ + showLoading() { + if (this.myChart) { + this.myChart.showLoading({ + text: '鏁版嵁鍔犺浇涓�...', + color: '#1890ff', + textColor: '#333', + maskColor: 'rgba(255, 255, 255, 0.8)', + zlevel: 0, + fontSize: 14, + showSpinner: true, + spinnerRadius: 10, + lineWidth: 2, + fontWeight: 'normal' + }); + } + }, + + hideLoading() { + if (this.myChart) { + this.myChart.hideLoading(); + } + }, + getEmptyOption() { + return { + title: { + text: '鏆傛棤鏁版嵁', + left: 'center', + top: 'center', + textStyle: { + color: '#999', + fontWeight: 'normal', + fontSize: 16 + } + }, + series: [] + }; + }, + initEcharts(id){ + // 閿�姣佹棫瀹炰緥 + if (this.myChart) { + this.myChart.dispose(); + } + + this.myChart = echarts.init(this.$refs.chart); + this.showLoading() + memberActionAnalyse(id).then(res =>{ + let option; + this.hideLoading() + if (res.code === 200){ + const chartData = Object.entries(res.data).map(([name, value]) => ({ + value, + name + })); + console.log(chartData) + if (chartData.length ===0){ + option = this.getEmptyOption(); + }else { + option = { + title: { + text: '鐢ㄦ埛琛屼负鍒嗘瀽', + left: 'center' + }, + + tooltip: { + trigger: 'item' + }, + series: [{ + radius: ['40%', '70%'], + type: 'pie', + data: chartData, + emphasis: { + itemStyle: { + shadowBlur: 10, + shadowOffsetX: 0, + shadowColor: 'rgba(0, 0, 0, 0.5)' + } + } + }] + }; + } + + this.myChart.setOption(option); + } + }) + }, + // 鏍囩椤靛垏鎹㈠鐞� + handleTabChange(tabName) { + this.activeTab = tabName; + }, + // 鑾峰緱鍟嗗涓嬫媺妗嗘暟鎹� getStoreSelectOptions(){ this.storeSelectLoading = true; @@ -275,12 +502,12 @@ // 鑾峰緱瀹㈡埛鏍囩涓嬫媺妗嗘暟鎹� getCustomerTagSelectOptions(){ this.selectLoading = true; - getTagList().then(res =>{ - this.selectLoading = false; - if (res.code === 200){ - this.tagList = res.data; - } - }) + // getTagList().then(res =>{ + // this.selectLoading = false; + // if (res.code === 200){ + // this.tagList = res.data; + // } + // }) }, init(){ this.getCustomerList(); @@ -293,6 +520,47 @@ showSelect(){ this.selectList = e.map(d => d.id); this.selectCount = e.length; + }, + memberActionAnalyse(id){ + + }, + //鏌ョ湅璇︽儏 + openInfo(row){ + this.showCustomerInfo = true; + this.modelTitle = "鐢ㄦ埛璇︽儏" + + this.activeTab = "basic" + + getCustomerInfo(row.id).then(res =>{ + if(res.code === 200){ + this.customerInfo = { + birthday: res.data.birthday || null, + blackId: res.data.blackId || null, + clientEnum: res.data.clientEnum || null, + createTime: res.data.createTime || '', + customerTagList: res.data.customerTagList || [], + disabled: res.data.disabled || false, + experience: res.data.experience || null, + face: res.data.face || '榛樿澶村儚URL', + gradeId: res.data.gradeId || null, + haveStore: res.data.haveStore || false, + id: res.data.id || '', + lastLoginDate: res.data.lastLoginDate || '', + mobile: res.data.mobile || null, + nickName: res.data.nickName || '寰俊鐢ㄦ埛', + openId: res.data.openId || null, + point: res.data.point || 0, + region: res.data.region || '', + regionId: res.data.regionId || '', + sex: res.data.sex || 0, + storeId: res.data.storeId || null, + totalPoint: res.data.totalPoint || 0, + username: res.data.username || '' + }; + } + }) + + this.initEcharts(row.id); }, // 缂栬緫鏍囩 openEdit(row){ @@ -309,17 +577,6 @@ this.searchForm.pageSize = 10; this.getCustomerList(); }, - // 鏂板鎴栦慨鏀� - // saveOrUpdate() { - // this.$refs.form.validate(valid => { - // if (valid) { - // this.submitLoading = true - // // 鏂板 - // console.log(this.tagForm) - // - // } - // }); - // }, handleSelectChange(newVal){ console.log(newVal) this.getCustomerList() @@ -348,8 +605,14 @@ this.searchForm.pageSize = v; this.getCustomerList() }, - joinBlack(){ - + joinBlack(row){ + this.blackParam.storeId = row.storeId; + this.blackParam.userId = row.id; + addCustomerBlackByPC(this.blackParam).then(res =>{ + if (res.code === 200){ + this.$Message.success(res.msg); + } + }) }, @@ -358,6 +621,55 @@ </script> <style lang="scss" scoped> +.chart-container { + width: 100%; + height: 100%; /* 鏀逛负100%濉厖鐖跺鍣� */ + min-height: 400px; /* 鏈�灏忛珮搴︿繚闅� */ + display: flex; + justify-content: center; + align-items: center; + position: relative; + margin: auto; /* 鏂板 */ +} +.chart-content { + width: 400px; + height: 400px; + margin: 0 auto; +} +.customer-detail { + padding: 16px; +} + +.avatar-section { + display: flex; + align-items: center; + margin-bottom: 16px; +} + +.basic-info { + margin-left: 16px; +} + +.basic-info h3 { + margin: 0 0 8px 0; + font-size: 18px; +} + +.basic-info p { + margin: 6px 0; + color: #808695; + font-size: 14px; +} + +.tags-section { + margin-top: 16px; + padding-top: 16px; +} + +.tags-section h4 { + margin-bottom: 12px; + color: #17233d; +} .export { margin: 10px 20px 10px 0; } -- Gitblit v1.8.0