From f8fd46a27906504513787770500b6d7076c554fa Mon Sep 17 00:00:00 2001 From: wangfukang <15630117759@163.com> Date: Mon, 1 Jun 2026 14:39:10 +0800 Subject: [PATCH 1/3] 1 --- src/api/planet.js | 27 ++ src/views/app/business/luckey/luckey.vue | 303 ++++++++++++++++++++++- 2 files changed, 327 insertions(+), 3 deletions(-) diff --git a/src/api/planet.js b/src/api/planet.js index 6f6869c..75f8867 100644 --- a/src/api/planet.js +++ b/src/api/planet.js @@ -42,3 +42,30 @@ export const planetWinnerPage = (params) => getRequest(`${PREFIX}/winner/page`, // ---------------- 手动开奖(必须传 regionId,仅限本区域) ---------------- export const planetManualDraw = (poolId, regionId) => postRequest(`${PREFIX}/draw/manual`, { poolId, regionId }); + +// ---------------- 经营系统配置 ---------------- +export const planetTreePage = (params) => getRequest(`${PREFIX}/tree/page`, params); +export const planetTreeSave = (params) => postBodyRequest(`${PREFIX}/tree/save`, params); +export const planetTreeDelete = (id) => postRequest(`${PREFIX}/tree/delete`, { id }); + +export const planetWarehousePage = (params) => getRequest(`${PREFIX}/warehouse/page`, params); +export const planetWarehouseSave = (params) => postBodyRequest(`${PREFIX}/warehouse/save`, params); +export const planetWarehouseDelete = (id) => postRequest(`${PREFIX}/warehouse/delete`, { id }); + +export const planetTowerPage = (params) => getRequest(`${PREFIX}/tower/page`, params); +export const planetTowerSave = (params) => postBodyRequest(`${PREFIX}/tower/save`, params); +export const planetTowerDelete = (id) => postRequest(`${PREFIX}/tower/delete`, { id }); + +export const planetSearchPage = (params) => getRequest(`${PREFIX}/search/page`, params); +export const planetSearchSave = (params) => postBodyRequest(`${PREFIX}/search/save`, params); +export const planetSearchDelete = (id) => postRequest(`${PREFIX}/search/delete`, { id }); + +export const planetStaminaPage = (params) => getRequest(`${PREFIX}/stamina/page`, params); +export const planetStaminaSave = (params) => postBodyRequest(`${PREFIX}/stamina/save`, params); +export const planetStaminaDelete = (id) => postRequest(`${PREFIX}/stamina/delete`, { id }); + +export const planetLandmarkPage = (params) => getRequest(`${PREFIX}/landmark/page`, params); +export const planetLandmarkSave = (params) => postBodyRequest(`${PREFIX}/landmark/save`, params); +export const planetLandmarkDelete = (id) => postRequest(`${PREFIX}/landmark/delete`, { id }); + +export const planetEconomyPage = (params) => getRequest(`${PREFIX}/economy/page`, params); diff --git a/src/views/app/business/luckey/luckey.vue b/src/views/app/business/luckey/luckey.vue index 0675ae6..dda57a1 100644 --- a/src/views/app/business/luckey/luckey.vue +++ b/src/views/app/business/luckey/luckey.vue @@ -9,6 +9,9 @@ + + 现金奖池采用“主动投入”规则:用户投入星球券后即从余额扣除并回收,本期按投入券数加权开奖,投入越多中奖概率越高。 +
@@ -37,6 +40,63 @@
+ + + +
+ + + +
+ + +
+ + + +
+ + +
+ + + +
+ + +
+ + + +
+ + +
+ + + +
+ + +
+ + + +
+ +
+ + + +
+ @@ -227,6 +287,25 @@ + + + +
+ + + + + + + +
+
+ + +
+
@@ -238,7 +317,14 @@ planetBuffPage, planetBuffSave, planetBuffDelete, planetNewsPage, planetNewsSave, planetNewsDelete, planetRankPage, planetHuntPage, planetDrawPage, planetWinnerPage, - planetManualDraw + planetManualDraw, + planetTreePage, planetTreeSave, planetTreeDelete, + planetWarehousePage, planetWarehouseSave, planetWarehouseDelete, + planetTowerPage, planetTowerSave, planetTowerDelete, + planetSearchPage, planetSearchSave, planetSearchDelete, + planetStaminaPage, planetStaminaSave, planetStaminaDelete, + planetLandmarkPage, planetLandmarkSave, planetLandmarkDelete, + planetEconomyPage } from '@/api/planet'; export default { @@ -255,6 +341,13 @@ hunt: { loading: false, data: [], total: 0, pageNumber: 1, pageSize: 10 }, draw: { loading: false, data: [], total: 0, pageNumber: 1, pageSize: 10 }, winner: { loading: false, data: [], total: 0, pageNumber: 1, pageSize: 10 }, + tree: { loading: false, data: [], total: 0, pageNumber: 1, pageSize: 10 }, + warehouse: { loading: false, data: [], total: 0, pageNumber: 1, pageSize: 10 }, + tower: { loading: false, data: [], total: 0, pageNumber: 1, pageSize: 10 }, + search: { loading: false, data: [], total: 0, pageNumber: 1, pageSize: 10 }, + stamina: { loading: false, data: [], total: 0, pageNumber: 1, pageSize: 10 }, + landmark: { loading: false, data: [], total: 0, pageNumber: 1, pageSize: 10 }, + economy: { loading: false, data: [], total: 0, pageNumber: 1, pageSize: 10 }, // 弹窗 poolModal: false, poolForm: {}, @@ -268,10 +361,81 @@ buffModal: false, buffForm: {}, newsModal: false, - newsForm: {} + newsForm: {}, + operateModal: false, + operateType: '', + operateForm: {} } }, computed: { + operateTitle() { + const map = { tree: '券树周期', warehouse: '仓库等级', tower: '防御塔等级', search: '搜查规则', stamina: '体力道具', landmark: '校园地标' } + return (this.operateForm.id ? '编辑' : '新增') + (map[this.operateType] || '经营配置') + }, + operateFields() { + const fields = { + tree: [ + { key: 'cycleHours', label: '培育小时', type: 'number' }, + { key: 'rate', label: '收益率', type: 'number', step: 0.01 }, + { key: 'minInvest', label: '最低投入', type: 'number' }, + { key: 'maxInvest', label: '最高投入', type: 'number' }, + { key: 'maxProfit', label: '单次最高收益', type: 'number' }, + { key: 'dailyProfitLimit', label: '每日收益上限', type: 'number' }, + { key: 'sort', label: '排序', type: 'number' }, + { key: 'enabled', label: '是否启用', type: 'switch' } + ], + warehouse: [ + { key: 'level', label: '等级', type: 'number' }, + { key: 'capacity', label: '容量', type: 'number' }, + { key: 'upgradeCost', label: '升级消耗券', type: 'number' }, + { key: 'enabled', label: '是否启用', type: 'switch' } + ], + tower: [ + { key: 'level', label: '等级', type: 'number' }, + { key: 'interceptRate', label: '拦截率(%)', type: 'number', step: 0.1 }, + { key: 'damage', label: '体力伤害', type: 'number' }, + { key: 'counterRate', label: '反击率(%)', type: 'number', step: 0.1 }, + { key: 'upgradeCost', label: '升级消耗券', type: 'number' }, + { key: 'enabled', label: '是否启用', type: 'switch' } + ], + search: [ + { key: 'dailyLimit', label: '每日次数', type: 'number' }, + { key: 'staminaCost', label: '消耗体力', type: 'number' }, + { key: 'minGain', label: '最低获得', type: 'number' }, + { key: 'maxGain', label: '最高获得', type: 'number' }, + { key: 'targetBalanceRate', label: '目标余额比例', type: 'number', step: 0.01 }, + { key: 'dailyGainLimit', label: '每日获得上限', type: 'number' }, + { key: 'targetProtectMinutes', label: '保护分钟', type: 'number' }, + { key: 'enabled', label: '是否启用', type: 'switch' } + ], + stamina: [ + { key: 'name', label: '道具名称' }, + { key: 'recoverStamina', label: '恢复体力', type: 'number' }, + { key: 'costTickets', label: '消耗券', type: 'number' }, + { key: 'dailyBuyLimit', label: '每日购买上限', type: 'number' }, + { key: 'sort', label: '排序', type: 'number' }, + { key: 'enabled', label: '是否启用', type: 'switch' } + ], + landmark: [ + { key: 'name', label: '地标名称' }, + { key: 'icon', label: '图标' }, + { key: 'benefitType', label: '收益类型', type: 'select', options: [ + { value: 'ticket', label: '每日发券' }, + { value: 'stamina_speed', label: '体力恢复加速' }, + { value: 'search_rate', label: '搜查成功率' }, + { value: 'tower_damage', label: '防御塔伤害' } + ] }, + { key: 'benefitValue', label: '收益值', type: 'number', step: 0.1 }, + { key: 'dailyOutputLimit', label: '日输出上限', type: 'number' }, + { key: 'openStartTime', label: '开放开始' }, + { key: 'openEndTime', label: '开放结束' }, + { key: 'settleTime', label: '结算时间' }, + { key: 'sort', label: '排序', type: 'number' }, + { key: 'enabled', label: '是否启用', type: 'switch' } + ] + } + return fields[this.operateType] || [] + }, poolColumns() { return [ { title: '期号', key: 'periodNo', minWidth: 120 }, @@ -416,6 +580,82 @@ { title: '已领取', width: 80, render: (h, p) => h('Tag', { props: { color: p.row.isReceived === 1 ? 'green' : 'orange' } }, p.row.isReceived === 1 ? '已领' : '未领') }, { title: '时间', key: 'createTime', minWidth: 160 } ] + }, + treeColumns() { + return [ + { title: '周期(h)', key: 'cycleHours', width: 90 }, + { title: '收益率', key: 'rate', width: 90 }, + { title: '投入范围', minWidth: 140, render: (h, p) => h('span', `${p.row.minInvest || 0} - ${p.row.maxInvest || '不限'}`) }, + { title: '单次收益上限', key: 'maxProfit', width: 120 }, + { title: '日收益上限', key: 'dailyProfitLimit', width: 110 }, + { title: '启用', width: 70, render: (h, p) => this.enabledTag(h, p.row.enabled) }, + this.operateActionColumn('tree') + ] + }, + warehouseColumns() { + return [ + { title: '等级', key: 'level', width: 90 }, + { title: '容量', key: 'capacity', width: 100 }, + { title: '升级消耗券', key: 'upgradeCost', width: 120 }, + { title: '启用', width: 70, render: (h, p) => this.enabledTag(h, p.row.enabled) }, + this.operateActionColumn('warehouse') + ] + }, + towerColumns() { + return [ + { title: '等级', key: 'level', width: 80 }, + { title: '拦截率(%)', key: 'interceptRate', width: 110 }, + { title: '伤害', key: 'damage', width: 90 }, + { title: '反击率(%)', key: 'counterRate', width: 110 }, + { title: '升级消耗券', key: 'upgradeCost', width: 120 }, + { title: '启用', width: 70, render: (h, p) => this.enabledTag(h, p.row.enabled) }, + this.operateActionColumn('tower') + ] + }, + searchColumns() { + return [ + { title: '每日次数', key: 'dailyLimit', width: 90 }, + { title: '体力消耗', key: 'staminaCost', width: 90 }, + { title: '获得范围', minWidth: 120, render: (h, p) => h('span', `${p.row.minGain || 0} - ${p.row.maxGain || 0}`) }, + { title: '目标比例', key: 'targetBalanceRate', width: 90 }, + { title: '日获得上限', key: 'dailyGainLimit', width: 110 }, + { title: '启用', width: 70, render: (h, p) => this.enabledTag(h, p.row.enabled) }, + this.operateActionColumn('search') + ] + }, + staminaColumns() { + return [ + { title: '名称', key: 'name', minWidth: 120 }, + { title: '恢复体力', key: 'recoverStamina', width: 90 }, + { title: '消耗券', key: 'costTickets', width: 90 }, + { title: '日购买上限', key: 'dailyBuyLimit', width: 110 }, + { title: '启用', width: 70, render: (h, p) => this.enabledTag(h, p.row.enabled) }, + this.operateActionColumn('stamina') + ] + }, + landmarkColumns() { + return [ + { title: '名称', key: 'name', minWidth: 120 }, + { title: '图标', key: 'icon', width: 80 }, + { title: '收益类型', key: 'benefitType', width: 120 }, + { title: '收益值', key: 'benefitValue', width: 90 }, + { title: '开放时间', minWidth: 150, render: (h, p) => h('span', `${p.row.openStartTime || '--'} - ${p.row.openEndTime || '--'}`) }, + { title: '启用', width: 70, render: (h, p) => this.enabledTag(h, p.row.enabled) }, + this.operateActionColumn('landmark') + ] + }, + economyColumns() { + return [ + { title: '日期', key: 'auditDate', width: 120 }, + { title: '产出券', key: 'newTickets', width: 90 }, + { title: '回收券', key: 'burnTickets', width: 90 }, + { title: '净增', key: 'netTickets', width: 90 }, + { title: '种植产出', key: 'plantOutput', width: 100 }, + { title: '地标回收', key: 'landmarkBurn', width: 100 }, + { title: '升级回收', key: 'upgradeBurn', width: 100 }, + { title: '活跃持券用户', key: 'activeUserCount', width: 120 }, + { title: '预警', width: 80, render: (h, p) => h('Tag', { props: { color: p.row.warning === 1 ? 'red' : 'green' } }, p.row.warning === 1 ? '净增' : '平衡') } + ] } }, mounted() { @@ -431,11 +671,25 @@ huntResultText(r) { return { success: '缴获成功', shield: '对方防护', fail: '扑空' }[r] || r }, + enabledTag(h, enabled) { + return h('Tag', { props: { color: enabled === 1 ? 'green' : 'default' } }, enabled === 1 ? '是' : '否') + }, + operateActionColumn(type) { + return { + title: '操作', width: 150, align: 'center', render: (h, params) => h('div', [ + h('Button', { props: { type: 'text', size: 'small' }, on: { click: () => this.openOperate(type, params.row) } }, '编辑'), + h('Button', { props: { type: 'text', size: 'small' }, style: { color: '#ed4014' }, on: { click: () => this.delOperate(type, params.row) } }, '删除') + ]) + } + }, onTabChange(name) { const map = { pool: this.loadPool, task: this.loadTask, buff: this.loadBuff, news: this.loadNews, rank: this.loadRank, hunt: this.loadHunt, - draw: this.loadDraw, winner: this.loadWinner + draw: this.loadDraw, winner: this.loadWinner, + tree: this.loadTree, warehouse: this.loadWarehouse, tower: this.loadTower, + search: this.loadSearch, stamina: this.loadStamina, landmark: this.loadLandmark, + economy: this.loadEconomy } map[name] && map[name]() }, @@ -489,6 +743,13 @@ loadHunt() { if (!this.guardRegion('hunt')) return; this.hunt.loading = true; planetHuntPage(this.baseParams('hunt')).then(r => this.fill('hunt', r)) }, loadDraw() { if (!this.guardRegion('draw')) return; this.draw.loading = true; planetDrawPage(this.baseParams('draw')).then(r => this.fill('draw', r)) }, loadWinner() { if (!this.guardRegion('winner')) return; this.winner.loading = true; planetWinnerPage(this.baseParams('winner')).then(r => this.fill('winner', r)) }, + loadTree() { if (!this.guardRegion('tree')) return; this.tree.loading = true; planetTreePage(this.baseParams('tree')).then(r => this.fill('tree', r)) }, + loadWarehouse() { if (!this.guardRegion('warehouse')) return; this.warehouse.loading = true; planetWarehousePage(this.baseParams('warehouse')).then(r => this.fill('warehouse', r)) }, + loadTower() { if (!this.guardRegion('tower')) return; this.tower.loading = true; planetTowerPage(this.baseParams('tower')).then(r => this.fill('tower', r)) }, + loadSearch() { if (!this.guardRegion('search')) return; this.search.loading = true; planetSearchPage(this.baseParams('search')).then(r => this.fill('search', r)) }, + loadStamina() { if (!this.guardRegion('stamina')) return; this.stamina.loading = true; planetStaminaPage(this.baseParams('stamina')).then(r => this.fill('stamina', r)) }, + loadLandmark() { if (!this.guardRegion('landmark')) return; this.landmark.loading = true; planetLandmarkPage(this.baseParams('landmark')).then(r => this.fill('landmark', r)) }, + loadEconomy() { if (!this.guardRegion('economy')) return; this.economy.loading = true; planetEconomyPage(this.baseParams('economy')).then(r => this.fill('economy', r)) }, // ---- 奖池 ---- openPool(row) { this.poolForm = row ? Object.assign({}, row) : { regionId: this.regionId || '', poolAmount: 88.88, status: 0 } @@ -597,6 +858,42 @@ delNews(row) { planetNewsDelete(row.id).then(() => { this.$Message.success('删除成功'); this.loadNews() }) }, + operateApis(type) { + return { + tree: { save: planetTreeSave, del: planetTreeDelete, load: this.loadTree, defaults: { cycleHours: 8, rate: 0.05, minInvest: 1, maxInvest: 50, maxProfit: 5, dailyProfitLimit: 10, sort: 0, enabled: 1 } }, + warehouse: { save: planetWarehouseSave, del: planetWarehouseDelete, load: this.loadWarehouse, defaults: { level: 1, capacity: 10, upgradeCost: 10, enabled: 1 } }, + tower: { save: planetTowerSave, del: planetTowerDelete, load: this.loadTower, defaults: { level: 1, interceptRate: 5, damage: 5, counterRate: 2, upgradeCost: 10, enabled: 1 } }, + search: { save: planetSearchSave, del: planetSearchDelete, load: this.loadSearch, defaults: { dailyLimit: 3, staminaCost: 30, minGain: 1, maxGain: 3, targetBalanceRate: 0.1, dailyGainLimit: 8, targetProtectMinutes: 30, enabled: 1 } }, + stamina: { save: planetStaminaSave, del: planetStaminaDelete, load: this.loadStamina, defaults: { name: '松果能量', recoverStamina: 30, costTickets: 2, dailyBuyLimit: 2, sort: 0, enabled: 1 } }, + landmark: { save: planetLandmarkSave, del: planetLandmarkDelete, load: this.loadLandmark, defaults: { name: '图书馆', icon: 'LIB', benefitType: 'ticket', benefitValue: 5, dailyOutputLimit: 5, openStartTime: '08:00', openEndTime: '22:00', settleTime: '22:00', sort: 0, enabled: 1 } } + }[type] + }, + openOperate(type, row) { + const api = this.operateApis(type) + this.operateType = type + this.operateForm = row ? Object.assign({}, row) : Object.assign({ regionId: this.regionId || '' }, api.defaults) + this.operateModal = true + }, + saveOperate() { + const api = this.operateApis(this.operateType) + api.save(this.operateForm).then(r => { + if (r && r.success) { + this.$Message.success('保存成功') + this.operateModal = false + api.load() + } else { + this.$Message.error((r && r.message) || '保存失败') + } + }) + }, + delOperate(type, row) { + const api = this.operateApis(type) + this.$Modal.confirm({ + title: '确认删除', + content: '确认删除该经营配置?', + onOk: () => api.del(row.id).then(() => { this.$Message.success('删除成功'); api.load() }) + }) + }, fmt(d) { const p = n => (n < 10 ? '0' + n : n) return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())} ${p(d.getHours())}:${p(d.getMinutes())}:${p(d.getSeconds())}` From 180fef0791b68a9c077ce65c7427bcb10646f2af Mon Sep 17 00:00:00 2001 From: wangfukang <15630117759@163.com> Date: Mon, 1 Jun 2026 14:40:03 +0800 Subject: [PATCH 2/3] 1 --- src/views/app/business/luckey/luckey.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/views/app/business/luckey/luckey.vue b/src/views/app/business/luckey/luckey.vue index dda57a1..962ebd5 100644 --- a/src/views/app/business/luckey/luckey.vue +++ b/src/views/app/business/luckey/luckey.vue @@ -10,7 +10,7 @@ - 现金奖池采用“主动投入”规则:用户投入星球券后即从余额扣除并回收,本期按投入券数加权开奖,投入越多中奖概率越高。 + 现金奖池采用“主动投入”规则:用户投入星球券后即从余额扣除并回收,本期按投入券数加权开奖,投入越多中奖概率越高
From cae4e47ea16320f295d26c9dd7c271b483e75644 Mon Sep 17 00:00:00 2001 From: wangfukang <15630117759@163.com> Date: Mon, 1 Jun 2026 14:41:34 +0800 Subject: [PATCH 3/3] 1 --- src/api/planet.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/planet.js b/src/api/planet.js index 75f8867..469e245 100644 --- a/src/api/planet.js +++ b/src/api/planet.js @@ -1,4 +1,4 @@ -// 白嫖星球 后台管理接口 +// 白嫖星球 import { getRequest, postRequest, postBodyRequest } from '@/libs/axios'; const PREFIX = '/app/planet/admin';