每周更新
This commit is contained in:
@@ -222,6 +222,15 @@
|
||||
@input="handleEditFeeRateInput"
|
||||
/>
|
||||
</div>
|
||||
<div class="row">
|
||||
<label class="label">谷歌验证码</label>
|
||||
<el-input
|
||||
v-model="editForm.gCode"
|
||||
placeholder="请输入6位谷歌验证码"
|
||||
maxlength="6"
|
||||
@input="handleEditShopGoogleCodeInput"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="visibleEdit=false">取消</el-button>
|
||||
@@ -263,7 +272,7 @@ import { getMyShop, updateShop, deleteShop, queryShop, closeShop ,updateShopConf
|
||||
import { coinList } from '@/utils/coinList'
|
||||
import { getShopConfig,getShopConfigV2 ,withdrawBalanceForSeller,updateShopConfigV2} from '@/api/wallet'
|
||||
import { rsaEncrypt, rsaEncryptSync } from '@/utils/rsaEncrypt'
|
||||
|
||||
import { getGoogleStatus } from '@/api/verification'
|
||||
|
||||
export default {
|
||||
name: 'AccountMyShops',
|
||||
@@ -281,7 +290,7 @@ export default {
|
||||
state: 0
|
||||
},
|
||||
visibleEdit: false,
|
||||
editForm: { id: '', name: '', image: '', description: '', feeRate: '' },
|
||||
editForm: { id: '', name: '', image: '', description: '', feeRate: '', gCode: '' },
|
||||
// 店铺配置列表
|
||||
shopConfigs: [],
|
||||
visibleConfigEdit: false,
|
||||
@@ -370,6 +379,58 @@ export default {
|
||||
this.fetchMyShop()
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 修改店铺:谷歌验证码输入(仅数字,最多6位)
|
||||
*/
|
||||
handleEditShopGoogleCodeInput(v) {
|
||||
this.editForm.gCode = String(v || '').replace(/\D/g, '').slice(0, 6)
|
||||
},
|
||||
/**
|
||||
* 钱包相关敏感操作前置校验:必须已开启双重验证(Google Authenticator)
|
||||
* getGoogleStatus 返回值:0 开启;1 未绑定;2 关闭
|
||||
*
|
||||
* - status=0:允许继续操作
|
||||
* - status=1/2:弹窗提示并阻止操作,可跳转到“安全设置”页面开启/绑定
|
||||
*
|
||||
* @param {string} actionLabel - 操作名称(用于文案:如“提现/修改/删除”)
|
||||
* @returns {Promise<boolean>} 是否允许继续
|
||||
*/
|
||||
async ensureGoogleStatusEnabledForWalletOp(actionLabel) {
|
||||
try {
|
||||
const res = await getGoogleStatus()
|
||||
if (!res || !(res.code === 0 || res.code === 200)) {
|
||||
this.$message.error('获取双重验证状态失败,请稍后重试')
|
||||
return false
|
||||
}
|
||||
|
||||
const status = (res && res.data && res.data.status != null) ? res.data.status : (res.data ?? 1)
|
||||
if (Number(status) === 0) return true
|
||||
|
||||
const title = '安全提示'
|
||||
const reason = Number(status) === 1 ? '您尚未绑定双重验证' : '您已关闭双重验证'
|
||||
const message = `
|
||||
<div class="google-2fa-guard__content">
|
||||
<div class="google-2fa-guard__title">${reason}</div>
|
||||
<div class="google-2fa-guard__desc">
|
||||
请先在<strong>安全设置</strong>中绑定并开启双重验证后,才可以进行<strong>${actionLabel || '该'}操作</strong>。
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
|
||||
await this.$confirm(message, title, {
|
||||
confirmButtonText: '去安全设置',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
dangerouslyUseHTMLString: true,
|
||||
customClass: 'google-2fa-guard-dialog'
|
||||
})
|
||||
this.$router.push('/account/security-settings')
|
||||
return false
|
||||
} catch (e) {
|
||||
// 用户取消弹窗或接口异常都视为不允许继续
|
||||
return false
|
||||
}
|
||||
},
|
||||
/** 余额展示:带币种单位 */
|
||||
formatBalance(row) {
|
||||
try {
|
||||
@@ -399,6 +460,9 @@ export default {
|
||||
},
|
||||
/** 打开提现对话框(行数据驱动) */
|
||||
async handleWithdraw(row) {
|
||||
const ok = await this.ensureGoogleStatusEnabledForWalletOp('提现')
|
||||
if (!ok) return
|
||||
|
||||
this.currentWithdrawRow = row || {}
|
||||
const fee = Number(row && (row.serviceCharge != null ? row.serviceCharge : row.charge))
|
||||
this.withdrawForm.fee = Number.isFinite(fee) ? this.formatDec6(fee) : '0.00'
|
||||
@@ -413,7 +477,10 @@ export default {
|
||||
{ required: true, message: '请输入提现金额', trigger: 'blur' },
|
||||
{ validator: this.validateWithdrawAmount, trigger: 'blur' }
|
||||
],
|
||||
// 地址为只读已填,不再要求用户输入
|
||||
toAddress: [
|
||||
{ required: true, message: '请输入收款钱包地址', trigger: 'blur' },
|
||||
{ validator: this.validateWithdrawToAddress, trigger: 'blur' }
|
||||
],
|
||||
googleCode: [
|
||||
{ required: true, message: '请输入谷歌验证码', trigger: 'blur' },
|
||||
{ validator: this.validateGoogleCode, trigger: 'blur' }
|
||||
@@ -584,6 +651,17 @@ export default {
|
||||
if (!/^\d{6}$/.test(v)) { callback(new Error('谷歌验证码必须是6位数字')); return }
|
||||
callback()
|
||||
},
|
||||
/**
|
||||
* 校验:收款地址不能为空
|
||||
* @param {any} rule
|
||||
* @param {string} value
|
||||
* @param {(err?: Error) => void} callback
|
||||
*/
|
||||
validateWithdrawToAddress(rule, value, callback) {
|
||||
const v = String(value || '').trim()
|
||||
if (!v) { callback(new Error('请输入收款钱包地址')); return }
|
||||
callback()
|
||||
},
|
||||
/**
|
||||
* 手续费率显示:最多6位小数,去除多余的0;空值显示为 '-'
|
||||
*/
|
||||
@@ -707,6 +785,9 @@ export default {
|
||||
}
|
||||
},
|
||||
async handleEditConfig(row) {
|
||||
const ok = await this.ensureGoogleStatusEnabledForWalletOp('修改')
|
||||
if (!ok) return
|
||||
|
||||
try {
|
||||
const res = await getChainAndCoin({ id: row.id })
|
||||
if (res && (res.code === 0 || res.code === 200) && res.data) {
|
||||
@@ -745,7 +826,31 @@ export default {
|
||||
}
|
||||
},
|
||||
async handleDeleteConfig(row) {
|
||||
this.deleteShopConfig({id:row.id})
|
||||
const ok = await this.ensureGoogleStatusEnabledForWalletOp('删除')
|
||||
if (!ok) return
|
||||
|
||||
try {
|
||||
const { value } = await this.$prompt(
|
||||
'请输入 6 位谷歌验证码以删除该钱包绑定配置',
|
||||
'安全验证',
|
||||
{
|
||||
confirmButtonText: '确认删除',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
inputPlaceholder: '6位数字验证码',
|
||||
inputPattern: /^\d{6}$/,
|
||||
inputErrorMessage: '谷歌验证码必须是6位数字'
|
||||
}
|
||||
)
|
||||
const gCode = String(value || '').trim()
|
||||
if (!/^\d{6}$/.test(gCode)) {
|
||||
this.$message.warning('谷歌验证码必须是6位数字')
|
||||
return
|
||||
}
|
||||
await this.deleteShopConfig({ id: row.id, gCode })
|
||||
} catch (e) {
|
||||
// 用户取消或弹窗关闭
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -828,6 +933,8 @@ export default {
|
||||
this.configForm.payCoins = (this.configForm.payCoins || []).filter(v => String(v) !== String(value))
|
||||
},
|
||||
async handleOpenEdit() {
|
||||
const ok = await this.ensureGoogleStatusEnabledForWalletOp('修改店铺')
|
||||
if (!ok) return
|
||||
try {
|
||||
// 先打开弹窗,提供更快的视觉反馈
|
||||
this.visibleEdit = true
|
||||
@@ -839,7 +946,8 @@ export default {
|
||||
name: res.data.name,
|
||||
image: res.data.image,
|
||||
description: res.data.description,
|
||||
feeRate: res.data.feeRate
|
||||
feeRate: res.data.feeRate,
|
||||
gCode: ''
|
||||
}
|
||||
|
||||
|
||||
@@ -850,7 +958,8 @@ export default {
|
||||
name: this.shop.name,
|
||||
image: this.shop.image,
|
||||
description: this.shop.description,
|
||||
feeRate: this.shop.feeRate
|
||||
feeRate: this.shop.feeRate,
|
||||
gCode: ''
|
||||
}
|
||||
this.$message.warning(res && res.msg ? res.msg : '未获取到店铺详情')
|
||||
}
|
||||
@@ -861,7 +970,8 @@ export default {
|
||||
name: this.shop.name,
|
||||
image: this.shop.image,
|
||||
description: this.shop.description,
|
||||
feeRate: this.shop.feeRate
|
||||
feeRate: this.shop.feeRate,
|
||||
gCode: ''
|
||||
}
|
||||
console.error('查询店铺详情失败:', error)
|
||||
|
||||
@@ -918,7 +1028,14 @@ export default {
|
||||
}
|
||||
this.editForm.feeRate = rateNum.toString()
|
||||
|
||||
const payload = { ...this.editForm }
|
||||
// 谷歌验证码:必填 6 位数字
|
||||
const gCode = String(this.editForm.gCode || '').trim()
|
||||
if (!/^\d{6}$/.test(gCode)) {
|
||||
this.$message.warning('请输入6位谷歌验证码')
|
||||
return
|
||||
}
|
||||
|
||||
const payload = { ...this.editForm, gCode }
|
||||
const res = await updateShop(payload)
|
||||
if (res && (res.code === 0 || res.code === 200)) {
|
||||
this.$message({
|
||||
@@ -941,9 +1058,27 @@ export default {
|
||||
}
|
||||
},
|
||||
async handleDelete() {
|
||||
const ok = await this.ensureGoogleStatusEnabledForWalletOp('删除店铺')
|
||||
if (!ok) return
|
||||
try {
|
||||
await this.$confirm('确定删除该店铺吗?此操作不可恢复', '提示', { type: 'warning' })
|
||||
const res = await deleteShop(this.shop.id)
|
||||
const { value } = await this.$prompt(
|
||||
'删除店铺将不可恢复,请输入 6 位谷歌验证码确认删除',
|
||||
'安全验证',
|
||||
{
|
||||
confirmButtonText: '确认删除',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
inputPlaceholder: '6位数字验证码',
|
||||
inputPattern: /^\d{6}$/,
|
||||
inputErrorMessage: '谷歌验证码必须是6位数字'
|
||||
}
|
||||
)
|
||||
const gCode = String(value || '').trim()
|
||||
if (!/^\d{6}$/.test(gCode)) {
|
||||
this.$message.warning('谷歌验证码必须是6位数字')
|
||||
return
|
||||
}
|
||||
const res = await deleteShop(this.shop.id, gCode)
|
||||
if (res && (res.code === 0 || res.code === 200)) {
|
||||
this.$message({
|
||||
message: '删除成功',
|
||||
@@ -1074,6 +1209,51 @@ export default {
|
||||
/* 全局弹窗宽度微调(仅当前页面生效)*/
|
||||
.el-dialog__body .row { margin-bottom: 12px; }
|
||||
|
||||
/* 双重验证拦截弹窗 - 轻渐变美化(仅当前页面生效) */
|
||||
.google-2fa-guard-dialog {
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.google-2fa-guard-dialog .el-message-box__header {
|
||||
/* 与导航按钮同色系:#667eea -> #764ba2,降低透明度让其更淡 */
|
||||
background: linear-gradient(135deg, rgba(102, 126, 234, 0.16), rgba(118, 75, 162, 0.10));
|
||||
border-bottom: 1px solid rgba(102, 126, 234, 0.10);
|
||||
padding: 14px 16px 10px;
|
||||
}
|
||||
.google-2fa-guard-dialog .el-message-box__title {
|
||||
font-weight: 700;
|
||||
color: #1f2d3d;
|
||||
}
|
||||
.google-2fa-guard-dialog .el-message-box__content {
|
||||
padding: 14px 18px 6px;
|
||||
}
|
||||
.google-2fa-guard-dialog .el-message-box__message {
|
||||
color: #374151;
|
||||
line-height: 1.7;
|
||||
}
|
||||
.google-2fa-guard-dialog .google-2fa-guard__title {
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
color: #111827;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.google-2fa-guard-dialog .google-2fa-guard__desc {
|
||||
font-size: 13px;
|
||||
color: #4b5563;
|
||||
}
|
||||
.google-2fa-guard-dialog .el-message-box__btns {
|
||||
padding: 10px 16px 14px;
|
||||
}
|
||||
.google-2fa-guard-dialog .el-button--primary {
|
||||
border: none;
|
||||
/* 与导航按钮一致的紫色渐变 */
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
}
|
||||
.google-2fa-guard-dialog .el-button--primary:hover,
|
||||
.google-2fa-guard-dialog .el-button--primary:focus {
|
||||
filter: brightness(1.02);
|
||||
}
|
||||
|
||||
/* 弹窗表单统一对齐与留白优化 */
|
||||
.el-dialog__body .row {
|
||||
display: grid;
|
||||
|
||||
Reference in New Issue
Block a user