fix(operator): fix operator edit issue
All checks were successful
构建并部署前端到测试环境 / build-and-deploy (push) Successful in 4m51s
All checks were successful
构建并部署前端到测试环境 / build-and-deploy (push) Successful in 4m51s
This commit is contained in:
@@ -309,7 +309,7 @@ API Status (2) -> CommonStatus.DISABLED (0)
|
|||||||
- **网络错误**:axios 拦截器统一捕获,显示通用错误提示
|
- **网络错误**:axios 拦截器统一捕获,显示通用错误提示
|
||||||
- **401 未认证**:自动跳转到登录页面
|
- **401 未认证**:自动跳转到登录页面
|
||||||
- **403 无权限**:显示权限不足提示,不跳转
|
- **403 无权限**:显示权限不足提示,不跳转
|
||||||
- **400 业务错误**:根据错误信息显示具体提示(ElMessage.error)
|
- **400 业务错误**:根据错误信息显示具体提示()
|
||||||
- **表单验证错误**:在表单字段下显示错误提示
|
- **表单验证错误**:在表单字段下显示错误提示
|
||||||
|
|
||||||
**错误提示方式**:
|
**错误提示方式**:
|
||||||
|
|||||||
@@ -101,9 +101,14 @@ export class BaseService {
|
|||||||
* 获取单个资源
|
* 获取单个资源
|
||||||
* @param url 请求URL
|
* @param url 请求URL
|
||||||
* @param params 请求参数
|
* @param params 请求参数
|
||||||
|
* @param config 额外配置
|
||||||
*/
|
*/
|
||||||
protected static getOne<T>(url: string, params?: Record<string, any>): Promise<BaseResponse<T>> {
|
protected static getOne<T>(
|
||||||
return this.get<BaseResponse<T>>(url, params)
|
url: string,
|
||||||
|
params?: Record<string, any>,
|
||||||
|
config?: Record<string, any>
|
||||||
|
): Promise<BaseResponse<T>> {
|
||||||
|
return this.get<BaseResponse<T>>(url, params, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -38,7 +38,13 @@ export class AssetService extends BaseService {
|
|||||||
*/
|
*/
|
||||||
static getRealtimeStatus(identifier: string): Promise<BaseResponse<AssetRealtimeStatusResponse>> {
|
static getRealtimeStatus(identifier: string): Promise<BaseResponse<AssetRealtimeStatusResponse>> {
|
||||||
return this.getOne<AssetRealtimeStatusResponse>(
|
return this.getOne<AssetRealtimeStatusResponse>(
|
||||||
`/api/admin/assets/${identifier}/realtime-status`
|
`/api/admin/assets/${identifier}/realtime-status`,
|
||||||
|
undefined,
|
||||||
|
{
|
||||||
|
requestOptions: {
|
||||||
|
show404Error: false // 404时不显示错误提示
|
||||||
|
}
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,7 +73,12 @@ export class AssetService extends BaseService {
|
|||||||
): Promise<BaseResponse<AssetPackageListResponse>> {
|
): Promise<BaseResponse<AssetPackageListResponse>> {
|
||||||
return this.get<BaseResponse<AssetPackageListResponse>>(
|
return this.get<BaseResponse<AssetPackageListResponse>>(
|
||||||
`/api/admin/assets/${identifier}/packages`,
|
`/api/admin/assets/${identifier}/packages`,
|
||||||
params
|
params,
|
||||||
|
{
|
||||||
|
requestOptions: {
|
||||||
|
show404Error: false // 404时不显示错误提示
|
||||||
|
}
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,7 +90,13 @@ export class AssetService extends BaseService {
|
|||||||
*/
|
*/
|
||||||
static getCurrentPackage(identifier: string): Promise<BaseResponse<AssetCurrentPackageResponse>> {
|
static getCurrentPackage(identifier: string): Promise<BaseResponse<AssetCurrentPackageResponse>> {
|
||||||
return this.getOne<AssetCurrentPackageResponse>(
|
return this.getOne<AssetCurrentPackageResponse>(
|
||||||
`/api/admin/assets/${identifier}/current-package`
|
`/api/admin/assets/${identifier}/current-package`,
|
||||||
|
undefined,
|
||||||
|
{
|
||||||
|
requestOptions: {
|
||||||
|
show404Error: false // 404时不显示错误提示
|
||||||
|
}
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,7 +145,11 @@ export class AssetService extends BaseService {
|
|||||||
* @param identifier 资产标识符(ICCID 或 VirtualNo)
|
* @param identifier 资产标识符(ICCID 或 VirtualNo)
|
||||||
*/
|
*/
|
||||||
static getAssetWallet(identifier: string): Promise<BaseResponse<AssetWalletResponse>> {
|
static getAssetWallet(identifier: string): Promise<BaseResponse<AssetWalletResponse>> {
|
||||||
return this.getOne<AssetWalletResponse>(`/api/admin/assets/${identifier}/wallet`)
|
return this.getOne<AssetWalletResponse>(`/api/admin/assets/${identifier}/wallet`, undefined, {
|
||||||
|
requestOptions: {
|
||||||
|
show404Error: false // 404时不显示错误提示
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -184,7 +184,7 @@
|
|||||||
selectOptions.value = options
|
selectOptions.value = options
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('远程搜索失败:', error)
|
console.error('远程搜索失败:', error)
|
||||||
ElMessage.error('搜索失败,请重试')
|
console.log('搜索失败,请重试')
|
||||||
} finally {
|
} finally {
|
||||||
selectLoading.value = false
|
selectLoading.value = false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,7 +52,7 @@
|
|||||||
code = generateEnterpriseCode()
|
code = generateEnterpriseCode()
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
ElMessage.error('未知的编码类型')
|
console.log('未知的编码类型')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -244,7 +244,7 @@
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
ElMessage.error('获取客户账号列表失败')
|
console.log('获取客户账号列表失败')
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -198,13 +198,13 @@
|
|||||||
})
|
})
|
||||||
|
|
||||||
if (!isValidType) {
|
if (!isValidType) {
|
||||||
ElMessage.error(`只能上传 ${acceptText.value} 格式的文件`)
|
console.log(`只能上传 ${acceptText.value} 格式的文件`)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
const isLtSize = file.size / 1024 / 1024 < props.maxSize
|
const isLtSize = file.size / 1024 / 1024 < props.maxSize
|
||||||
if (!isLtSize) {
|
if (!isLtSize) {
|
||||||
ElMessage.error(`文件大小不能超过 ${props.maxSize}MB`)
|
console.log(`文件大小不能超过 ${props.maxSize}MB`)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -222,7 +222,7 @@
|
|||||||
|
|
||||||
const handleUploadError = () => {
|
const handleUploadError = () => {
|
||||||
uploading.value = false
|
uploading.value = false
|
||||||
ElMessage.error('导入失败')
|
console.log('导入失败')
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleConfirm = async () => {
|
const handleConfirm = async () => {
|
||||||
|
|||||||
@@ -68,7 +68,7 @@
|
|||||||
// 上传错误,或者触发 timeout 超时
|
// 上传错误,或者触发 timeout 超时
|
||||||
onError(file: File, err: any, res: any) {
|
onError(file: File, err: any, res: any) {
|
||||||
console.log(`上传出错`, err, res)
|
console.log(`上传出错`, err, res)
|
||||||
ElMessage.error('图片上传失败')
|
console.log('图片上传失败')
|
||||||
}
|
}
|
||||||
// 注意:返回格式需要按照指定格式返回,才能显示图片
|
// 注意:返回格式需要按照指定格式返回,才能显示图片
|
||||||
// 上传成功的返回格式:
|
// 上传成功的返回格式:
|
||||||
|
|||||||
@@ -330,7 +330,7 @@
|
|||||||
console.error('更新store失败:', error)
|
console.error('更新store失败:', error)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ElMessage.error(t('lockScreen.pwdError'))
|
console.log(t('lockScreen.pwdError'))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.error('表单验证失败:', fields)
|
console.error('表单验证失败:', fields)
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ export function useAgentManagement() {
|
|||||||
setTotal(res.data.total)
|
setTotal(res.data.total)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取代理商列表失败:', error)
|
console.error('获取代理商列表失败:', error)
|
||||||
ElMessage.error('获取代理商列表失败')
|
console.log('获取代理商列表失败')
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
@@ -54,7 +54,7 @@ export function useAgentManagement() {
|
|||||||
treeData.value = res.data
|
treeData.value = res.data
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取代理商树失败:', error)
|
console.error('获取代理商树失败:', error)
|
||||||
ElMessage.error('获取代理商树失败')
|
console.log('获取代理商树失败')
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
@@ -71,7 +71,7 @@ export function useAgentManagement() {
|
|||||||
return res.data
|
return res.data
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取代理商详情失败:', error)
|
console.error('获取代理商详情失败:', error)
|
||||||
ElMessage.error('获取代理商详情失败')
|
console.log('获取代理商详情失败')
|
||||||
return null
|
return null
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
@@ -90,7 +90,7 @@ export function useAgentManagement() {
|
|||||||
return true
|
return true
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('创建失败:', error)
|
console.error('创建失败:', error)
|
||||||
ElMessage.error('创建失败')
|
console.log('创建失败')
|
||||||
return false
|
return false
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
@@ -110,7 +110,7 @@ export function useAgentManagement() {
|
|||||||
return true
|
return true
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('更新失败:', error)
|
console.error('更新失败:', error)
|
||||||
ElMessage.error('更新失败')
|
console.log('更新失败')
|
||||||
return false
|
return false
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
@@ -130,7 +130,7 @@ export function useAgentManagement() {
|
|||||||
return true
|
return true
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('状态更新失败:', error)
|
console.error('状态更新失败:', error)
|
||||||
ElMessage.error('状态更新失败')
|
console.log('状态更新失败')
|
||||||
return false
|
return false
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
@@ -148,7 +148,7 @@ export function useAgentManagement() {
|
|||||||
return res.data
|
return res.data
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取下级代理失败:', error)
|
console.error('获取下级代理失败:', error)
|
||||||
ElMessage.error('获取下级代理失败')
|
console.log('获取下级代理失败')
|
||||||
return []
|
return []
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ export function useCardManagement() {
|
|||||||
setTotal(res.data.total)
|
setTotal(res.data.total)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取网卡列表失败:', error)
|
console.error('获取网卡列表失败:', error)
|
||||||
ElMessage.error('获取网卡列表失败')
|
console.log('获取网卡列表失败')
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
@@ -57,7 +57,7 @@ export function useCardManagement() {
|
|||||||
return res.data
|
return res.data
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取单卡信息失败:', error)
|
console.error('获取单卡信息失败:', error)
|
||||||
ElMessage.error('获取单卡信息失败')
|
console.log('获取单卡信息失败')
|
||||||
return null
|
return null
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
@@ -76,7 +76,7 @@ export function useCardManagement() {
|
|||||||
return true
|
return true
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('操作失败:', error)
|
console.error('操作失败:', error)
|
||||||
ElMessage.error('操作失败')
|
console.log('操作失败')
|
||||||
return false
|
return false
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
@@ -96,7 +96,7 @@ export function useCardManagement() {
|
|||||||
return true
|
return true
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('停机失败:', error)
|
console.error('停机失败:', error)
|
||||||
ElMessage.error('停机失败')
|
console.log('停机失败')
|
||||||
return false
|
return false
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
@@ -116,7 +116,7 @@ export function useCardManagement() {
|
|||||||
return true
|
return true
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('复机失败:', error)
|
console.error('复机失败:', error)
|
||||||
ElMessage.error('复机失败')
|
console.log('复机失败')
|
||||||
return false
|
return false
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
@@ -136,7 +136,7 @@ export function useCardManagement() {
|
|||||||
return true
|
return true
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('导入失败:', error)
|
console.error('导入失败:', error)
|
||||||
ElMessage.error('导入失败')
|
console.log('导入失败')
|
||||||
return false
|
return false
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ export function useLogin() {
|
|||||||
const loginResult = mockLogin(formData.username, formData.password)
|
const loginResult = mockLogin(formData.username, formData.password)
|
||||||
|
|
||||||
if (!loginResult) {
|
if (!loginResult) {
|
||||||
ElMessage.error(t('login.error.invalidCredentials'))
|
console.log(t('login.error.invalidCredentials'))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,7 +144,7 @@ export function useLogin() {
|
|||||||
const userInfo = mockGetUserInfo(loginResult.access_token)
|
const userInfo = mockGetUserInfo(loginResult.access_token)
|
||||||
|
|
||||||
if (!userInfo) {
|
if (!userInfo) {
|
||||||
ElMessage.error(t('login.error.getUserInfoFailed'))
|
console.log(t('login.error.getUserInfoFailed'))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,19 +175,19 @@ export function useLogin() {
|
|||||||
|
|
||||||
// 检查响应状态
|
// 检查响应状态
|
||||||
if (response.code !== ApiStatus.success) {
|
if (response.code !== ApiStatus.success) {
|
||||||
ElMessage.error(response.msg || t('login.error.invalidCredentials'))
|
console.log(response.msg || t('login.error.invalidCredentials'))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查返回数据
|
// 检查返回数据
|
||||||
if (!response.data || !response.data.access_token) {
|
if (!response.data || !response.data.access_token) {
|
||||||
ElMessage.error(t('login.error.loginFailed'))
|
console.log(t('login.error.loginFailed'))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查用户类型 - 禁止企业账号登录
|
// 检查用户类型 - 禁止企业账号登录
|
||||||
if (response.data.user && response.data.user.user_type === 4) {
|
if (response.data.user && response.data.user.user_type === 4) {
|
||||||
ElMessage.error('企业账号无法登录后台管理系统')
|
console.log('企业账号无法登录后台管理系统')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,7 +199,7 @@ export function useLogin() {
|
|||||||
userStore.setUserInfo(response.data.user)
|
userStore.setUserInfo(response.data.user)
|
||||||
userStore.setLoginStatus(true)
|
userStore.setLoginStatus(true)
|
||||||
} else {
|
} else {
|
||||||
ElMessage.error(t('login.error.getUserInfoFailed'))
|
console.log(t('login.error.getUserInfoFailed'))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ export interface RequestOptions {
|
|||||||
ignoreCancelToken?: boolean
|
ignoreCancelToken?: boolean
|
||||||
// 是否携带token
|
// 是否携带token
|
||||||
withToken?: boolean
|
withToken?: boolean
|
||||||
|
// 是否显示404错误提示(默认false,即默认不显示404错误)
|
||||||
|
show404Error?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
// 请求方法类型
|
// 请求方法类型
|
||||||
|
|||||||
@@ -212,13 +212,34 @@ function processRequestConfig(config: ExtendedRequestConfig): AxiosRequestConfig
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 处理错误消息
|
// 处理错误消息
|
||||||
function handleErrorMessage(error: any, mode: ErrorMessageMode = 'message') {
|
function handleErrorMessage(
|
||||||
|
error: any,
|
||||||
|
mode: ErrorMessageMode = 'message',
|
||||||
|
show404Error: boolean = true
|
||||||
|
) {
|
||||||
if (mode === 'none') return
|
if (mode === 'none') return
|
||||||
|
|
||||||
// 优先使用响应中的 msg 字段
|
const backendMessage = error.response?.data?.msg
|
||||||
const errorMessage = error.response?.data?.msg || error.message
|
const httpStatus = error.response?.status
|
||||||
const message = errorMessage || '请求超时或服务器异常!'
|
|
||||||
|
|
||||||
|
// 如果是404错误,且未配置显示404错误,则不显示任何提示
|
||||||
|
if (httpStatus === 404 && !show404Error) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果后端返回了错误信息,使用后端信息
|
||||||
|
if (backendMessage) {
|
||||||
|
if (mode === 'modal') {
|
||||||
|
// TODO: 可以使用 ElMessageBox 显示模态框
|
||||||
|
ElMessage.error(backendMessage)
|
||||||
|
} else {
|
||||||
|
ElMessage.error(backendMessage)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 其他错误显示通用提示
|
||||||
|
const message = '请求超时或服务器异常!'
|
||||||
if (mode === 'modal') {
|
if (mode === 'modal') {
|
||||||
// TODO: 可以使用 ElMessageBox 显示模态框
|
// TODO: 可以使用 ElMessageBox 显示模态框
|
||||||
ElMessage.error(message)
|
ElMessage.error(message)
|
||||||
@@ -251,7 +272,10 @@ async function request<T = any>(config: ExtendedRequestConfig): Promise<T> {
|
|||||||
if (axios.isAxiosError(e)) {
|
if (axios.isAxiosError(e)) {
|
||||||
// 默认显示错误消息,除非明确设置为 'none'
|
// 默认显示错误消息,除非明确设置为 'none'
|
||||||
const errorMode = config.requestOptions?.errorMessageMode || 'message'
|
const errorMode = config.requestOptions?.errorMessageMode || 'message'
|
||||||
handleErrorMessage(e, errorMode)
|
const show404Error = config.requestOptions?.show404Error !== undefined
|
||||||
|
? config.requestOptions.show404Error
|
||||||
|
: true
|
||||||
|
handleErrorMessage(e, errorMode, show404Error)
|
||||||
}
|
}
|
||||||
return Promise.reject(e)
|
return Promise.reject(e)
|
||||||
}
|
}
|
||||||
@@ -279,14 +303,6 @@ const api = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 退出登录(调用接口)
|
|
||||||
const logOut = () => {
|
|
||||||
ElMessage.error('登录已过期,请重新登录')
|
|
||||||
setTimeout(() => {
|
|
||||||
useUserStore().logOut()
|
|
||||||
}, 1000)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 仅清理本地状态(不调用接口)- 用于401等情况
|
// 仅清理本地状态(不调用接口)- 用于401等情况
|
||||||
const clearLocalStateAndRedirect = () => {
|
const clearLocalStateAndRedirect = () => {
|
||||||
ElMessage.error('登录已过期,请重新登录')
|
ElMessage.error('登录已过期,请重新登录')
|
||||||
|
|||||||
@@ -40,6 +40,7 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
|
import { useRoute } from 'vue-router'
|
||||||
import { ElCard, ElInput, ElButton } from 'element-plus'
|
import { ElCard, ElInput, ElButton } from 'element-plus'
|
||||||
import { Search, Refresh } from '@element-plus/icons-vue'
|
import { Search, Refresh } from '@element-plus/icons-vue'
|
||||||
import { useAssetFormatters } from '../composables/useAssetFormatters'
|
import { useAssetFormatters } from '../composables/useAssetFormatters'
|
||||||
@@ -47,6 +48,8 @@
|
|||||||
// Use formatters
|
// Use formatters
|
||||||
const { formatIccidWithDashes } = useAssetFormatters()
|
const { formatIccidWithDashes } = useAssetFormatters()
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
|
|
||||||
// Props
|
// Props
|
||||||
interface Props {
|
interface Props {
|
||||||
hasCardInfo?: boolean
|
hasCardInfo?: boolean
|
||||||
@@ -66,6 +69,26 @@
|
|||||||
const searchIccid = ref('')
|
const searchIccid = ref('')
|
||||||
const iccidInputFocused = ref(false)
|
const iccidInputFocused = ref(false)
|
||||||
|
|
||||||
|
// 从URL参数中获取初始值
|
||||||
|
const initializeFromQuery = () => {
|
||||||
|
const iccid = route.query.iccid as string
|
||||||
|
const virtualNo = route.query.virtual_no as string
|
||||||
|
const deviceNo = route.query.device_no as string
|
||||||
|
|
||||||
|
const identifier = iccid || virtualNo || deviceNo
|
||||||
|
if (identifier) {
|
||||||
|
searchIccid.value = identifier
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化时从URL参数加载
|
||||||
|
initializeFromQuery()
|
||||||
|
|
||||||
|
// 暴露方法供父组件调用,用于更新搜索框值
|
||||||
|
const updateSearchValue = (value: string) => {
|
||||||
|
searchIccid.value = value
|
||||||
|
}
|
||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
const handleSearch = () => {
|
const handleSearch = () => {
|
||||||
if (!searchIccid.value.trim()) {
|
if (!searchIccid.value.trim()) {
|
||||||
@@ -77,6 +100,11 @@
|
|||||||
const handleRefresh = () => {
|
const handleRefresh = () => {
|
||||||
emit('refresh')
|
emit('refresh')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 暴露给父组件
|
||||||
|
defineExpose({
|
||||||
|
updateSearchValue
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|||||||
@@ -477,9 +477,10 @@
|
|||||||
(e: 'resetDevice'): void
|
(e: 'resetDevice'): void
|
||||||
(e: 'showSpeedLimit'): void
|
(e: 'showSpeedLimit'): void
|
||||||
(e: 'showSwitchCard'): void
|
(e: 'showSwitchCard'): void
|
||||||
(e: 'showSetWiFi'): void
|
(e: 'show-set-wifi'): void
|
||||||
(e: 'enableBindingCard', payload: { card: BindingCard }): void
|
(e: 'enableBindingCard', payload: { card: BindingCard }): void
|
||||||
(e: 'disableBindingCard', payload: { card: BindingCard }): void
|
(e: 'disableBindingCard', payload: { card: BindingCard }): void
|
||||||
|
(e: 'navigateToCard', iccid: string): void
|
||||||
}
|
}
|
||||||
|
|
||||||
const emit = defineEmits<Emits>()
|
const emit = defineEmits<Emits>()
|
||||||
@@ -528,8 +529,8 @@
|
|||||||
|
|
||||||
// 跳转到卡片信息
|
// 跳转到卡片信息
|
||||||
const handleNavigateToCardInfo = (iccid: string) => {
|
const handleNavigateToCardInfo = (iccid: string) => {
|
||||||
// 可以通过路由跳转或触发搜索
|
// 触发搜索事件,让父组件处理
|
||||||
console.log('Navigate to card:', iccid)
|
emit('navigateToCard', iccid)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 卡操作
|
// 卡操作
|
||||||
@@ -559,7 +560,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleShowSetWiFi = () => {
|
const handleShowSetWiFi = () => {
|
||||||
emit('showSetWiFi')
|
emit('show-set-wifi')
|
||||||
}
|
}
|
||||||
|
|
||||||
// 绑定卡操作
|
// 绑定卡操作
|
||||||
|
|||||||
@@ -69,27 +69,27 @@
|
|||||||
.wallet-balance-cards {
|
.wallet-balance-cards {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 8px;
|
gap: 12px;
|
||||||
|
|
||||||
.balance-card {
|
.balance-card {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 10px;
|
gap: 14px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 10px 14px;
|
padding: 16px 18px;
|
||||||
background: var(--el-fill-color-light);
|
background: var(--el-fill-color-light);
|
||||||
border: 1px solid var(--el-border-color-lighter);
|
border: 1px solid var(--el-border-color-lighter);
|
||||||
border-radius: 4px;
|
border-radius: 6px;
|
||||||
transition: all 0.3s ease;
|
transition: all 0.3s ease;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
border-color: var(--el-color-primary);
|
border-color: var(--el-color-primary);
|
||||||
box-shadow: 0 2px 6px rgb(0 0 0 / 6%);
|
box-shadow: 0 2px 8px rgb(0 0 0 / 8%);
|
||||||
transform: translateX(2px);
|
transform: translateX(2px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.balance-icon {
|
.balance-icon {
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
font-size: 20px;
|
font-size: 26px;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,16 +97,18 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 2px;
|
gap: 4px;
|
||||||
|
|
||||||
.balance-label {
|
.balance-label {
|
||||||
font-size: 12px;
|
font-size: 11px;
|
||||||
|
font-weight: 500;
|
||||||
color: var(--el-text-color-secondary);
|
color: var(--el-text-color-secondary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.balance-value {
|
.balance-value {
|
||||||
font-size: 18px;
|
font-size: 20px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
|
line-height: 1.2;
|
||||||
color: var(--el-text-color-primary);
|
color: var(--el-text-color-primary);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,10 +25,9 @@
|
|||||||
start-placeholder="开始时间"
|
start-placeholder="开始时间"
|
||||||
end-placeholder="结束时间"
|
end-placeholder="结束时间"
|
||||||
style="width: 360px"
|
style="width: 360px"
|
||||||
@change="handleDateChange"
|
|
||||||
/>
|
/>
|
||||||
<ElButton type="primary" @click="handleFilterChange">查询</ElButton>
|
<ElButton type="primary" @click="handleQuery">查询</ElButton>
|
||||||
<ElButton @click="handleResetFilter">重置</ElButton>
|
<ElButton @click="handleReset">重置</ElButton>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -194,28 +193,26 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理日期范围变化
|
// 处理查询按钮点击
|
||||||
const handleDateChange = (value: [Date, Date] | null) => {
|
const handleQuery = () => {
|
||||||
if (value && value.length === 2) {
|
queryParams.value.page = 1
|
||||||
// 转换为 RFC3339 格式
|
pagination.value.page = 1
|
||||||
queryParams.value.start_time = value[0].toISOString()
|
queryParams.value.transaction_type = filterForm.value.transaction_type
|
||||||
queryParams.value.end_time = value[1].toISOString()
|
|
||||||
|
// 处理日期范围
|
||||||
|
if (filterForm.value.date_range && filterForm.value.date_range.length === 2) {
|
||||||
|
queryParams.value.start_time = filterForm.value.date_range[0].toISOString()
|
||||||
|
queryParams.value.end_time = filterForm.value.date_range[1].toISOString()
|
||||||
} else {
|
} else {
|
||||||
queryParams.value.start_time = null
|
queryParams.value.start_time = null
|
||||||
queryParams.value.end_time = null
|
queryParams.value.end_time = null
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// 处理筛选条件变化
|
|
||||||
const handleFilterChange = () => {
|
|
||||||
queryParams.value.page = 1
|
|
||||||
pagination.value.page = 1
|
|
||||||
queryParams.value.transaction_type = filterForm.value.transaction_type
|
|
||||||
loadTransactions()
|
loadTransactions()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 重置筛选条件
|
// 处理重置按钮点击
|
||||||
const handleResetFilter = () => {
|
const handleReset = () => {
|
||||||
filterForm.value = {
|
filterForm.value = {
|
||||||
transaction_type: null,
|
transaction_type: null,
|
||||||
date_range: null
|
date_range: null
|
||||||
@@ -254,7 +251,7 @@
|
|||||||
(newVal) => {
|
(newVal) => {
|
||||||
if (newVal) {
|
if (newVal) {
|
||||||
// 重置状态
|
// 重置状态
|
||||||
handleResetFilter()
|
handleReset()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
|
|||||||
@@ -144,7 +144,7 @@
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('加载流量详单失败:', error)
|
console.error('加载流量详单失败:', error)
|
||||||
ElMessage.error('加载流量详单失败')
|
console.log('加载流量详单失败')
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -194,7 +194,7 @@
|
|||||||
}
|
}
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error('加载往期订单失败:', error)
|
console.error('加载往期订单失败:', error)
|
||||||
ElMessage.error(error?.message || '加载往期订单失败')
|
console.log(error?.message || '加载往期订单失败')
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -141,7 +141,7 @@
|
|||||||
}
|
}
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error('加载套餐列表失败:', error)
|
console.error('加载套餐列表失败:', error)
|
||||||
ElMessage.error(error?.message || '加载套餐列表失败')
|
console.log(error?.message || '加载套餐列表失败')
|
||||||
} finally {
|
} finally {
|
||||||
packageSearchLoading.value = false
|
packageSearchLoading.value = false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -138,7 +138,7 @@
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('加载设备绑定卡列表失败:', error)
|
console.error('加载设备绑定卡列表失败:', error)
|
||||||
ElMessage.error('加载卡列表失败')
|
console.log('加载卡列表失败')
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<ElDialog v-model="visible" title="设置WiFi" width="500px">
|
<ElDialog v-model="visible" title="设置WiFi" width="500px" :append-to-body="true">
|
||||||
<ElForm ref="formRef" :model="form" :rules="rules" label-width="120px">
|
<ElForm ref="formRef" :model="form" :rules="rules" label-width="120px">
|
||||||
<ElFormItem label="WiFi状态" prop="enabled">
|
<ElFormItem label="WiFi状态" prop="enabled">
|
||||||
<ElRadioGroup v-model="form.enabled">
|
<ElRadioGroup v-model="form.enabled">
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
import { AssetService } from '@/api/modules'
|
import { AssetService } from '@/api/modules'
|
||||||
import type { AssetWalletResponse } from '@/types/api'
|
import type { AssetWalletResponse, DeviceGatewayInfo, AssetPackageUsageRecord } from '@/types/api'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 格式化数据大小(MB -> GB/MB)
|
* 格式化数据大小(MB -> GB/MB)
|
||||||
@@ -22,11 +22,11 @@ export function useAssetInfo() {
|
|||||||
// 状态管理
|
// 状态管理
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const cardInfo = ref<any>(null) // 使用 any 以保持与原始实现一致
|
const cardInfo = ref<any>(null) // 使用 any 以保持与原始实现一致
|
||||||
const deviceRealtime = ref<DeviceRealtimeInfo | null>(null)
|
const deviceRealtime = ref<DeviceGatewayInfo | null>(null)
|
||||||
const currentPackage = ref<PackageInfo | null>(null)
|
const currentPackage = ref<AssetPackageUsageRecord | null>(null)
|
||||||
const currentPackageLoading = ref(false)
|
const currentPackageLoading = ref(false)
|
||||||
const currentPackageErrorMsg = ref('')
|
const currentPackageErrorMsg = ref('')
|
||||||
const packageList = ref<PackageInfo[]>([])
|
const packageList = ref<AssetPackageUsageRecord[]>([])
|
||||||
const walletInfo = ref<AssetWalletResponse | null>(null)
|
const walletInfo = ref<AssetWalletResponse | null>(null)
|
||||||
const walletLoading = ref(false)
|
const walletLoading = ref(false)
|
||||||
|
|
||||||
@@ -111,7 +111,7 @@ export function useAssetInfo() {
|
|||||||
const assetIdentifier = data.asset_type === 'card' ? data.iccid : data.virtual_no
|
const assetIdentifier = data.asset_type === 'card' ? data.iccid : data.virtual_no
|
||||||
if (assetIdentifier) {
|
if (assetIdentifier) {
|
||||||
// 并行调用多个接口: 当前生效套餐、套餐列表、实时状态、钱包概况
|
// 并行调用多个接口: 当前生效套餐、套餐列表、实时状态、钱包概况
|
||||||
Promise.all([
|
await Promise.all([
|
||||||
loadCurrentPackage(assetIdentifier),
|
loadCurrentPackage(assetIdentifier),
|
||||||
loadPackageList(assetIdentifier),
|
loadPackageList(assetIdentifier),
|
||||||
loadRealtimeStatus(assetIdentifier, data.asset_type),
|
loadRealtimeStatus(assetIdentifier, data.asset_type),
|
||||||
@@ -319,11 +319,9 @@ export function useAssetInfo() {
|
|||||||
await loadRealtimeStatus(identifier, assetType)
|
await loadRealtimeStatus(identifier, assetType)
|
||||||
}
|
}
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
// 检查429错误(冷却期)
|
// 检查 429 错误(冷却期)
|
||||||
if (error?.response?.status === 429) {
|
if (error?.response?.status === 429) {
|
||||||
ElMessage.warning('刷新过于频繁,请稍后再试')
|
ElMessage.warning('刷新过于频繁,请稍后再试')
|
||||||
} else {
|
|
||||||
ElMessage.error(error?.message || '刷新失败')
|
|
||||||
}
|
}
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ export function useAssetOperations(cardInfo: Ref<any>, refreshAssetFn?: () => Pr
|
|||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
if (error !== 'cancel') {
|
if (error !== 'cancel') {
|
||||||
console.error('手动停用失败:', error)
|
console.error('手动停用失败:', error)
|
||||||
ElMessage.error(error?.message || '手动停用失败')
|
console.log(error?.message || '手动停用失败')
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
manualDeactivateCardLoading.value = false
|
manualDeactivateCardLoading.value = false
|
||||||
@@ -186,7 +186,7 @@ export function useAssetOperations(cardInfo: Ref<any>, refreshAssetFn?: () => Pr
|
|||||||
}
|
}
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error('设置限速失败:', error)
|
console.error('设置限速失败:', error)
|
||||||
ElMessage.error(error?.message || '设置失败')
|
console.log(error?.message || '设置失败')
|
||||||
return false
|
return false
|
||||||
} finally {
|
} finally {
|
||||||
speedLimitLoading.value = false
|
speedLimitLoading.value = false
|
||||||
@@ -214,7 +214,7 @@ export function useAssetOperations(cardInfo: Ref<any>, refreshAssetFn?: () => Pr
|
|||||||
}
|
}
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error('切换SIM卡失败:', error)
|
console.error('切换SIM卡失败:', error)
|
||||||
ElMessage.error(error?.message || '切换失败')
|
console.log(error?.message || '切换失败')
|
||||||
return false
|
return false
|
||||||
} finally {
|
} finally {
|
||||||
switchCardLoading.value = false
|
switchCardLoading.value = false
|
||||||
@@ -244,7 +244,7 @@ export function useAssetOperations(cardInfo: Ref<any>, refreshAssetFn?: () => Pr
|
|||||||
}
|
}
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error('设置WiFi失败:', error)
|
console.error('设置WiFi失败:', error)
|
||||||
ElMessage.error(error?.message || '设置WiFi失败')
|
console.log(error?.message || '设置WiFi失败')
|
||||||
return false
|
return false
|
||||||
} finally {
|
} finally {
|
||||||
setWiFiLoading.value = false
|
setWiFiLoading.value = false
|
||||||
@@ -282,7 +282,7 @@ export function useAssetOperations(cardInfo: Ref<any>, refreshAssetFn?: () => Pr
|
|||||||
}
|
}
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error('更新轮询状态失败:', error)
|
console.error('更新轮询状态失败:', error)
|
||||||
ElMessage.error(error?.message || '更新轮询状态失败')
|
console.log(error?.message || '更新轮询状态失败')
|
||||||
return false
|
return false
|
||||||
} finally {
|
} finally {
|
||||||
pollingLoading.value = false
|
pollingLoading.value = false
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="single-card-page">
|
<div class="single-card-page">
|
||||||
<!-- 资产查询区域 -->
|
<!-- 资产查询区域 -->
|
||||||
<AssetSearchCard :has-card-info="!!cardInfo" @search="handleSearch" @refresh="handleRefresh" />
|
<AssetSearchCard
|
||||||
|
ref="assetSearchCardRef"
|
||||||
|
:has-card-info="!!cardInfo"
|
||||||
|
@search="handleSearch"
|
||||||
|
@refresh="handleRefresh"
|
||||||
|
/>
|
||||||
|
|
||||||
<!-- 卡片内容区域 -->
|
<!-- 卡片内容区域 -->
|
||||||
<div v-if="cardInfo" class="card-content-area slide-in">
|
<div v-if="cardInfo" class="card-content-area slide-in">
|
||||||
@@ -21,6 +26,7 @@
|
|||||||
@show-set-wifi="showSetWiFiDialog"
|
@show-set-wifi="showSetWiFiDialog"
|
||||||
@enable-binding-card="handleEnableBindingCard"
|
@enable-binding-card="handleEnableBindingCard"
|
||||||
@disable-binding-card="handleDisableBindingCard"
|
@disable-binding-card="handleDisableBindingCard"
|
||||||
|
@navigate-to-card="handleNavigateToCard"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -120,6 +126,9 @@
|
|||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
|
||||||
|
// ========== 组件引用 ==========
|
||||||
|
const assetSearchCardRef = ref<InstanceType<typeof AssetSearchCard>>()
|
||||||
|
|
||||||
// ========== 核心数据状态(使用 composable) ==========
|
// ========== 核心数据状态(使用 composable) ==========
|
||||||
const {
|
const {
|
||||||
cardInfo,
|
cardInfo,
|
||||||
@@ -174,16 +183,11 @@
|
|||||||
* 处理资产搜索
|
* 处理资产搜索
|
||||||
*/
|
*/
|
||||||
const handleSearch = async ({ identifier }: { identifier: string }) => {
|
const handleSearch = async ({ identifier }: { identifier: string }) => {
|
||||||
|
// 更新搜索框的值
|
||||||
|
assetSearchCardRef.value?.updateSearchValue(identifier)
|
||||||
|
|
||||||
|
// fetchAssetDetail 内部已经会并行加载所有相关数据,不需要重复调用
|
||||||
await fetchAssetDetail(identifier)
|
await fetchAssetDetail(identifier)
|
||||||
if (cardInfo.value) {
|
|
||||||
// 并行加载相关数据
|
|
||||||
await Promise.all([
|
|
||||||
loadPackageList(cardInfo.value.identifier),
|
|
||||||
loadCurrentPackage(cardInfo.value.identifier),
|
|
||||||
loadRealtimeStatus(cardInfo.value.identifier, cardInfo.value.asset_type),
|
|
||||||
loadAssetWallet(cardInfo.value.identifier)
|
|
||||||
])
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -269,19 +273,35 @@
|
|||||||
/**
|
/**
|
||||||
* 绑定卡操作 - 启用绑定卡
|
* 绑定卡操作 - 启用绑定卡
|
||||||
*/
|
*/
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
const handleEnableBindingCard = async (payload: { card: any }) => {
|
||||||
const handleEnableBindingCard = async (_card: any) => {
|
const { card } = payload
|
||||||
// TODO: 实现启用绑定卡逻辑
|
try {
|
||||||
ElMessage.info('启用绑定卡功能待实现')
|
const { CardService } = await import('@/api/modules')
|
||||||
|
await CardService.enableIotCard(card.iccid)
|
||||||
|
ElMessage.success('启用成功')
|
||||||
|
// 刷新资产信息
|
||||||
|
await handleRefresh()
|
||||||
|
} catch (error: any) {
|
||||||
|
console.error('启用绑定卡失败:', error)
|
||||||
|
ElMessage.error(error?.message || '启用失败')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 绑定卡操作 - 停用绑定卡
|
* 绑定卡操作 - 停用绑定卡
|
||||||
*/
|
*/
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
const handleDisableBindingCard = async (payload: { card: any }) => {
|
||||||
const handleDisableBindingCard = async (_card: any) => {
|
const { card } = payload
|
||||||
// TODO: 实现停用绑定卡逻辑
|
try {
|
||||||
ElMessage.info('停用绑定卡功能待实现')
|
const { CardService } = await import('@/api/modules')
|
||||||
|
await CardService.disableIotCard(card.iccid)
|
||||||
|
ElMessage.success('停用成功')
|
||||||
|
// 刷新资产信息
|
||||||
|
await handleRefresh()
|
||||||
|
} catch (error: any) {
|
||||||
|
console.error('停用绑定卡失败:', error)
|
||||||
|
ElMessage.error(error?.message || '停用失败')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -314,6 +334,13 @@
|
|||||||
dailyRecordsDialogVisible.value = true
|
dailyRecordsDialogVisible.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 跳转到绑定卡信息
|
||||||
|
*/
|
||||||
|
const handleNavigateToCard = async (iccid: string) => {
|
||||||
|
await handleSearch({ identifier: iccid })
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* URL参数自动加载
|
* URL参数自动加载
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -583,7 +583,7 @@
|
|||||||
getEnterpriseInfo()
|
getEnterpriseInfo()
|
||||||
getTableData()
|
getTableData()
|
||||||
} else {
|
} else {
|
||||||
ElMessage.error('缺少企业ID')
|
console.log('缺少企业ID')
|
||||||
goBack()
|
goBack()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -631,7 +631,7 @@
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
ElMessage.error('获取企业卡列表失败')
|
console.log('获取企业卡列表失败')
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
@@ -811,7 +811,7 @@
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
ElMessage.error('获取卡列表失败')
|
console.log('获取卡列表失败')
|
||||||
} finally {
|
} finally {
|
||||||
availableCardsLoading.value = false
|
availableCardsLoading.value = false
|
||||||
}
|
}
|
||||||
@@ -889,7 +889,7 @@
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
ElMessage.error('授权失败')
|
console.log('授权失败')
|
||||||
} finally {
|
} finally {
|
||||||
allocateLoading.value = false
|
allocateLoading.value = false
|
||||||
}
|
}
|
||||||
@@ -939,7 +939,7 @@
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
ElMessage.error('回收失败')
|
console.log('回收失败')
|
||||||
} finally {
|
} finally {
|
||||||
recallLoading.value = false
|
recallLoading.value = false
|
||||||
}
|
}
|
||||||
@@ -1023,7 +1023,7 @@
|
|||||||
getTableData()
|
getTableData()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
ElMessage.error('停机失败')
|
console.log('停机失败')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(() => {})
|
.catch(() => {})
|
||||||
@@ -1043,7 +1043,7 @@
|
|||||||
getTableData()
|
getTableData()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
ElMessage.error('复机失败')
|
console.log('复机失败')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(() => {})
|
.catch(() => {})
|
||||||
|
|||||||
@@ -157,11 +157,7 @@
|
|||||||
</ElDialog>
|
</ElDialog>
|
||||||
|
|
||||||
<!-- 结果对话框 -->
|
<!-- 结果对话框 -->
|
||||||
<ElDialog
|
<ElDialog v-model="resultDialogVisible" title="操作结果" width="700px">
|
||||||
v-model="resultDialogVisible"
|
|
||||||
title="操作结果"
|
|
||||||
width="700px"
|
|
||||||
>
|
|
||||||
<ElDescriptions :column="2" border>
|
<ElDescriptions :column="2" border>
|
||||||
<ElDescriptionsItem label="成功数量">
|
<ElDescriptionsItem label="成功数量">
|
||||||
<ElTag type="success">{{ operationResult.success_count }}</ElTag>
|
<ElTag type="success">{{ operationResult.success_count }}</ElTag>
|
||||||
@@ -178,11 +174,7 @@
|
|||||||
>
|
>
|
||||||
<ElDivider content-position="left">失败项</ElDivider>
|
<ElDivider content-position="left">失败项</ElDivider>
|
||||||
<ElTable :data="operationResult.failed_items" border max-height="300">
|
<ElTable :data="operationResult.failed_items" border max-height="300">
|
||||||
<ElTableColumn
|
<ElTableColumn prop="virtual_no" label="设备号" width="180" />
|
||||||
prop="virtual_no"
|
|
||||||
label="设备号"
|
|
||||||
width="180"
|
|
||||||
/>
|
|
||||||
<ElTableColumn prop="reason" label="失败原因" />
|
<ElTableColumn prop="reason" label="失败原因" />
|
||||||
</ElTable>
|
</ElTable>
|
||||||
</div>
|
</div>
|
||||||
@@ -196,16 +188,8 @@
|
|||||||
>
|
>
|
||||||
<ElDivider content-position="left">已授权设备</ElDivider>
|
<ElDivider content-position="left">已授权设备</ElDivider>
|
||||||
<ElTable :data="operationResult.authorized_devices" border max-height="200">
|
<ElTable :data="operationResult.authorized_devices" border max-height="200">
|
||||||
<ElTableColumn
|
<ElTableColumn prop="virtual_no" label="设备号" width="180" />
|
||||||
prop="virtual_no"
|
<ElTableColumn prop="device_id" label="设备ID" width="100" />
|
||||||
label="设备号"
|
|
||||||
width="180"
|
|
||||||
/>
|
|
||||||
<ElTableColumn
|
|
||||||
prop="device_id"
|
|
||||||
label="设备ID"
|
|
||||||
width="100"
|
|
||||||
/>
|
|
||||||
<ElTableColumn label="绑定卡数">
|
<ElTableColumn label="绑定卡数">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
{{ row.card_count || 0 }}
|
{{ row.card_count || 0 }}
|
||||||
@@ -756,7 +740,7 @@
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
ElMessage.error('撤销授权失败')
|
console.logr('撤销授权失败')
|
||||||
} finally {
|
} finally {
|
||||||
recallLoading.value = false
|
recallLoading.value = false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,7 +63,9 @@
|
|||||||
<p>4. <strong>重要:列顺序固定,不可调整。</strong>系统按位置读取,不识别列名</p>
|
<p>4. <strong>重要:列顺序固定,不可调整。</strong>系统按位置读取,不识别列名</p>
|
||||||
<p>5. 必填列:虚拟号(第1列)</p>
|
<p>5. 必填列:虚拟号(第1列)</p>
|
||||||
<p
|
<p
|
||||||
>6. 可选列:设备名称、设备型号、设备类型、IMEI、制造商、最大SIM槽数(默认4,有效范围1-4)、卡1~卡4 ICCID</p
|
>6.
|
||||||
|
可选列:设备名称、设备型号、设备类型、IMEI、制造商、最大SIM槽数(默认4,有效范围1-4)、卡1~卡4
|
||||||
|
ICCID</p
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -566,7 +568,7 @@
|
|||||||
})
|
})
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error('设备导入失败:', error)
|
console.error('设备导入失败:', error)
|
||||||
ElMessage.error(error.message || '设备导入失败')
|
console.log(error.message || '设备导入失败')
|
||||||
} finally {
|
} finally {
|
||||||
uploading.value = false
|
uploading.value = false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -775,7 +775,7 @@
|
|||||||
})
|
})
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error('IoT卡导入失败:', error)
|
console.error('IoT卡导入失败:', error)
|
||||||
ElMessage.error(error.message || 'IoT卡导入失败')
|
console.log(error.message || 'IoT卡导入失败')
|
||||||
} finally {
|
} finally {
|
||||||
uploading.value = false
|
uploading.value = false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -622,7 +622,7 @@
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
ElMessage.error('获取数据失败')
|
console.log('获取数据失败')
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
@@ -736,7 +736,7 @@
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
ElMessage.error('获取佣金明细失败')
|
console.log('获取佣金明细失败')
|
||||||
} finally {
|
} finally {
|
||||||
commissionLoading.value = false
|
commissionLoading.value = false
|
||||||
}
|
}
|
||||||
@@ -773,7 +773,7 @@
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
ElMessage.error('获取提现记录失败')
|
console.log('获取提现记录失败')
|
||||||
} finally {
|
} finally {
|
||||||
withdrawalLoading.value = false
|
withdrawalLoading.value = false
|
||||||
}
|
}
|
||||||
@@ -810,7 +810,7 @@
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
ElMessage.error('获取预充值钱包流水失败')
|
console.log('获取预充值钱包流水失败')
|
||||||
} finally {
|
} finally {
|
||||||
mainWalletLoading.value = false
|
mainWalletLoading.value = false
|
||||||
}
|
}
|
||||||
@@ -878,10 +878,10 @@
|
|||||||
resolveFormRef.value?.resetFields()
|
resolveFormRef.value?.resetFields()
|
||||||
|
|
||||||
// 刷新佣金明细列表
|
// 刷新佣金明细列表
|
||||||
loadCommissionRecords()
|
await loadCommissionRecords()
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
ElMessage.error(error?.message || `${actionText}失败`)
|
console.log(error?.message || `${actionText}失败`)
|
||||||
} finally {
|
} finally {
|
||||||
resolveSubmitLoading.value = false
|
resolveSubmitLoading.value = false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -429,7 +429,7 @@
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
ElMessage.error('获取账号列表失败')
|
console.log('获取账号列表失败')
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
@@ -544,7 +544,7 @@
|
|||||||
getTableData()
|
getTableData()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
ElMessage.error('添加账号失败')
|
console.log('添加账号失败')
|
||||||
} finally {
|
} finally {
|
||||||
submitLoading.value = false
|
submitLoading.value = false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,10 @@
|
|||||||
</template>
|
</template>
|
||||||
<div class="stats-grid">
|
<div class="stats-grid">
|
||||||
<div class="stat-card">
|
<div class="stat-card">
|
||||||
<div class="stat-icon" style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%)">
|
<div
|
||||||
|
class="stat-icon"
|
||||||
|
style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%)"
|
||||||
|
>
|
||||||
<el-icon :size="24"><Document /></el-icon>
|
<el-icon :size="24"><Document /></el-icon>
|
||||||
</div>
|
</div>
|
||||||
<div class="stat-content">
|
<div class="stat-content">
|
||||||
@@ -22,41 +25,60 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="stat-card">
|
<div class="stat-card">
|
||||||
<div class="stat-icon" style="background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%)">
|
<div
|
||||||
|
class="stat-icon"
|
||||||
|
style="background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%)"
|
||||||
|
>
|
||||||
<el-icon :size="24"><CircleCheck /></el-icon>
|
<el-icon :size="24"><CircleCheck /></el-icon>
|
||||||
</div>
|
</div>
|
||||||
<div class="stat-content">
|
<div class="stat-content">
|
||||||
<div class="stat-label">已初始化</div>
|
<div class="stat-label">已初始化</div>
|
||||||
<div class="stat-value">
|
<div class="stat-value">
|
||||||
{{ overviewStats?.initialized_cards?.toLocaleString() || 0 }} / {{ overviewStats?.total_cards?.toLocaleString() || 0 }}
|
{{ overviewStats?.initialized_cards?.toLocaleString() || 0 }} /
|
||||||
|
{{ overviewStats?.total_cards?.toLocaleString() || 0 }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="stat-card">
|
<div class="stat-card">
|
||||||
<div class="stat-icon" style="background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)">
|
<div
|
||||||
|
class="stat-icon"
|
||||||
|
style="background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)"
|
||||||
|
>
|
||||||
<el-icon :size="24"><User /></el-icon>
|
<el-icon :size="24"><User /></el-icon>
|
||||||
</div>
|
</div>
|
||||||
<div class="stat-content">
|
<div class="stat-content">
|
||||||
<div class="stat-label">实名队列</div>
|
<div class="stat-label">实名队列</div>
|
||||||
<div class="stat-value">{{ overviewStats?.realname_queue_size?.toLocaleString() || 0 }}</div>
|
<div class="stat-value">{{
|
||||||
|
overviewStats?.realname_queue_size?.toLocaleString() || 0
|
||||||
|
}}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="stat-card">
|
<div class="stat-card">
|
||||||
<div class="stat-icon" style="background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%)">
|
<div
|
||||||
|
class="stat-icon"
|
||||||
|
style="background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%)"
|
||||||
|
>
|
||||||
<el-icon :size="24"><Box /></el-icon>
|
<el-icon :size="24"><Box /></el-icon>
|
||||||
</div>
|
</div>
|
||||||
<div class="stat-content">
|
<div class="stat-content">
|
||||||
<div class="stat-label">套餐队列</div>
|
<div class="stat-label">套餐队列</div>
|
||||||
<div class="stat-value">{{ overviewStats?.package_queue_size?.toLocaleString() || 0 }}</div>
|
<div class="stat-value">{{
|
||||||
|
overviewStats?.package_queue_size?.toLocaleString() || 0
|
||||||
|
}}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="stat-card">
|
<div class="stat-card">
|
||||||
<div class="stat-icon" style="background: linear-gradient(135deg, #fa709a 0%, #fee140 100%)">
|
<div
|
||||||
|
class="stat-icon"
|
||||||
|
style="background: linear-gradient(135deg, #fa709a 0%, #fee140 100%)"
|
||||||
|
>
|
||||||
<el-icon :size="24"><DataLine /></el-icon>
|
<el-icon :size="24"><DataLine /></el-icon>
|
||||||
</div>
|
</div>
|
||||||
<div class="stat-content">
|
<div class="stat-content">
|
||||||
<div class="stat-label">流量队列</div>
|
<div class="stat-label">流量队列</div>
|
||||||
<div class="stat-value">{{ overviewStats?.carddata_queue_size?.toLocaleString() || 0 }}</div>
|
<div class="stat-value">{{
|
||||||
|
overviewStats?.carddata_queue_size?.toLocaleString() || 0
|
||||||
|
}}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -82,7 +104,7 @@
|
|||||||
const { data } = await PollingMonitorService.getOverviewStats()
|
const { data } = await PollingMonitorService.getOverviewStats()
|
||||||
overviewStats.value = data
|
overviewStats.value = data
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
ElMessage.error('加载轮询统计失败')
|
console.log('加载轮询统计失败')
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -169,7 +169,7 @@
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
ElMessage.error('加载失败')
|
console.log('加载失败')
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -234,7 +234,7 @@
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
ElMessage.error('获取订单详情失败')
|
console.log('获取订单详情失败')
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -284,7 +284,13 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { h } from 'vue'
|
import { h } from 'vue'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import { OrderService, CardService, DeviceService, PackageManageService, StorageService } from '@/api/modules'
|
import {
|
||||||
|
OrderService,
|
||||||
|
CardService,
|
||||||
|
DeviceService,
|
||||||
|
PackageManageService,
|
||||||
|
StorageService
|
||||||
|
} from '@/api/modules'
|
||||||
import { ElMessage, ElMessageBox, ElTag } from 'element-plus'
|
import { ElMessage, ElMessageBox, ElTag } from 'element-plus'
|
||||||
import { Plus } from '@element-plus/icons-vue'
|
import { Plus } from '@element-plus/icons-vue'
|
||||||
import type { FormInstance, FormRules, UploadInstance, UploadFile } from 'element-plus'
|
import type { FormInstance, FormRules, UploadInstance, UploadFile } from 'element-plus'
|
||||||
@@ -477,7 +483,7 @@
|
|||||||
ElMessage.success('上传成功')
|
ElMessage.success('上传成功')
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error('上传失败:', error)
|
console.error('上传失败:', error)
|
||||||
ElMessage.error(error.message || '上传失败,请重试')
|
console.log(error.message || '上传失败,请重试')
|
||||||
createForm.payment_voucher_key = undefined
|
createForm.payment_voucher_key = undefined
|
||||||
uploadRef.value?.clearFiles()
|
uploadRef.value?.clearFiles()
|
||||||
}
|
}
|
||||||
@@ -733,8 +739,10 @@
|
|||||||
purchased_by_platform: 'danger',
|
purchased_by_platform: 'danger',
|
||||||
purchase_for_subordinate: 'info'
|
purchase_for_subordinate: 'info'
|
||||||
}
|
}
|
||||||
return h(ElTag, { type: roleTypeMap[row.purchase_role || ''] || 'info', size: 'small' }, () =>
|
return h(
|
||||||
getPurchaseRoleText(row.purchase_role || '')
|
ElTag,
|
||||||
|
{ type: roleTypeMap[row.purchase_role || ''] || 'info', size: 'small' },
|
||||||
|
() => getPurchaseRoleText(row.purchase_role || '')
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -242,7 +242,7 @@
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
ElMessage.error('获取详情失败')
|
console.log('获取详情失败')
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -941,7 +941,7 @@
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
ElMessage.error('获取套餐列表失败')
|
console.log('获取套餐列表失败')
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -229,7 +229,7 @@
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
ElMessage.error('获取详情失败')
|
console.log('获取详情失败')
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -751,7 +751,7 @@
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
ElMessage.error('获取套餐系列列表失败')
|
console.log('获取套餐系列列表失败')
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -413,7 +413,7 @@
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
ElMessage.error('获取详情失败')
|
console.log('获取详情失败')
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
@@ -535,7 +535,7 @@
|
|||||||
await fetchDetail()
|
await fetchDetail()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
ElMessage.error(packageDialogType.value === 'add' ? '添加失败' : '更新失败')
|
console.log(packageDialogType.value === 'add' ? '添加失败' : '更新失败')
|
||||||
} finally {
|
} finally {
|
||||||
submitLoading.value = false
|
submitLoading.value = false
|
||||||
}
|
}
|
||||||
@@ -568,7 +568,7 @@
|
|||||||
await fetchDetail()
|
await fetchDetail()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
ElMessage.error('删除失败')
|
console.log('删除失败')
|
||||||
} finally {
|
} finally {
|
||||||
submitLoading.value = false
|
submitLoading.value = false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -175,7 +175,11 @@
|
|||||||
<ElInputNumber
|
<ElInputNumber
|
||||||
v-model="packageForm.cost_price_yuan"
|
v-model="packageForm.cost_price_yuan"
|
||||||
:min="packageForm.original_cost_price || 0"
|
:min="packageForm.original_cost_price || 0"
|
||||||
:max="packageForm.original_cost_price ? packageForm.original_cost_price * 1.5 : undefined"
|
:max="
|
||||||
|
packageForm.original_cost_price
|
||||||
|
? packageForm.original_cost_price * 1.5
|
||||||
|
: undefined
|
||||||
|
"
|
||||||
:precision="2"
|
:precision="2"
|
||||||
:step="0.01"
|
:step="0.01"
|
||||||
:controls="false"
|
:controls="false"
|
||||||
@@ -183,8 +187,10 @@
|
|||||||
placeholder="请输入成本价"
|
placeholder="请输入成本价"
|
||||||
/>
|
/>
|
||||||
<div v-if="packageForm.original_cost_price" class="form-tip">
|
<div v-if="packageForm.original_cost_price" class="form-tip">
|
||||||
原价: ¥{{ packageForm.original_cost_price.toFixed(2) }},
|
原价: ¥{{ packageForm.original_cost_price.toFixed(2) }}, 最高: ¥{{
|
||||||
最高: ¥{{ (packageForm.original_cost_price * 1.5).toFixed(2) }} (50%溢价)
|
(packageForm.original_cost_price * 1.5).toFixed(2)
|
||||||
|
}}
|
||||||
|
(50%溢价)
|
||||||
</div>
|
</div>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
</ElForm>
|
</ElForm>
|
||||||
@@ -312,7 +318,9 @@
|
|||||||
<ElInputNumber
|
<ElInputNumber
|
||||||
v-model="pkg.cost_price"
|
v-model="pkg.cost_price"
|
||||||
:min="pkg.original_cost_price || 0"
|
:min="pkg.original_cost_price || 0"
|
||||||
:max="pkg.original_cost_price ? pkg.original_cost_price * 1.5 : undefined"
|
:max="
|
||||||
|
pkg.original_cost_price ? pkg.original_cost_price * 1.5 : undefined
|
||||||
|
"
|
||||||
:precision="2"
|
:precision="2"
|
||||||
:step="0.01"
|
:step="0.01"
|
||||||
:controls="false"
|
:controls="false"
|
||||||
@@ -320,7 +328,9 @@
|
|||||||
style="width: 150px"
|
style="width: 150px"
|
||||||
/>
|
/>
|
||||||
<span v-if="pkg.original_cost_price" class="min-cost-hint">
|
<span v-if="pkg.original_cost_price" class="min-cost-hint">
|
||||||
(原价: ¥{{ pkg.original_cost_price.toFixed(2) }}, 最高: ¥{{ (pkg.original_cost_price * 1.5).toFixed(2) }})
|
(原价: ¥{{ pkg.original_cost_price.toFixed(2) }}, 最高: ¥{{
|
||||||
|
(pkg.original_cost_price * 1.5).toFixed(2)
|
||||||
|
}})
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<ElButton type="danger" size="small" @click="removePackage(index)"
|
<ElButton type="danger" size="small" @click="removePackage(index)"
|
||||||
@@ -345,99 +355,99 @@
|
|||||||
|
|
||||||
<!-- 佣金类型和金额 - 2列布局 -->
|
<!-- 佣金类型和金额 - 2列布局 -->
|
||||||
<ElRow :gutter="20">
|
<ElRow :gutter="20">
|
||||||
<ElCol :span="12">
|
<ElCol :span="12">
|
||||||
<ElFormItem label="佣金类型">
|
<ElFormItem label="佣金类型">
|
||||||
<div class="commission-type-display">
|
<div class="commission-type-display">
|
||||||
<ElTag
|
<ElTag
|
||||||
:type="form.commission_type === 'fixed' ? 'success' : 'warning'"
|
:type="form.commission_type === 'fixed' ? 'success' : 'warning'"
|
||||||
size="large"
|
size="large"
|
||||||
>
|
|
||||||
{{ form.commission_type === 'fixed' ? '固定佣金' : '梯度佣金' }}
|
|
||||||
</ElTag>
|
|
||||||
<span class="type-hint">(从套餐系列配置继承)</span>
|
|
||||||
</div>
|
|
||||||
</ElFormItem>
|
|
||||||
</ElCol>
|
|
||||||
<ElCol :span="12" v-if="form.commission_type === 'fixed'">
|
|
||||||
<ElFormItem label="佣金金额(元)" prop="one_time_commission_amount">
|
|
||||||
<ElInputNumber
|
|
||||||
v-model="form.one_time_commission_amount"
|
|
||||||
:min="0"
|
|
||||||
:max="form.series_max_commission_amount"
|
|
||||||
:precision="2"
|
|
||||||
:step="0.01"
|
|
||||||
:controls="false"
|
|
||||||
style="width: 100%"
|
|
||||||
placeholder="请输入固定佣金金额(元)"
|
|
||||||
/>
|
|
||||||
<div class="form-tip">
|
|
||||||
该代理能获得的固定佣金金额(单位:元)
|
|
||||||
<span class="max-amount-hint">
|
|
||||||
<br />
|
|
||||||
该系列最大佣金金额:
|
|
||||||
<span class="amount-value"
|
|
||||||
>¥{{ form.series_max_commission_amount.toFixed(2) }}</span
|
|
||||||
>
|
>
|
||||||
</span>
|
{{ form.commission_type === 'fixed' ? '固定佣金' : '梯度佣金' }}
|
||||||
|
</ElTag>
|
||||||
|
<span class="type-hint">(从套餐系列配置继承)</span>
|
||||||
|
</div>
|
||||||
|
</ElFormItem>
|
||||||
|
</ElCol>
|
||||||
|
<ElCol :span="12" v-if="form.commission_type === 'fixed'">
|
||||||
|
<ElFormItem label="佣金金额(元)" prop="one_time_commission_amount">
|
||||||
|
<ElInputNumber
|
||||||
|
v-model="form.one_time_commission_amount"
|
||||||
|
:min="0"
|
||||||
|
:max="form.series_max_commission_amount"
|
||||||
|
:precision="2"
|
||||||
|
:step="0.01"
|
||||||
|
:controls="false"
|
||||||
|
style="width: 100%"
|
||||||
|
placeholder="请输入固定佣金金额(元)"
|
||||||
|
/>
|
||||||
|
<div class="form-tip">
|
||||||
|
该代理能获得的固定佣金金额(单位:元)
|
||||||
|
<span class="max-amount-hint">
|
||||||
|
<br />
|
||||||
|
该系列最大佣金金额:
|
||||||
|
<span class="amount-value"
|
||||||
|
>¥{{ form.series_max_commission_amount.toFixed(2) }}</span
|
||||||
|
>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</ElFormItem>
|
||||||
|
</ElCol>
|
||||||
|
</ElRow>
|
||||||
|
|
||||||
|
<!-- 梯度佣金配置 -->
|
||||||
|
<template v-if="form.commission_type === 'tiered'">
|
||||||
|
<ElFormItem label="梯度配置" prop="commission_tiers">
|
||||||
|
<ElTable :data="form.commission_tiers" border style="width: 100%">
|
||||||
|
<ElTableColumn label="比较运算符" width="100" align="center">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<ElTag size="small" type="success">{{ row.operator || '>=' }}</ElTag>
|
||||||
|
</template>
|
||||||
|
</ElTableColumn>
|
||||||
|
<ElTableColumn label="达标阈值" width="120">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<span class="readonly-value">{{ row.threshold }}</span>
|
||||||
|
</template>
|
||||||
|
</ElTableColumn>
|
||||||
|
<ElTableColumn label="统计维度" width="120">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<ElTag size="small" type="info">
|
||||||
|
{{ row.dimension === 'sales_count' ? '销量' : '销售额' }}
|
||||||
|
</ElTag>
|
||||||
|
</template>
|
||||||
|
</ElTableColumn>
|
||||||
|
<ElTableColumn label="统计范围" width="140">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<ElTag size="small" type="warning"> 仅自己 </ElTag>
|
||||||
|
</template>
|
||||||
|
</ElTableColumn>
|
||||||
|
<ElTableColumn label="佣金金额(元)" min-width="180">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<div style="display: flex; flex-direction: column; gap: 4px">
|
||||||
|
<ElInputNumber
|
||||||
|
v-model="row.amount"
|
||||||
|
:min="0"
|
||||||
|
:max="row.max_amount"
|
||||||
|
:precision="2"
|
||||||
|
:step="0.01"
|
||||||
|
:controls="false"
|
||||||
|
placeholder="请输入佣金金额"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
v-if="row.max_amount"
|
||||||
|
style="font-size: 12px; color: var(--el-text-color-secondary)"
|
||||||
|
>
|
||||||
|
最大: ¥{{ row.max_amount.toFixed(2) }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</ElTableColumn>
|
||||||
|
</ElTable>
|
||||||
|
<div class="form-tip" style="margin-top: 8px">
|
||||||
|
梯度配置从套餐系列继承,达标阈值、统计维度、统计范围为只读,只能修改佣金金额
|
||||||
</div>
|
</div>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
</ElCol>
|
</template>
|
||||||
</ElRow>
|
|
||||||
|
|
||||||
<!-- 梯度佣金配置 -->
|
|
||||||
<template v-if="form.commission_type === 'tiered'">
|
|
||||||
<ElFormItem label="梯度配置" prop="commission_tiers">
|
|
||||||
<ElTable :data="form.commission_tiers" border style="width: 100%">
|
|
||||||
<ElTableColumn label="比较运算符" width="100" align="center">
|
|
||||||
<template #default="{ row }">
|
|
||||||
<ElTag size="small" type="success">{{ row.operator || '>=' }}</ElTag>
|
|
||||||
</template>
|
|
||||||
</ElTableColumn>
|
|
||||||
<ElTableColumn label="达标阈值" width="120">
|
|
||||||
<template #default="{ row }">
|
|
||||||
<span class="readonly-value">{{ row.threshold }}</span>
|
|
||||||
</template>
|
|
||||||
</ElTableColumn>
|
|
||||||
<ElTableColumn label="统计维度" width="120">
|
|
||||||
<template #default="{ row }">
|
|
||||||
<ElTag size="small" type="info">
|
|
||||||
{{ row.dimension === 'sales_count' ? '销量' : '销售额' }}
|
|
||||||
</ElTag>
|
|
||||||
</template>
|
|
||||||
</ElTableColumn>
|
|
||||||
<ElTableColumn label="统计范围" width="140">
|
|
||||||
<template #default="{ row }">
|
|
||||||
<ElTag size="small" type="warning"> 仅自己 </ElTag>
|
|
||||||
</template>
|
|
||||||
</ElTableColumn>
|
|
||||||
<ElTableColumn label="佣金金额(元)" min-width="180">
|
|
||||||
<template #default="{ row }">
|
|
||||||
<div style="display: flex; flex-direction: column; gap: 4px">
|
|
||||||
<ElInputNumber
|
|
||||||
v-model="row.amount"
|
|
||||||
:min="0"
|
|
||||||
:max="row.max_amount"
|
|
||||||
:precision="2"
|
|
||||||
:step="0.01"
|
|
||||||
:controls="false"
|
|
||||||
placeholder="请输入佣金金额"
|
|
||||||
style="width: 100%"
|
|
||||||
/>
|
|
||||||
<span
|
|
||||||
v-if="row.max_amount"
|
|
||||||
style="font-size: 12px; color: var(--el-text-color-secondary)"
|
|
||||||
>
|
|
||||||
最大: ¥{{ row.max_amount.toFixed(2) }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</ElTableColumn>
|
|
||||||
</ElTable>
|
|
||||||
<div class="form-tip" style="margin-top: 8px">
|
|
||||||
梯度配置从套餐系列继承,达标阈值、统计维度、统计范围为只读,只能修改佣金金额
|
|
||||||
</div>
|
|
||||||
</ElFormItem>
|
|
||||||
</template>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- 强制充值配置 -->
|
<!-- 强制充值配置 -->
|
||||||
@@ -511,99 +521,99 @@
|
|||||||
|
|
||||||
<!-- 佣金类型和金额 - 2列布局 -->
|
<!-- 佣金类型和金额 - 2列布局 -->
|
||||||
<ElRow :gutter="20" v-if="form.series_id">
|
<ElRow :gutter="20" v-if="form.series_id">
|
||||||
<ElCol :span="12">
|
<ElCol :span="12">
|
||||||
<ElFormItem label="佣金类型">
|
<ElFormItem label="佣金类型">
|
||||||
<div class="commission-type-display">
|
<div class="commission-type-display">
|
||||||
<ElTag
|
<ElTag
|
||||||
:type="form.commission_type === 'fixed' ? 'success' : 'warning'"
|
:type="form.commission_type === 'fixed' ? 'success' : 'warning'"
|
||||||
size="large"
|
size="large"
|
||||||
>
|
|
||||||
{{ form.commission_type === 'fixed' ? '固定佣金' : '梯度佣金' }}
|
|
||||||
</ElTag>
|
|
||||||
<span class="type-hint">(从套餐系列配置继承)</span>
|
|
||||||
</div>
|
|
||||||
</ElFormItem>
|
|
||||||
</ElCol>
|
|
||||||
<ElCol :span="12" v-if="form.commission_type === 'fixed'">
|
|
||||||
<ElFormItem label="佣金金额(元)" prop="one_time_commission_amount">
|
|
||||||
<ElInputNumber
|
|
||||||
v-model="form.one_time_commission_amount"
|
|
||||||
:min="0"
|
|
||||||
:max="form.series_max_commission_amount"
|
|
||||||
:precision="2"
|
|
||||||
:step="0.01"
|
|
||||||
:controls="false"
|
|
||||||
style="width: 100%"
|
|
||||||
placeholder="请输入固定佣金金额(元)"
|
|
||||||
/>
|
|
||||||
<div class="form-tip">
|
|
||||||
该代理能获得的固定佣金金额(单位:元)
|
|
||||||
<span class="max-amount-hint">
|
|
||||||
<br />
|
|
||||||
该系列最大佣金金额:
|
|
||||||
<span class="amount-value"
|
|
||||||
>¥{{ form.series_max_commission_amount.toFixed(2) }}</span
|
|
||||||
>
|
>
|
||||||
</span>
|
{{ form.commission_type === 'fixed' ? '固定佣金' : '梯度佣金' }}
|
||||||
|
</ElTag>
|
||||||
|
<span class="type-hint">(从套餐系列配置继承)</span>
|
||||||
|
</div>
|
||||||
|
</ElFormItem>
|
||||||
|
</ElCol>
|
||||||
|
<ElCol :span="12" v-if="form.commission_type === 'fixed'">
|
||||||
|
<ElFormItem label="佣金金额(元)" prop="one_time_commission_amount">
|
||||||
|
<ElInputNumber
|
||||||
|
v-model="form.one_time_commission_amount"
|
||||||
|
:min="0"
|
||||||
|
:max="form.series_max_commission_amount"
|
||||||
|
:precision="2"
|
||||||
|
:step="0.01"
|
||||||
|
:controls="false"
|
||||||
|
style="width: 100%"
|
||||||
|
placeholder="请输入固定佣金金额(元)"
|
||||||
|
/>
|
||||||
|
<div class="form-tip">
|
||||||
|
该代理能获得的固定佣金金额(单位:元)
|
||||||
|
<span class="max-amount-hint">
|
||||||
|
<br />
|
||||||
|
该系列最大佣金金额:
|
||||||
|
<span class="amount-value"
|
||||||
|
>¥{{ form.series_max_commission_amount.toFixed(2) }}</span
|
||||||
|
>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</ElFormItem>
|
||||||
|
</ElCol>
|
||||||
|
</ElRow>
|
||||||
|
|
||||||
|
<!-- 梯度佣金配置 -->
|
||||||
|
<template v-if="form.commission_type === 'tiered'">
|
||||||
|
<ElFormItem label="梯度配置" prop="commission_tiers">
|
||||||
|
<ElTable :data="form.commission_tiers" border style="width: 100%">
|
||||||
|
<ElTableColumn label="比较运算符" width="100" align="center">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<ElTag size="small" type="success">{{ row.operator || '>=' }}</ElTag>
|
||||||
|
</template>
|
||||||
|
</ElTableColumn>
|
||||||
|
<ElTableColumn label="达标阈值" width="120">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<span class="readonly-value">{{ row.threshold }}</span>
|
||||||
|
</template>
|
||||||
|
</ElTableColumn>
|
||||||
|
<ElTableColumn label="统计维度" width="120">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<ElTag size="small" type="info">
|
||||||
|
{{ row.dimension === 'sales_count' ? '销量' : '销售额' }}
|
||||||
|
</ElTag>
|
||||||
|
</template>
|
||||||
|
</ElTableColumn>
|
||||||
|
<ElTableColumn label="统计范围" width="140">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<ElTag size="small" type="warning"> 仅自己 </ElTag>
|
||||||
|
</template>
|
||||||
|
</ElTableColumn>
|
||||||
|
<ElTableColumn label="佣金金额(元)" min-width="180">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<div style="display: flex; flex-direction: column; gap: 4px">
|
||||||
|
<ElInputNumber
|
||||||
|
v-model="row.amount"
|
||||||
|
:min="0"
|
||||||
|
:max="row.max_amount"
|
||||||
|
:precision="2"
|
||||||
|
:step="0.01"
|
||||||
|
:controls="false"
|
||||||
|
placeholder="请输入佣金金额"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
v-if="row.max_amount"
|
||||||
|
style="font-size: 12px; color: var(--el-text-color-secondary)"
|
||||||
|
>
|
||||||
|
最大: ¥{{ row.max_amount.toFixed(2) }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</ElTableColumn>
|
||||||
|
</ElTable>
|
||||||
|
<div class="form-tip" style="margin-top: 8px">
|
||||||
|
梯度配置从套餐系列继承,达标阈值、统计维度、统计范围为只读,只能修改佣金金额
|
||||||
</div>
|
</div>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
</ElCol>
|
</template>
|
||||||
</ElRow>
|
|
||||||
|
|
||||||
<!-- 梯度佣金配置 -->
|
|
||||||
<template v-if="form.commission_type === 'tiered'">
|
|
||||||
<ElFormItem label="梯度配置" prop="commission_tiers">
|
|
||||||
<ElTable :data="form.commission_tiers" border style="width: 100%">
|
|
||||||
<ElTableColumn label="比较运算符" width="100" align="center">
|
|
||||||
<template #default="{ row }">
|
|
||||||
<ElTag size="small" type="success">{{ row.operator || '>=' }}</ElTag>
|
|
||||||
</template>
|
|
||||||
</ElTableColumn>
|
|
||||||
<ElTableColumn label="达标阈值" width="120">
|
|
||||||
<template #default="{ row }">
|
|
||||||
<span class="readonly-value">{{ row.threshold }}</span>
|
|
||||||
</template>
|
|
||||||
</ElTableColumn>
|
|
||||||
<ElTableColumn label="统计维度" width="120">
|
|
||||||
<template #default="{ row }">
|
|
||||||
<ElTag size="small" type="info">
|
|
||||||
{{ row.dimension === 'sales_count' ? '销量' : '销售额' }}
|
|
||||||
</ElTag>
|
|
||||||
</template>
|
|
||||||
</ElTableColumn>
|
|
||||||
<ElTableColumn label="统计范围" width="140">
|
|
||||||
<template #default="{ row }">
|
|
||||||
<ElTag size="small" type="warning"> 仅自己 </ElTag>
|
|
||||||
</template>
|
|
||||||
</ElTableColumn>
|
|
||||||
<ElTableColumn label="佣金金额(元)" min-width="180">
|
|
||||||
<template #default="{ row }">
|
|
||||||
<div style="display: flex; flex-direction: column; gap: 4px">
|
|
||||||
<ElInputNumber
|
|
||||||
v-model="row.amount"
|
|
||||||
:min="0"
|
|
||||||
:max="row.max_amount"
|
|
||||||
:precision="2"
|
|
||||||
:step="0.01"
|
|
||||||
:controls="false"
|
|
||||||
placeholder="请输入佣金金额"
|
|
||||||
style="width: 100%"
|
|
||||||
/>
|
|
||||||
<span
|
|
||||||
v-if="row.max_amount"
|
|
||||||
style="font-size: 12px; color: var(--el-text-color-secondary)"
|
|
||||||
>
|
|
||||||
最大: ¥{{ row.max_amount.toFixed(2) }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</ElTableColumn>
|
|
||||||
</ElTable>
|
|
||||||
<div class="form-tip" style="margin-top: 8px">
|
|
||||||
梯度配置从套餐系列继承,达标阈值、统计维度、统计范围为只读,只能修改佣金金额
|
|
||||||
</div>
|
|
||||||
</ElFormItem>
|
|
||||||
</template>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- 强制充值配置 -->
|
<!-- 强制充值配置 -->
|
||||||
@@ -835,10 +845,22 @@
|
|||||||
callback(new Error('请输入成本价'))
|
callback(new Error('请输入成本价'))
|
||||||
} else if (value < 0) {
|
} else if (value < 0) {
|
||||||
callback(new Error('成本价不能小于0'))
|
callback(new Error('成本价不能小于0'))
|
||||||
} else if (packageForm.value.original_cost_price && value < packageForm.value.original_cost_price) {
|
} else if (
|
||||||
callback(new Error(`成本价不能低于原价 ¥${packageForm.value.original_cost_price.toFixed(2)}`))
|
packageForm.value.original_cost_price &&
|
||||||
} else if (packageForm.value.original_cost_price && value > packageForm.value.original_cost_price * 1.5) {
|
value < packageForm.value.original_cost_price
|
||||||
callback(new Error(`成本价不能高于原价的50%溢价(最高:¥${(packageForm.value.original_cost_price * 1.5).toFixed(2)})`))
|
) {
|
||||||
|
callback(
|
||||||
|
new Error(`成本价不能低于原价 ¥${packageForm.value.original_cost_price.toFixed(2)}`)
|
||||||
|
)
|
||||||
|
} else if (
|
||||||
|
packageForm.value.original_cost_price &&
|
||||||
|
value > packageForm.value.original_cost_price * 1.5
|
||||||
|
) {
|
||||||
|
callback(
|
||||||
|
new Error(
|
||||||
|
`成本价不能高于原价的50%溢价(最高:¥${(packageForm.value.original_cost_price * 1.5).toFixed(2)})`
|
||||||
|
)
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
callback()
|
callback()
|
||||||
}
|
}
|
||||||
@@ -1470,7 +1492,9 @@
|
|||||||
// 从 availablePackages 中查找选中的套餐
|
// 从 availablePackages 中查找选中的套餐
|
||||||
const selectedPackage = availablePackages.value.find((p) => p.id === packageId)
|
const selectedPackage = availablePackages.value.find((p) => p.id === packageId)
|
||||||
if (selectedPackage) {
|
if (selectedPackage) {
|
||||||
const originalCostPrice = selectedPackage.cost_price ? selectedPackage.cost_price / 100 : 0
|
const originalCostPrice = selectedPackage.cost_price
|
||||||
|
? selectedPackage.cost_price / 100
|
||||||
|
: 0
|
||||||
packageForm.value.original_cost_price = originalCostPrice
|
packageForm.value.original_cost_price = originalCostPrice
|
||||||
packageForm.value.cost_price_yuan = originalCostPrice
|
packageForm.value.cost_price_yuan = originalCostPrice
|
||||||
}
|
}
|
||||||
@@ -1501,7 +1525,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 加载搜索栏系列选项(默认加载10条)
|
// 加载搜索栏系列选项(默认加载10条)
|
||||||
const loadSearchSeriesOptions = async () => {
|
const loadSearchSeriesOptions = async () => {
|
||||||
try {
|
try {
|
||||||
@@ -1661,7 +1684,7 @@
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
ElMessage.error('获取系列分配列表失败')
|
console.log('获取系列分配列表失败')
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
@@ -1798,7 +1821,7 @@
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取详情失败:', error)
|
console.error('获取详情失败:', error)
|
||||||
ElMessage.error('获取详情失败')
|
console.log('获取详情失败')
|
||||||
dialogVisible.value = false
|
dialogVisible.value = false
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
@@ -1910,7 +1933,9 @@
|
|||||||
// 根据佣金类型携带不同参数
|
// 根据佣金类型携带不同参数
|
||||||
if (form.commission_type === 'fixed') {
|
if (form.commission_type === 'fixed') {
|
||||||
// 固定模式:携带 one_time_commission_amount(将元转换为分)
|
// 固定模式:携带 one_time_commission_amount(将元转换为分)
|
||||||
data.one_time_commission_amount = Math.round((form.one_time_commission_amount || 0) * 100)
|
data.one_time_commission_amount = Math.round(
|
||||||
|
(form.one_time_commission_amount || 0) * 100
|
||||||
|
)
|
||||||
} else if (form.commission_type === 'tiered') {
|
} else if (form.commission_type === 'tiered') {
|
||||||
// 梯度模式:携带 commission_tiers(将元转换为分)
|
// 梯度模式:携带 commission_tiers(将元转换为分)
|
||||||
// 注意:请求时不传 operator,operator 是响应中从 PackageSeries 合并过来的
|
// 注意:请求时不传 operator,operator 是响应中从 PackageSeries 合并过来的
|
||||||
@@ -2013,7 +2038,7 @@
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取套餐列表失败:', error)
|
console.error('获取套餐列表失败:', error)
|
||||||
ElMessage.error('获取套餐列表失败')
|
console.log('获取套餐列表失败')
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
@@ -2128,7 +2153,7 @@
|
|||||||
await refreshPackageList()
|
await refreshPackageList()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
ElMessage.error(packageDialogType.value === 'add' ? '添加失败' : '更新失败')
|
console.log(packageDialogType.value === 'add' ? '添加失败' : '更新失败')
|
||||||
} finally {
|
} finally {
|
||||||
packageSubmitLoading.value = false
|
packageSubmitLoading.value = false
|
||||||
}
|
}
|
||||||
@@ -2161,7 +2186,7 @@
|
|||||||
await refreshPackageList()
|
await refreshPackageList()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
ElMessage.error('删除失败')
|
console.log('删除失败')
|
||||||
} finally {
|
} finally {
|
||||||
packageSubmitLoading.value = false
|
packageSubmitLoading.value = false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -231,7 +231,7 @@
|
|||||||
tableData.value = data.items
|
tableData.value = data.items
|
||||||
pagination.total = data.total
|
pagination.total = data.total
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
ElMessage.error('加载告警历史失败')
|
console.log('加载告警历史失败')
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -329,7 +329,7 @@
|
|||||||
tableData.value = res.data.items
|
tableData.value = res.data.items
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
ElMessage.error('加载数据失败')
|
console.log('加载数据失败')
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
@@ -384,7 +384,7 @@
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
ElMessage.error('获取规则详情失败')
|
console.log('获取规则详情失败')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -410,7 +410,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
ElMessage.error(dialogType.value === 'create' ? '创建失败' : '更新失败')
|
console.log(dialogType.value === 'create' ? '创建失败' : '更新失败')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -425,7 +425,7 @@
|
|||||||
loadData()
|
loadData()
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
ElMessage.error('操作失败')
|
console.log('操作失败')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -442,7 +442,7 @@
|
|||||||
loadData()
|
loadData()
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
ElMessage.error('删除失败')
|
console.log('删除失败')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -165,7 +165,7 @@
|
|||||||
const { data } = await PollingConcurrencyService.getConcurrencyList()
|
const { data } = await PollingConcurrencyService.getConcurrencyList()
|
||||||
tableData.value = data.items
|
tableData.value = data.items
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
ElMessage.error('加载并发配置失败')
|
console.log('加载并发配置失败')
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
@@ -179,7 +179,7 @@
|
|||||||
formData.max_concurrency = data.max_concurrency
|
formData.max_concurrency = data.max_concurrency
|
||||||
dialogVisible.value = true
|
dialogVisible.value = true
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
ElMessage.error('获取并发配置失败')
|
console.log('获取并发配置失败')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,7 +196,7 @@
|
|||||||
await loadData()
|
await loadData()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error !== 'cancel') {
|
if (error !== 'cancel') {
|
||||||
ElMessage.error('重置失败')
|
console.log('重置失败')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -214,7 +214,7 @@
|
|||||||
await loadData()
|
await loadData()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error !== 'cancel') {
|
if (error !== 'cancel') {
|
||||||
ElMessage.error('重置失败')
|
console.log('重置失败')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -231,7 +231,7 @@
|
|||||||
dialogVisible.value = false
|
dialogVisible.value = false
|
||||||
await loadData()
|
await loadData()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
ElMessage.error('修改失败')
|
console.log('修改失败')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -516,7 +516,7 @@
|
|||||||
tableData.value = data.items
|
tableData.value = data.items
|
||||||
pagination.total = data.total
|
pagination.total = data.total
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
ElMessage.error('加载配置列表失败')
|
console.log('加载配置列表失败')
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
@@ -594,7 +594,7 @@
|
|||||||
formRef.value?.clearValidate()
|
formRef.value?.clearValidate()
|
||||||
})
|
})
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
ElMessage.error('获取配置详情失败')
|
console.log('获取配置详情失败')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -605,7 +605,7 @@
|
|||||||
ElMessage.success(newStatus === 1 ? '已启用' : '已禁用')
|
ElMessage.success(newStatus === 1 ? '已启用' : '已禁用')
|
||||||
await loadData()
|
await loadData()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
ElMessage.error('状态更新失败')
|
console.log('状态更新失败')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -622,7 +622,7 @@
|
|||||||
await loadData()
|
await loadData()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error !== 'cancel') {
|
if (error !== 'cancel') {
|
||||||
ElMessage.error('删除失败')
|
console.log('删除失败')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -657,7 +657,7 @@
|
|||||||
dialogVisible.value = false
|
dialogVisible.value = false
|
||||||
await loadData()
|
await loadData()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
ElMessage.error(dialogType.value === 'create' ? '创建失败' : '更新失败')
|
console.log(dialogType.value === 'create' ? '创建失败' : '更新失败')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -424,7 +424,6 @@
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取详情失败:', error)
|
console.error('获取详情失败:', error)
|
||||||
ElMessage.error('获取配置详情失败')
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -294,7 +294,6 @@
|
|||||||
ManualTriggerHistoryQueryParams,
|
ManualTriggerHistoryQueryParams,
|
||||||
BatchManualTriggerRequest,
|
BatchManualTriggerRequest,
|
||||||
ConditionManualTriggerRequest,
|
ConditionManualTriggerRequest,
|
||||||
SingleManualTriggerRequest,
|
|
||||||
TaskType
|
TaskType
|
||||||
} from '@/types/api'
|
} from '@/types/api'
|
||||||
import type { SearchFormItem } from '@/types'
|
import type { SearchFormItem } from '@/types'
|
||||||
@@ -510,7 +509,7 @@
|
|||||||
tableData.value = data.items
|
tableData.value = data.items
|
||||||
pagination.total = data.total
|
pagination.total = data.total
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
ElMessage.error('加载触发历史失败')
|
console.log('加载触发历史失败')
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
@@ -610,9 +609,9 @@
|
|||||||
await ManualTriggerService.batchTrigger(requestData)
|
await ManualTriggerService.batchTrigger(requestData)
|
||||||
ElMessage.success('批量触发成功')
|
ElMessage.success('批量触发成功')
|
||||||
batchDialogVisible.value = false
|
batchDialogVisible.value = false
|
||||||
loadData()
|
await loadData()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
ElMessage.error('批量触发失败')
|
console.log('批量触发失败')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -637,9 +636,9 @@
|
|||||||
await ManualTriggerService.conditionTrigger(requestData)
|
await ManualTriggerService.conditionTrigger(requestData)
|
||||||
ElMessage.success('条件触发成功')
|
ElMessage.success('条件触发成功')
|
||||||
conditionDialogVisible.value = false
|
conditionDialogVisible.value = false
|
||||||
loadData()
|
await loadData()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
ElMessage.error('条件触发失败')
|
console.log('条件触发失败')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -656,9 +655,9 @@
|
|||||||
})
|
})
|
||||||
ElMessage.success('单卡触发成功')
|
ElMessage.success('单卡触发成功')
|
||||||
singleDialogVisible.value = false
|
singleDialogVisible.value = false
|
||||||
loadData()
|
await loadData()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
ElMessage.error('单卡触发失败')
|
console.log('单卡触发失败')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -673,15 +672,15 @@
|
|||||||
|
|
||||||
await ManualTriggerService.cancelTrigger({ trigger_id: row.id })
|
await ManualTriggerService.cancelTrigger({ trigger_id: row.id })
|
||||||
ElMessage.success('任务已取消')
|
ElMessage.success('任务已取消')
|
||||||
loadData()
|
await loadData()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error !== 'cancel') {
|
if (error !== 'cancel') {
|
||||||
ElMessage.error('取消任务失败')
|
console.log('取消任务失败')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleRowContextMenu = (row: ManualTriggerLog, column: any, event: MouseEvent) => {
|
const handleRowContextMenu = (row: ManualTriggerLog, _column: any, event: MouseEvent) => {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
event.stopPropagation()
|
event.stopPropagation()
|
||||||
currentClickRow.value = row
|
currentClickRow.value = row
|
||||||
|
|||||||
@@ -98,11 +98,7 @@
|
|||||||
import { ref, onMounted, onUnmounted } from 'vue'
|
import { ref, onMounted, onUnmounted } from 'vue'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
import { PollingMonitorService } from '@/api/modules'
|
import { PollingMonitorService } from '@/api/modules'
|
||||||
import type {
|
import type { PollingInitProgress, PollingQueueStatus, PollingTaskStats } from '@/types/api'
|
||||||
PollingInitProgress,
|
|
||||||
PollingQueueStatus,
|
|
||||||
PollingTaskStats
|
|
||||||
} from '@/types/api'
|
|
||||||
import { formatDateTime } from '@/utils/business/format'
|
import { formatDateTime } from '@/utils/business/format'
|
||||||
const initProgress = ref<PollingInitProgress>()
|
const initProgress = ref<PollingInitProgress>()
|
||||||
const queueStatusList = ref<PollingQueueStatus[]>([])
|
const queueStatusList = ref<PollingQueueStatus[]>([])
|
||||||
@@ -120,9 +116,6 @@
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('加载初始化进度失败', error)
|
console.error('加载初始化进度失败', error)
|
||||||
if (showMessage) {
|
|
||||||
ElMessage.error('加载初始化进度失败')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,7 +128,7 @@
|
|||||||
ElMessage.success('队列状态已刷新')
|
ElMessage.success('队列状态已刷新')
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
ElMessage.error('加载队列状态失败')
|
console.log('加载队列状态失败')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,7 +141,7 @@
|
|||||||
ElMessage.success('任务统计已刷新')
|
ElMessage.success('任务统计已刷新')
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
ElMessage.error('加载任务统计失败')
|
console.log('加载任务统计失败')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -262,7 +262,6 @@
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
ElMessage.error('获取支付配置详情失败')
|
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,12 @@
|
|||||||
@refresh="handleRefresh"
|
@refresh="handleRefresh"
|
||||||
>
|
>
|
||||||
<template #left>
|
<template #left>
|
||||||
<ElButton type="primary" @click="showCreateDialog" v-if="hasAuth('wechat_config:create')">新增支付配置</ElButton>
|
<ElButton
|
||||||
|
type="primary"
|
||||||
|
@click="showCreateDialog"
|
||||||
|
v-if="hasAuth('wechat_config:create')"
|
||||||
|
>新增支付配置</ElButton
|
||||||
|
>
|
||||||
</template>
|
</template>
|
||||||
</ArtTableHeader>
|
</ArtTableHeader>
|
||||||
|
|
||||||
@@ -834,7 +839,6 @@
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取详情失败:', error)
|
console.error('获取详情失败:', error)
|
||||||
ElMessage.error('获取配置详情失败')
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -915,7 +915,6 @@
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取店铺默认角色失败:', error)
|
console.error('获取店铺默认角色失败:', error)
|
||||||
ElMessage.error('获取店铺默认角色失败')
|
|
||||||
} finally {
|
} finally {
|
||||||
defaultRolesLoading.value = false
|
defaultRolesLoading.value = false
|
||||||
}
|
}
|
||||||
@@ -944,7 +943,7 @@
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取角色列表失败:', error)
|
console.error('获取角色列表失败:', error)
|
||||||
ElMessage.error('获取角色列表失败')
|
console.log('获取角色列表失败')
|
||||||
} finally {
|
} finally {
|
||||||
rolesLoading.value = false
|
rolesLoading.value = false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -826,7 +826,6 @@
|
|||||||
ElMessage.success('权限添加成功')
|
ElMessage.success('权限添加成功')
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('添加权限失败:', error)
|
console.error('添加权限失败:', error)
|
||||||
ElMessage.error('权限添加失败')
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -881,7 +880,6 @@
|
|||||||
ElMessage.success('权限移除成功')
|
ElMessage.success('权限移除成功')
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('移除权限失败:', error)
|
console.error('移除权限失败:', error)
|
||||||
ElMessage.error('权限移除失败')
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user