- 新增改枪码管理页面与 API(分页、新增、编辑、删除、复制) - 新增免登录公开页 public/delta-gun-codes.html - 新增通用剪贴板工具 src/common/js/clipboard.js
This commit is contained in:
@@ -0,0 +1,281 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>三角洲行动 · 改枪码速查复制</title>
|
||||||
|
<style>
|
||||||
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||||
|
body {
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif;
|
||||||
|
background: radial-gradient(1200px 600px at 80% -10%, #1d3a1d 0%, transparent 60%),
|
||||||
|
radial-gradient(900px 500px at -10% 110%, #14303a 0%, transparent 55%),
|
||||||
|
#0c1117;
|
||||||
|
color: #dbe4ee;
|
||||||
|
min-height: 100vh;
|
||||||
|
padding: 28px 16px 60px;
|
||||||
|
}
|
||||||
|
.wrap { max-width: 1200px; margin: 0 auto; }
|
||||||
|
|
||||||
|
/* 头部 */
|
||||||
|
.hero { text-align: center; margin-bottom: 26px; }
|
||||||
|
.hero .badge {
|
||||||
|
display: inline-block; font-size: 12px; letter-spacing: 2px; color: #7fd0a0;
|
||||||
|
border: 1px solid #2c6e4f; border-radius: 999px; padding: 4px 14px; margin-bottom: 14px;
|
||||||
|
background: rgba(44,110,79,.12);
|
||||||
|
}
|
||||||
|
.hero h1 { font-size: 30px; font-weight: 800; letter-spacing: 1px; }
|
||||||
|
.hero h1 span { color: #f0b04a; }
|
||||||
|
.hero p { margin-top: 10px; color: #8492a6; font-size: 14px; }
|
||||||
|
.hero .total { color: #7fd0a0; }
|
||||||
|
|
||||||
|
/* 工具栏 */
|
||||||
|
.toolbar { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; justify-content: center; margin-bottom: 22px; }
|
||||||
|
.toolbar .search input {
|
||||||
|
width: 260px; max-width: 60vw; background: #131a22; border: 1px solid #27313d;
|
||||||
|
color: #dbe4ee; padding: 9px 14px; border-radius: 8px; outline: none; font-size: 14px;
|
||||||
|
}
|
||||||
|
.toolbar .search input:focus { border-color: #3aa76d; }
|
||||||
|
.chips { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; }
|
||||||
|
.chip {
|
||||||
|
cursor: pointer; user-select: none; font-size: 13px; padding: 6px 14px;
|
||||||
|
border-radius: 999px; border: 1px solid #27313d; color: #9fb0c0; background: #131a22;
|
||||||
|
transition: all .15s;
|
||||||
|
}
|
||||||
|
.chip.active, .chip:hover { color: #0c1117; background: #7fd0a0; border-color: #7fd0a0; }
|
||||||
|
|
||||||
|
/* 卡片 */
|
||||||
|
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(340px, 1fr)); gap: 16px; }
|
||||||
|
.card {
|
||||||
|
background: #131a22; border: 1px solid #1f2a35; border-radius: 12px;
|
||||||
|
padding: 16px 16px 14px; display: flex; flex-direction: column; gap: 10px;
|
||||||
|
transition: transform .15s, border-color .15s;
|
||||||
|
}
|
||||||
|
.card:hover { transform: translateY(-2px); border-color: #2c6e4f; }
|
||||||
|
.card .top { display: flex; align-items: center; justify-content: space-between; }
|
||||||
|
.card .tags { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
|
||||||
|
.tag { font-size: 12px; padding: 2px 10px; border-radius: 6px; }
|
||||||
|
.tag.cat { color: #ffd28a; background: rgba(240,176,74,.12); border: 1px solid rgba(240,176,74,.4); }
|
||||||
|
.tag.gun { color: #9fd8ff; background: rgba(80,160,240,.1); border: 1px solid rgba(80,160,240,.35); }
|
||||||
|
.count { font-size: 12px; color: #6a7888; white-space: nowrap; }
|
||||||
|
.card .name { font-size: 17px; font-weight: 700; }
|
||||||
|
.card .code {
|
||||||
|
background: #0b0f14; border: 1px solid #22303d; border-radius: 8px;
|
||||||
|
padding: 10px 12px; font-family: "SFMono-Regular", Consolas, "Courier New", monospace;
|
||||||
|
font-size: 13px; line-height: 1.6; color: #a8f0c8; word-break: break-all;
|
||||||
|
max-height: 140px; overflow: auto; white-space: pre-wrap;
|
||||||
|
}
|
||||||
|
.card .remark { font-size: 13px; color: #8aa0b5; }
|
||||||
|
.card .foot { display: flex; align-items: center; justify-content: space-between; margin-top: auto; }
|
||||||
|
.copy-btn {
|
||||||
|
cursor: pointer; border: none; width: 100%; border-radius: 8px;
|
||||||
|
background: linear-gradient(135deg, #2f8f5e, #1f7a4e); color: #fff;
|
||||||
|
padding: 10px 0; font-size: 14px; font-weight: 700; letter-spacing: 1px; transition: filter .15s;
|
||||||
|
}
|
||||||
|
.copy-btn:hover { filter: brightness(1.12); }
|
||||||
|
.copy-btn:active { transform: scale(.98); }
|
||||||
|
|
||||||
|
/* 空状态 / loading */
|
||||||
|
.empty, .loading { text-align: center; padding: 60px 0; color: #8492a6; }
|
||||||
|
.empty svg { width: 46px; height: 46px; margin-bottom: 10px; opacity: .5; }
|
||||||
|
|
||||||
|
/* toast */
|
||||||
|
.toast {
|
||||||
|
position: fixed; left: 50%; bottom: 42px; transform: translate(-50%, 20px);
|
||||||
|
background: #18a05e; color: #fff; padding: 11px 22px; border-radius: 8px;
|
||||||
|
font-size: 14px; opacity: 0; visibility: hidden; transition: all .25s; z-index: 99;
|
||||||
|
box-shadow: 0 8px 24px rgba(0,0,0,.4);
|
||||||
|
}
|
||||||
|
.toast.show { opacity: 1; visibility: visible; transform: translate(-50%, 0); }
|
||||||
|
.toast.error { background: #d84a4a; }
|
||||||
|
|
||||||
|
footer { text-align: center; margin-top: 30px; color: #56616e; font-size: 12px; }
|
||||||
|
@media (max-width: 720px) {
|
||||||
|
.hero h1 { font-size: 23px; }
|
||||||
|
.grid { grid-template-columns: 1fr; }
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="hero">
|
||||||
|
<div class="badge">DELTA FORCE · GUN CODE</div>
|
||||||
|
<h1>三角洲行动 · <span>改枪码速查</span></h1>
|
||||||
|
<p>已收录 <span class="total" id="totalNum">0</span> 套配置,点击复制即可在游戏内粘贴使用</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="toolbar">
|
||||||
|
<div class="search">
|
||||||
|
<input id="searchInput" type="text" placeholder="搜索名称 / 枪械 / 分类...">
|
||||||
|
</div>
|
||||||
|
<div class="chips" id="chipBox"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="container">
|
||||||
|
<div class="loading" id="loading">加载中...</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<footer>三角洲行动 · 改枪码共享站 | 本页面无需登录即可访问</footer>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="toast" id="toast"></div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// 接口地址:生产走同源 /api(nginx 反代去前缀);本地 8080 开发时直连后端 8800
|
||||||
|
var apiBase = ''
|
||||||
|
var apiPrefix = '/api'
|
||||||
|
if (location.port === '8080' && /^(localhost|127\.0\.0\.1)$/.test(location.hostname)) {
|
||||||
|
apiBase = 'http://localhost:8800'
|
||||||
|
apiPrefix = ''
|
||||||
|
}
|
||||||
|
var listApi = apiBase + apiPrefix + '/delta-gun-code/public/list'
|
||||||
|
var countApi = apiBase + apiPrefix + '/delta-gun-code/public/addCopyCount'
|
||||||
|
|
||||||
|
var allData = []
|
||||||
|
var activeCategory = '全部'
|
||||||
|
var keyword = ''
|
||||||
|
|
||||||
|
var container = document.getElementById('container')
|
||||||
|
var loading = document.getElementById('loading')
|
||||||
|
var chipBox = document.getElementById('chipBox')
|
||||||
|
var searchInput = document.getElementById('searchInput')
|
||||||
|
var toast = document.getElementById('toast')
|
||||||
|
var totalNum = document.getElementById('totalNum')
|
||||||
|
|
||||||
|
function showToast (msg, isError) {
|
||||||
|
toast.textContent = msg
|
||||||
|
toast.className = 'toast show' + (isError ? ' error' : '')
|
||||||
|
clearTimeout(showToast._t)
|
||||||
|
showToast._t = setTimeout(function () { toast.className = 'toast' }, 2000)
|
||||||
|
}
|
||||||
|
|
||||||
|
function copyText (text) {
|
||||||
|
if (navigator.clipboard && window.isSecureContext) {
|
||||||
|
return navigator.clipboard.writeText(text).then(function () { return true }).catch(function () { return fallbackCopy(text) })
|
||||||
|
}
|
||||||
|
return Promise.resolve(fallbackCopy(text))
|
||||||
|
}
|
||||||
|
|
||||||
|
function fallbackCopy (text) {
|
||||||
|
var ta = document.createElement('textarea')
|
||||||
|
ta.value = text
|
||||||
|
ta.setAttribute('readonly', '')
|
||||||
|
ta.style.position = 'fixed'
|
||||||
|
ta.style.top = '-9999px'
|
||||||
|
ta.style.opacity = '0'
|
||||||
|
document.body.appendChild(ta)
|
||||||
|
ta.select()
|
||||||
|
var ok = false
|
||||||
|
try { ok = document.execCommand('copy') } catch (e) { ok = false }
|
||||||
|
document.body.removeChild(ta)
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderChips () {
|
||||||
|
var set = ['全部']
|
||||||
|
allData.forEach(function (item) {
|
||||||
|
if (item.category && set.indexOf(item.category) < 0) set.push(item.category)
|
||||||
|
})
|
||||||
|
chipBox.innerHTML = ''
|
||||||
|
set.forEach(function (c) {
|
||||||
|
var el = document.createElement('div')
|
||||||
|
el.className = 'chip' + (c === activeCategory ? ' active' : '')
|
||||||
|
el.textContent = c
|
||||||
|
el.onclick = function () {
|
||||||
|
activeCategory = c
|
||||||
|
renderChips()
|
||||||
|
renderCards()
|
||||||
|
}
|
||||||
|
chipBox.appendChild(el)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function filterData () {
|
||||||
|
var kw = keyword.trim().toLowerCase()
|
||||||
|
return allData.filter(function (item) {
|
||||||
|
if (activeCategory !== '全部' && item.category !== activeCategory) return false
|
||||||
|
if (!kw) return true
|
||||||
|
return [item.name, item.gunName, item.category, item.code].join(' ').toLowerCase().indexOf(kw) > -1
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderCards () {
|
||||||
|
var list = filterData()
|
||||||
|
totalNum.textContent = list.length
|
||||||
|
if (!list.length) {
|
||||||
|
container.innerHTML =
|
||||||
|
'<div class="empty"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M3 6h18M6 6v12M18 6v12M6 18h12M10 9v6M14 9v6"/></svg>' +
|
||||||
|
'<div>没有找到对应的改枪码,稍后再来看看吧</div></div>'
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var html = '<div class="grid">'
|
||||||
|
list.forEach(function (item) {
|
||||||
|
var cat = item.category ? '<span class="tag cat">' + esc(item.category) + '</span>' : ''
|
||||||
|
var gun = item.gunName ? '<span class="tag gun">' + esc(item.gunName) + '</span>' : ''
|
||||||
|
var remark = item.remark ? '<div class="remark">' + esc(item.remark) + '</div>' : ''
|
||||||
|
html +=
|
||||||
|
'<div class="card">' +
|
||||||
|
' <div class="top"><div class="tags">' + cat + gun + '</div>' +
|
||||||
|
' <span class="count">被复制 ' + (item.copyCount || 0) + ' 次</span></div>' +
|
||||||
|
' <div class="name">' + esc(item.name || '未命名配置') + '</div>' +
|
||||||
|
' <div class="code">' + esc(item.code || '') + '</div>' +
|
||||||
|
remark +
|
||||||
|
' <div class="foot"><button class="copy-btn" data-id="' + item.id + '">复制改枪码</button></div>' +
|
||||||
|
'</div>'
|
||||||
|
})
|
||||||
|
html += '</div>'
|
||||||
|
container.innerHTML = html
|
||||||
|
}
|
||||||
|
|
||||||
|
function esc (s) {
|
||||||
|
return String(s == null ? '' : s).replace(/[&<>"']/g, function (c) {
|
||||||
|
return { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }[c]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener('click', function (e) {
|
||||||
|
var btn = e.target.closest('.copy-btn')
|
||||||
|
if (!btn) return
|
||||||
|
var id = Number(btn.getAttribute('data-id'))
|
||||||
|
var item = allData.find(function (x) { return x.id === id })
|
||||||
|
if (!item) return
|
||||||
|
copyText(item.code).then(function (ok) {
|
||||||
|
if (ok) {
|
||||||
|
showToast('复制成功,去游戏里粘贴吧!')
|
||||||
|
// 异步上报复制次数,失败不影响用户
|
||||||
|
fetch(countApi + '?id=' + id, { method: 'GET' }).catch(function () {})
|
||||||
|
} else {
|
||||||
|
showToast('复制失败,请长按改枪码手动复制', true)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
searchInput.addEventListener('input', function (e) {
|
||||||
|
keyword = e.target.value
|
||||||
|
renderCards()
|
||||||
|
})
|
||||||
|
|
||||||
|
function load () {
|
||||||
|
fetch(listApi, { method: 'GET' }).then(function (res) {
|
||||||
|
if (!res.ok) throw new Error('http ' + res.status)
|
||||||
|
return res.json()
|
||||||
|
}).then(function (res) {
|
||||||
|
if (res.code === 200) {
|
||||||
|
allData = (res.data || []).filter(function (x) { return x.code })
|
||||||
|
} else {
|
||||||
|
throw new Error(res.message || '加载失败')
|
||||||
|
}
|
||||||
|
renderChips()
|
||||||
|
renderCards()
|
||||||
|
}).catch(function (err) {
|
||||||
|
loading.style.display = 'none'
|
||||||
|
container.innerHTML =
|
||||||
|
'<div class="empty"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><circle cx="12" cy="12" r="9"/><path d="M12 8v4M12 16h.01"/></svg>' +
|
||||||
|
'<div>数据加载失败:' + esc(err.message || err) + '<br><small style="color:#56616e">请确认后端服务可用后刷新重试</small></div></div>'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
load()
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
import axios from '@/libs/api.request'
|
||||||
|
import { getToken } from '@/libs/util'
|
||||||
|
|
||||||
|
/** 后台管理-分页查询改枪码列表 **/
|
||||||
|
export const getDataList = (data) => {
|
||||||
|
return axios.request({
|
||||||
|
url: 'delta-gun-code/findPageList',
|
||||||
|
headers: {
|
||||||
|
'Authorization': getToken()
|
||||||
|
},
|
||||||
|
data: data,
|
||||||
|
method: 'post'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 后台管理-新增改枪码 **/
|
||||||
|
export const add = (data) => {
|
||||||
|
return axios.request({
|
||||||
|
url: 'delta-gun-code/add',
|
||||||
|
headers: {
|
||||||
|
'Authorization': getToken()
|
||||||
|
},
|
||||||
|
data: data,
|
||||||
|
method: 'post'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 后台管理-更新改枪码 **/
|
||||||
|
export const update = (data) => {
|
||||||
|
return axios.request({
|
||||||
|
url: 'delta-gun-code/update',
|
||||||
|
headers: {
|
||||||
|
'Authorization': getToken()
|
||||||
|
},
|
||||||
|
data: data,
|
||||||
|
method: 'post'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 后台管理-删除改枪码 **/
|
||||||
|
export const remove = (data) => {
|
||||||
|
return axios.request({
|
||||||
|
url: 'delta-gun-code/remove',
|
||||||
|
headers: {
|
||||||
|
'Authorization': getToken()
|
||||||
|
},
|
||||||
|
data: data,
|
||||||
|
method: 'post'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 公开-查询所有启用改枪码(无需鉴权) **/
|
||||||
|
export const getPublicList = () => {
|
||||||
|
return axios.request({
|
||||||
|
url: 'delta-gun-code/public/list',
|
||||||
|
method: 'post'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 公开-复制成功增加复制次数(无需鉴权) **/
|
||||||
|
export const addCopyCount = (id) => {
|
||||||
|
return axios.request({
|
||||||
|
url: 'delta-gun-code/public/addCopyCount',
|
||||||
|
params: { id: id },
|
||||||
|
method: 'post'
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
/**
|
||||||
|
* 文本复制工具
|
||||||
|
* 优先使用 navigator.clipboard(需安全上下文),否则降级为隐藏 textarea + execCommand
|
||||||
|
* @param {String} text 待复制的文本
|
||||||
|
* @returns {Promise<Boolean>} 是否复制成功
|
||||||
|
*/
|
||||||
|
const fallbackCopy = (text) => {
|
||||||
|
const textarea = document.createElement('textarea')
|
||||||
|
textarea.value = text
|
||||||
|
textarea.setAttribute('readonly', '')
|
||||||
|
textarea.style.position = 'fixed'
|
||||||
|
textarea.style.top = '-9999px'
|
||||||
|
textarea.style.opacity = '0'
|
||||||
|
document.body.appendChild(textarea)
|
||||||
|
textarea.select()
|
||||||
|
textarea.setSelectionRange(0, textarea.value.length)
|
||||||
|
let ok = false
|
||||||
|
try {
|
||||||
|
ok = document.execCommand('copy')
|
||||||
|
} catch (e) {
|
||||||
|
ok = false
|
||||||
|
}
|
||||||
|
document.body.removeChild(textarea)
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
|
export const copyText = (text) => {
|
||||||
|
if (!text) return Promise.resolve(false)
|
||||||
|
if (navigator.clipboard && window.isSecureContext) {
|
||||||
|
return navigator.clipboard.writeText(text)
|
||||||
|
.then(() => true)
|
||||||
|
.catch(() => fallbackCopy(text))
|
||||||
|
}
|
||||||
|
return Promise.resolve(fallbackCopy(text))
|
||||||
|
}
|
||||||
|
|
||||||
|
export default copyText
|
||||||
@@ -0,0 +1,414 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<!-- 查询区域 start -->
|
||||||
|
<div class="option">
|
||||||
|
<Input v-model="search.name" class="short-input" clearable placeholder="配装名称"/>
|
||||||
|
<Input v-model="search.gunName" class="short-input" clearable placeholder="枪械/载具"/>
|
||||||
|
<Input v-model="search.category" class="short-input" clearable placeholder="分类标签"/>
|
||||||
|
<Button class="free" type="primary" icon="ios-search" @click="getDataList()">查询</Button>
|
||||||
|
<Button class="free" type="primary" icon="md-refresh" @click="refresh()">重置</Button>
|
||||||
|
</div>
|
||||||
|
<!-- 查询区域 end -->
|
||||||
|
|
||||||
|
<!-- 公开复制页面地址 start -->
|
||||||
|
<div class="share-address">
|
||||||
|
<span class="share-label">公开复制页地址(无需登录)</span>
|
||||||
|
<Input v-model="shareUrl" readonly class="share-input"/>
|
||||||
|
<Button type="success" icon="md-link" @click="copyAddress">复制地址</Button>
|
||||||
|
</div>
|
||||||
|
<!-- 公开复制页面地址 end -->
|
||||||
|
|
||||||
|
<!-- 列表区域 start -->
|
||||||
|
<div class="table-button-list">
|
||||||
|
<Button class="free" type="info" icon="md-add" @click="toAdd">添加</Button>
|
||||||
|
</div>
|
||||||
|
<Table :height="fixedHeader ? autoHeight : ''"
|
||||||
|
border ref="table"
|
||||||
|
:columns="listColumns"
|
||||||
|
:data="dataList"
|
||||||
|
:loading="tableLoading">
|
||||||
|
<template slot-scope="{ row }" slot="category">
|
||||||
|
<Tag :color="categoryColor(row.category)">{{ row.category || '未分类' }}</Tag>
|
||||||
|
</template>
|
||||||
|
<template slot-scope="{ row }" slot="status">
|
||||||
|
<i-switch :value="row.status === 1" true-value="1" false-value="0"
|
||||||
|
@on-change="val => updateStatus(row, val)">
|
||||||
|
<span slot="open">显示</span>
|
||||||
|
<span slot="close">隐藏</span>
|
||||||
|
</i-switch>
|
||||||
|
</template>
|
||||||
|
<template slot-scope="{ row, index }" slot="action">
|
||||||
|
<Button type="success"
|
||||||
|
size="small"
|
||||||
|
style="margin-right: 5px"
|
||||||
|
icon="md-copy"
|
||||||
|
@click="copyRow(index)">复制
|
||||||
|
</Button>
|
||||||
|
<Button type="primary"
|
||||||
|
size="small"
|
||||||
|
style="margin-right: 5px"
|
||||||
|
icon="ios-create"
|
||||||
|
@click="toEdit(index)">编辑
|
||||||
|
</Button>
|
||||||
|
<Poptip
|
||||||
|
confirm
|
||||||
|
title="您确定要删除吗?"
|
||||||
|
:transfer="true"
|
||||||
|
@on-ok="toDelete(index)"
|
||||||
|
>
|
||||||
|
<Button type="error" size="small" icon="md-trash">删除</Button>
|
||||||
|
</Poptip>
|
||||||
|
</template>
|
||||||
|
</Table>
|
||||||
|
<div class="pagination">
|
||||||
|
<Page show-elevator show-sizer show-total
|
||||||
|
:total="pageTotal" :page-size="pageParam.pageSize"
|
||||||
|
:current="pageParam.pageNum"
|
||||||
|
@on-page-size-change="changePageSize" @on-change="changePage"></Page>
|
||||||
|
</div>
|
||||||
|
<!-- 列表区域 end -->
|
||||||
|
|
||||||
|
<!-- Modal区域 start -->
|
||||||
|
<Modal v-model="modal" :title="modalTitle" :styles="{top: '20px'}" width="700" :mask-closable="false"
|
||||||
|
@on-cancel="cancel()">
|
||||||
|
<Form :rules="ruleCustom" :model="formItem" ref="formItem" :label-width="110" label-position="right">
|
||||||
|
<Row :gutter="32">
|
||||||
|
<Col span="12">
|
||||||
|
<FormItem label="配装名称" prop="name">
|
||||||
|
<Input type="text" class="form-input" v-model="formItem.name" placeholder="如:MP7 冲锋流"/>
|
||||||
|
</FormItem>
|
||||||
|
</Col>
|
||||||
|
<Col span="12">
|
||||||
|
<FormItem label="枪械/载具" prop="gunName">
|
||||||
|
<Input type="text" class="form-input" v-model="formItem.gunName" placeholder="如:MP7"/>
|
||||||
|
</FormItem>
|
||||||
|
</Col>
|
||||||
|
<Col span="12">
|
||||||
|
<FormItem label="分类标签" prop="category">
|
||||||
|
<Input type="text" class="form-input" v-model="formItem.category" placeholder="如:主武器/副武器"/>
|
||||||
|
</FormItem>
|
||||||
|
</Col>
|
||||||
|
<Col span="12">
|
||||||
|
<FormItem label="排序" prop="sort">
|
||||||
|
<InputNumber :min="0" v-model="formItem.sort" class="form-input" placeholder="数字越小越靠前"/>
|
||||||
|
</FormItem>
|
||||||
|
</Col>
|
||||||
|
<Col span="12">
|
||||||
|
<FormItem label="状态" prop="status">
|
||||||
|
<RadioGroup v-model="formItem.status">
|
||||||
|
<Radio :label="1">
|
||||||
|
<span>显示</span>
|
||||||
|
</Radio>
|
||||||
|
<Radio :label="0">
|
||||||
|
<span>隐藏</span>
|
||||||
|
</Radio>
|
||||||
|
</RadioGroup>
|
||||||
|
</FormItem>
|
||||||
|
</Col>
|
||||||
|
<Col span="24">
|
||||||
|
<FormItem label="改枪码" prop="code">
|
||||||
|
<Input type="textarea" :rows="8" show-word-limit class="form-input"
|
||||||
|
v-model="formItem.code" placeholder="请输入改枪码内容(公开页面可直接复制)"/>
|
||||||
|
</FormItem>
|
||||||
|
</Col>
|
||||||
|
<Col span="24">
|
||||||
|
<FormItem label="备注" prop="remark">
|
||||||
|
<Input type="textarea" :rows="3" maxlength="200" show-word-limit class="form-input"
|
||||||
|
v-model="formItem.remark" placeholder="选填:配装思路/适用场景等"/>
|
||||||
|
</FormItem>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</Form>
|
||||||
|
<div slot="footer">
|
||||||
|
<Button type="text" size="large" @click="cancel">取消</Button>
|
||||||
|
<Button type="primary" size="large"
|
||||||
|
:loading="submitLoading"
|
||||||
|
@click="submit('formItem')">提交
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
|
<!-- Modal区域 end -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { getDataList, add, update, remove } from '@/api/delta/delta-gun-code'
|
||||||
|
import { objectUtil } from '@/common/js/util'
|
||||||
|
import { copyText } from '@/common/js/clipboard'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'delta-gun-code',
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
fixedHeader: true, // 高度自适应
|
||||||
|
autoHeight: `${window.innerHeight} ` * 0.55, // 获取当前可视高度-定义Table高度
|
||||||
|
shareUrl: `${window.location.origin}/delta-gun-codes.html`, // 公开复制页面地址
|
||||||
|
search: {
|
||||||
|
name: '',
|
||||||
|
gunName: '',
|
||||||
|
category: ''
|
||||||
|
},
|
||||||
|
listColumns: [
|
||||||
|
{
|
||||||
|
title: '#',
|
||||||
|
type: 'index',
|
||||||
|
width: 60,
|
||||||
|
align: 'center',
|
||||||
|
indexMethod: (row) => {
|
||||||
|
return (row._index + 1) + ((this.pageParam.pageNum - 1) * this.pageParam.pageSize)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '配装名称',
|
||||||
|
key: 'name',
|
||||||
|
minWidth: 160
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '枪械/载具',
|
||||||
|
key: 'gunName',
|
||||||
|
width: 120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '分类',
|
||||||
|
slot: 'category',
|
||||||
|
width: 130,
|
||||||
|
align: 'center'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '排序',
|
||||||
|
key: 'sort',
|
||||||
|
width: 80,
|
||||||
|
align: 'center'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '被复制次数',
|
||||||
|
key: 'copyCount',
|
||||||
|
width: 110,
|
||||||
|
align: 'center'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '状态',
|
||||||
|
slot: 'status',
|
||||||
|
width: 110,
|
||||||
|
align: 'center'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作区',
|
||||||
|
slot: 'action',
|
||||||
|
width: 230,
|
||||||
|
fixed: 'right',
|
||||||
|
align: 'center'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
dataList: [],
|
||||||
|
tableLoading: false,
|
||||||
|
pageTotal: 0, // 总页数
|
||||||
|
pageParam: { // 调用时候的分页参数
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10
|
||||||
|
},
|
||||||
|
modal: false,
|
||||||
|
modalTitle: '',
|
||||||
|
addModal: false, // 添加
|
||||||
|
editModal: false, // 编辑
|
||||||
|
submitLoading: false,
|
||||||
|
formItem: {
|
||||||
|
id: '',
|
||||||
|
name: '',
|
||||||
|
gunName: '',
|
||||||
|
category: '',
|
||||||
|
code: '',
|
||||||
|
remark: '',
|
||||||
|
sort: 0,
|
||||||
|
status: 1
|
||||||
|
},
|
||||||
|
ruleCustom: {
|
||||||
|
name: [{ required: true, message: '请输入配装名称', trigger: 'blur' }],
|
||||||
|
code: [{ required: true, message: '请输入改枪码', trigger: 'blur' }]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getDataList () {
|
||||||
|
let temp = JSON.parse(JSON.stringify(this.pageParam))
|
||||||
|
let data = objectUtil.trimJoin(temp, this.search)
|
||||||
|
this.tableLoading = true
|
||||||
|
getDataList(data).then(res => {
|
||||||
|
let page = res.data.data
|
||||||
|
this.pageTotal = page.total
|
||||||
|
this.dataList = page.records
|
||||||
|
// 延迟300毫秒,给它更流畅的感觉
|
||||||
|
setTimeout(() => {
|
||||||
|
this.tableLoading = false
|
||||||
|
}, 300)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
toAdd () {
|
||||||
|
this.modalTitle = '添加'
|
||||||
|
this.modal = true
|
||||||
|
this.addModal = true
|
||||||
|
this.editModal = false
|
||||||
|
},
|
||||||
|
toEdit (index) {
|
||||||
|
this.modalTitle = '编辑'
|
||||||
|
let temp = this.dataList[index]
|
||||||
|
|
||||||
|
this.addModal = false
|
||||||
|
this.editModal = true
|
||||||
|
this.modal = true
|
||||||
|
|
||||||
|
this.$nextTick(() => {
|
||||||
|
// 清除上次校验状态,避免编辑回显报红
|
||||||
|
if (this.$refs.formItem) {
|
||||||
|
this.$refs.formItem.resetFields()
|
||||||
|
}
|
||||||
|
this.formItem.id = temp.id
|
||||||
|
this.formItem.name = temp.name
|
||||||
|
this.formItem.gunName = temp.gunName
|
||||||
|
this.formItem.category = temp.category
|
||||||
|
this.formItem.code = temp.code
|
||||||
|
this.formItem.remark = temp.remark
|
||||||
|
this.formItem.sort = temp.sort
|
||||||
|
this.formItem.status = temp.status
|
||||||
|
})
|
||||||
|
},
|
||||||
|
submit (formItem) {
|
||||||
|
// modal 提交
|
||||||
|
this.$refs[formItem].validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
if (this.addModal) { // 添加
|
||||||
|
add(this.formItem).then(res => {
|
||||||
|
this.$Message.success('添加成功!')
|
||||||
|
this.refresh()
|
||||||
|
this.getDataList()
|
||||||
|
})
|
||||||
|
} else { // 编辑
|
||||||
|
update(this.formItem).then(res => {
|
||||||
|
this.$Message.success('编辑成功!')
|
||||||
|
this.refresh()
|
||||||
|
this.getDataList()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this.cancel()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
cancel () {
|
||||||
|
// Modal cancel
|
||||||
|
this.modal = false
|
||||||
|
this.refresh()
|
||||||
|
},
|
||||||
|
toDelete (index) {
|
||||||
|
let temp = this.dataList[index]
|
||||||
|
let data = {
|
||||||
|
id: temp.id
|
||||||
|
}
|
||||||
|
remove(data).then(res => {
|
||||||
|
this.refresh()
|
||||||
|
this.getDataList()
|
||||||
|
this.$Message.success('删除成功!')
|
||||||
|
})
|
||||||
|
},
|
||||||
|
updateStatus (row, value) {
|
||||||
|
let status = value === true || value === 1 || value === '1' ? 1 : 0
|
||||||
|
let data = {
|
||||||
|
id: row.id,
|
||||||
|
status: status
|
||||||
|
}
|
||||||
|
update(data).then(res => {
|
||||||
|
this.$Message.success('状态更新成功!')
|
||||||
|
this.getDataList()
|
||||||
|
}).catch(() => {
|
||||||
|
this.getDataList()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
copyRow (index) {
|
||||||
|
let temp = this.dataList[index]
|
||||||
|
copyText(temp.code).then(ok => {
|
||||||
|
if (ok) {
|
||||||
|
this.$Message.success('改枪码已复制到剪贴板!')
|
||||||
|
} else {
|
||||||
|
this.$Message.error('复制失败,请手动选择复制')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
copyAddress () {
|
||||||
|
copyText(this.shareUrl).then(ok => {
|
||||||
|
if (ok) {
|
||||||
|
this.$Message.success('公开页面地址已复制!')
|
||||||
|
} else {
|
||||||
|
this.$Message.error('复制失败,请手动选择复制')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
refresh () {
|
||||||
|
this.pageParam = {
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10
|
||||||
|
}
|
||||||
|
this.search = {
|
||||||
|
name: '',
|
||||||
|
gunName: '',
|
||||||
|
category: ''
|
||||||
|
}
|
||||||
|
this.formItem = {
|
||||||
|
id: '',
|
||||||
|
name: '',
|
||||||
|
gunName: '',
|
||||||
|
category: '',
|
||||||
|
code: '',
|
||||||
|
remark: '',
|
||||||
|
sort: 0,
|
||||||
|
status: 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
changePage (index) {
|
||||||
|
// 需要显示开始数据的index,(因为数据是从0开始的,页码是从1开始的,需要-1)
|
||||||
|
this.pageParam.pageNum = index
|
||||||
|
this.getDataList()
|
||||||
|
},
|
||||||
|
changePageSize (page) {
|
||||||
|
// 切换分页条数
|
||||||
|
this.pageParam.pageNum = 1
|
||||||
|
this.pageParam.pageSize = page
|
||||||
|
this.getDataList()
|
||||||
|
},
|
||||||
|
categoryColor (category) {
|
||||||
|
let map = {
|
||||||
|
'主武器': 'red',
|
||||||
|
'副武器': 'blue',
|
||||||
|
'载具配置': 'green',
|
||||||
|
'装备': 'orange',
|
||||||
|
'默认': 'default'
|
||||||
|
}
|
||||||
|
return map[category] || 'geekblue'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created () {
|
||||||
|
this.getDataList()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.form-input {
|
||||||
|
width: 100%
|
||||||
|
}
|
||||||
|
|
||||||
|
.share-address {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin: 4px 0 8px;
|
||||||
|
.share-label {
|
||||||
|
white-space: nowrap;
|
||||||
|
margin-right: 10px;
|
||||||
|
color: #808695;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
.share-input {
|
||||||
|
max-width: 520px;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user