This commit is contained in:
@@ -10,12 +10,13 @@
|
|||||||
generateSeriesCode,
|
generateSeriesCode,
|
||||||
generatePackageCode,
|
generatePackageCode,
|
||||||
generateShopCode,
|
generateShopCode,
|
||||||
generateCarrierCode
|
generateCarrierCode,
|
||||||
|
generateEnterpriseCode
|
||||||
} from '@/utils/codeGenerator'
|
} from '@/utils/codeGenerator'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
// 编码类型: series(套餐系列) | package(套餐) | shop(店铺) | carrier(运营商)
|
// 编码类型: series(套餐系列) | package(套餐) | shop(店铺) | carrier(运营商) | enterprise(企业)
|
||||||
codeType: 'series' | 'package' | 'shop' | 'carrier'
|
codeType: 'series' | 'package' | 'shop' | 'carrier' | 'enterprise'
|
||||||
// 按钮文字
|
// 按钮文字
|
||||||
buttonText?: string
|
buttonText?: string
|
||||||
// 表单字段名,用于清除验证
|
// 表单字段名,用于清除验证
|
||||||
@@ -47,6 +48,9 @@
|
|||||||
case 'carrier':
|
case 'carrier':
|
||||||
code = generateCarrierCode()
|
code = generateCarrierCode()
|
||||||
break
|
break
|
||||||
|
case 'enterprise':
|
||||||
|
code = generateEnterpriseCode()
|
||||||
|
break
|
||||||
default:
|
default:
|
||||||
ElMessage.error('未知的编码类型')
|
ElMessage.error('未知的编码类型')
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -24,9 +24,8 @@ export interface PaginationParams {
|
|||||||
export interface PaginationData<T> {
|
export interface PaginationData<T> {
|
||||||
items: T[] // 数据列表
|
items: T[] // 数据列表
|
||||||
total: number // 总数
|
total: number // 总数
|
||||||
page_size: number // 每页数量
|
size: number // 每页数量
|
||||||
page: number // 当前页
|
page: number // 当前页
|
||||||
total_pages: number // 总页数
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 分页响应
|
// 分页响应
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ export interface EnterpriseDevicePageResult {
|
|||||||
* 授权设备请求参数
|
* 授权设备请求参数
|
||||||
*/
|
*/
|
||||||
export interface AllocateDevicesRequest {
|
export interface AllocateDevicesRequest {
|
||||||
virtual_nos: string[] | null // 虚拟号列表(最多100个,原 device_nos)
|
device_nos: string[] | null // 设备号列表(最多100个)
|
||||||
remark?: string // 授权备注
|
remark?: string // 授权备注
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,7 +76,7 @@ export interface AllocateDevicesResponse {
|
|||||||
* 撤销设备授权请求参数
|
* 撤销设备授权请求参数
|
||||||
*/
|
*/
|
||||||
export interface RecallDevicesRequest {
|
export interface RecallDevicesRequest {
|
||||||
virtual_nos: string[] | null // 虚拟号列表(最多100个,原 device_nos)
|
device_nos: string[] | null // 设备号列表(最多100个)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// 支付渠道类型
|
// 支付渠道类型
|
||||||
export type PaymentProviderType = 'wechat' | 'fuiou'
|
export type PaymentProviderType = 'wechat' | 'wechat_v2' | 'fuiou'
|
||||||
|
|
||||||
// 微信支付配置
|
// 微信支付配置
|
||||||
export interface WechatConfig {
|
export interface WechatConfig {
|
||||||
|
|||||||
@@ -89,3 +89,25 @@ export function generateCarrierCode(): string {
|
|||||||
|
|
||||||
return `CARRIER${year}${month}${day}${hours}${minutes}${seconds}${randomChars}`
|
return `CARRIER${year}${month}${day}${hours}${minutes}${seconds}${randomChars}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成企业编码
|
||||||
|
* 规则: ENT + 年月日时分秒 + 4位随机数
|
||||||
|
* 示例: ENT20260331143025ABCD
|
||||||
|
*/
|
||||||
|
export function generateEnterpriseCode(): string {
|
||||||
|
const now = new Date()
|
||||||
|
const year = now.getFullYear()
|
||||||
|
const month = String(now.getMonth() + 1).padStart(2, '0')
|
||||||
|
const day = String(now.getDate()).padStart(2, '0')
|
||||||
|
const hours = String(now.getHours()).padStart(2, '0')
|
||||||
|
const minutes = String(now.getMinutes()).padStart(2, '0')
|
||||||
|
const seconds = String(now.getSeconds()).padStart(2, '0')
|
||||||
|
|
||||||
|
// 生成4位随机大写字母
|
||||||
|
const randomChars = Array.from({ length: 4 }, () =>
|
||||||
|
String.fromCharCode(65 + Math.floor(Math.random() * 26))
|
||||||
|
).join('')
|
||||||
|
|
||||||
|
return `ENT${year}${month}${day}${hours}${minutes}${seconds}${randomChars}`
|
||||||
|
}
|
||||||
|
|||||||
@@ -57,28 +57,28 @@
|
|||||||
width="600px"
|
width="600px"
|
||||||
>
|
>
|
||||||
<ElForm ref="formRef" :model="form" :rules="rules" label-width="100px">
|
<ElForm ref="formRef" :model="form" :rules="rules" label-width="100px">
|
||||||
|
<ElFormItem label="企业编号" prop="enterprise_code">
|
||||||
|
<div style="display: flex; gap: 8px">
|
||||||
|
<ElInput
|
||||||
|
v-model="form.enterprise_code"
|
||||||
|
placeholder="请输入企业编号或点击生成"
|
||||||
|
:disabled="dialogType === 'edit'"
|
||||||
|
clearable
|
||||||
|
style="flex: 1"
|
||||||
|
/>
|
||||||
|
<CodeGeneratorButton
|
||||||
|
v-if="dialogType === 'add'"
|
||||||
|
code-type="enterprise"
|
||||||
|
@generated="handleCodeGenerated"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</ElFormItem>
|
||||||
<ElRow :gutter="20">
|
<ElRow :gutter="20">
|
||||||
<ElCol :span="12">
|
|
||||||
<ElFormItem label="企业编号" prop="enterprise_code">
|
|
||||||
<ElInput
|
|
||||||
v-model="form.enterprise_code"
|
|
||||||
placeholder="请输入企业编号"
|
|
||||||
:disabled="dialogType === 'edit'"
|
|
||||||
/>
|
|
||||||
</ElFormItem>
|
|
||||||
</ElCol>
|
|
||||||
<ElCol :span="12">
|
<ElCol :span="12">
|
||||||
<ElFormItem label="企业名称" prop="enterprise_name">
|
<ElFormItem label="企业名称" prop="enterprise_name">
|
||||||
<ElInput v-model="form.enterprise_name" placeholder="请输入企业名称" />
|
<ElInput v-model="form.enterprise_name" placeholder="请输入企业名称" />
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
</ElCol>
|
</ElCol>
|
||||||
</ElRow>
|
|
||||||
<ElRow :gutter="20">
|
|
||||||
<ElCol :span="12">
|
|
||||||
<ElFormItem label="营业执照号" prop="business_license">
|
|
||||||
<ElInput v-model="form.business_license" placeholder="请输入营业执照号" />
|
|
||||||
</ElFormItem>
|
|
||||||
</ElCol>
|
|
||||||
<ElCol :span="12">
|
<ElCol :span="12">
|
||||||
<ElFormItem label="法人代表" prop="legal_person">
|
<ElFormItem label="法人代表" prop="legal_person">
|
||||||
<ElInput v-model="form.legal_person" placeholder="请输入法人代表" />
|
<ElInput v-model="form.legal_person" placeholder="请输入法人代表" />
|
||||||
@@ -86,6 +86,11 @@
|
|||||||
</ElCol>
|
</ElCol>
|
||||||
</ElRow>
|
</ElRow>
|
||||||
<ElRow :gutter="20">
|
<ElRow :gutter="20">
|
||||||
|
<ElCol :span="12">
|
||||||
|
<ElFormItem label="营业执照号" prop="business_license">
|
||||||
|
<ElInput v-model="form.business_license" placeholder="请输入营业执照号" />
|
||||||
|
</ElFormItem>
|
||||||
|
</ElCol>
|
||||||
<ElCol :span="12">
|
<ElCol :span="12">
|
||||||
<ElFormItem label="所在地区" prop="region">
|
<ElFormItem label="所在地区" prop="region">
|
||||||
<ElCascader
|
<ElCascader
|
||||||
@@ -99,6 +104,8 @@
|
|||||||
/>
|
/>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
</ElCol>
|
</ElCol>
|
||||||
|
</ElRow>
|
||||||
|
<ElRow :gutter="20">
|
||||||
<!-- 只有非代理账号才显示归属店铺选择 -->
|
<!-- 只有非代理账号才显示归属店铺选择 -->
|
||||||
<ElCol :span="12" v-if="!isAgentAccount">
|
<ElCol :span="12" v-if="!isAgentAccount">
|
||||||
<ElFormItem label="归属店铺" prop="owner_shop_id">
|
<ElFormItem label="归属店铺" prop="owner_shop_id">
|
||||||
@@ -225,6 +232,7 @@
|
|||||||
import ArtButtonTable from '@/components/core/forms/ArtButtonTable.vue'
|
import ArtButtonTable from '@/components/core/forms/ArtButtonTable.vue'
|
||||||
import ArtMenuRight from '@/components/core/others/ArtMenuRight.vue'
|
import ArtMenuRight from '@/components/core/others/ArtMenuRight.vue'
|
||||||
import TableContextMenuHint from '@/components/core/others/TableContextMenuHint.vue'
|
import TableContextMenuHint from '@/components/core/others/TableContextMenuHint.vue'
|
||||||
|
import CodeGeneratorButton from '@/components/business/CodeGeneratorButton.vue'
|
||||||
import type { MenuItemType } from '@/components/core/others/ArtMenuRight.vue'
|
import type { MenuItemType } from '@/components/core/others/ArtMenuRight.vue'
|
||||||
import { formatDateTime } from '@/utils/business/format'
|
import { formatDateTime } from '@/utils/business/format'
|
||||||
import { regionData } from '@/utils/constants/regionData'
|
import { regionData } from '@/utils/constants/regionData'
|
||||||
@@ -478,7 +486,7 @@
|
|||||||
{
|
{
|
||||||
prop: 'operation',
|
prop: 'operation',
|
||||||
label: '操作',
|
label: '操作',
|
||||||
width: 190,
|
width: 280,
|
||||||
fixed: 'right',
|
fixed: 'right',
|
||||||
formatter: (row: EnterpriseItem) => {
|
formatter: (row: EnterpriseItem) => {
|
||||||
const buttons = []
|
const buttons = []
|
||||||
@@ -501,6 +509,15 @@
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hasAuth('enterprise_customer:device_authorization')) {
|
||||||
|
buttons.push(
|
||||||
|
h(ArtButtonTable, {
|
||||||
|
text: '设备授权',
|
||||||
|
onClick: () => manageDevices(row)
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
return h('div', { style: 'display: flex; gap: 8px;' }, buttons)
|
return h('div', { style: 'display: flex; gap: 8px;' }, buttons)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -712,6 +729,11 @@
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 处理企业编码生成
|
||||||
|
const handleCodeGenerated = (code: string) => {
|
||||||
|
form.enterprise_code = code
|
||||||
|
}
|
||||||
|
|
||||||
// 提交表单
|
// 提交表单
|
||||||
const handleSubmit = async (formEl: FormInstance | undefined) => {
|
const handleSubmit = async (formEl: FormInstance | undefined) => {
|
||||||
if (!formEl) return
|
if (!formEl) return
|
||||||
@@ -810,6 +832,13 @@
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const manageDevices = (row: EnterpriseItem) => {
|
||||||
|
router.push({
|
||||||
|
path: '/asset-management/enterprise-devices',
|
||||||
|
query: { id: row.id }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// 企业客户操作菜单项配置
|
// 企业客户操作菜单项配置
|
||||||
const enterpriseOperationMenuItems = computed((): MenuItemType[] => {
|
const enterpriseOperationMenuItems = computed((): MenuItemType[] => {
|
||||||
const items: MenuItemType[] = []
|
const items: MenuItemType[] = []
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
<ArtSearchBar
|
<ArtSearchBar
|
||||||
v-model:filter="searchForm"
|
v-model:filter="searchForm"
|
||||||
:items="searchFormItems"
|
:items="searchFormItems"
|
||||||
|
:show-expand="false"
|
||||||
@reset="handleReset"
|
@reset="handleReset"
|
||||||
@search="handleSearch"
|
@search="handleSearch"
|
||||||
></ArtSearchBar>
|
></ArtSearchBar>
|
||||||
@@ -73,45 +74,55 @@
|
|||||||
<ElDialog
|
<ElDialog
|
||||||
v-model="allocateDialogVisible"
|
v-model="allocateDialogVisible"
|
||||||
:title="$t('enterpriseDevices.dialog.allocateTitle')"
|
:title="$t('enterpriseDevices.dialog.allocateTitle')"
|
||||||
width="700px"
|
width="75%"
|
||||||
@close="handleAllocateDialogClose"
|
@close="handleAllocateDialogClose"
|
||||||
>
|
>
|
||||||
<ElForm
|
<!-- 搜索过滤条件 -->
|
||||||
ref="allocateFormRef"
|
<ArtSearchBar
|
||||||
:model="allocateForm"
|
v-model:filter="deviceSearchForm"
|
||||||
:rules="allocateRules"
|
:items="deviceSearchFormItems"
|
||||||
label-width="120px"
|
label-width="85"
|
||||||
|
:show-expand="false"
|
||||||
|
@reset="handleDeviceSearchReset"
|
||||||
|
@search="handleDeviceSearch"
|
||||||
|
></ArtSearchBar>
|
||||||
|
|
||||||
|
<!-- 设备列表 -->
|
||||||
|
<div class="device-selection-info">
|
||||||
|
已选择 {{ selectedAvailableDevices.length }} 台设备
|
||||||
|
</div>
|
||||||
|
<ArtTable
|
||||||
|
ref="availableDevicesTableRef"
|
||||||
|
row-key="id"
|
||||||
|
:loading="availableDevicesLoading"
|
||||||
|
:data="availableDevicesList"
|
||||||
|
:currentPage="devicePagination.page"
|
||||||
|
:pageSize="devicePagination.pageSize"
|
||||||
|
:total="devicePagination.total"
|
||||||
|
:marginTop="10"
|
||||||
|
@size-change="handleDevicePageSizeChange"
|
||||||
|
@current-change="handleDevicePageChange"
|
||||||
|
@selection-change="handleAvailableDevicesSelectionChange"
|
||||||
>
|
>
|
||||||
<ElFormItem :label="$t('enterpriseDevices.form.deviceNos')" prop="virtual_nos">
|
<template #default>
|
||||||
<ElInput
|
<ElTableColumn type="selection" width="55" :selectable="checkDeviceSelectable" />
|
||||||
v-model="deviceNosText"
|
<ElTableColumn
|
||||||
type="textarea"
|
v-for="col in availableDeviceColumns"
|
||||||
:rows="6"
|
:key="col.prop || col.type"
|
||||||
:placeholder="$t('enterpriseDevices.form.deviceNosPlaceholder')"
|
v-bind="col"
|
||||||
@input="handleDeviceNosChange"
|
|
||||||
/>
|
/>
|
||||||
<div style="margin-top: 4px; font-size: 12px; color: var(--el-color-info)">
|
</template>
|
||||||
{{
|
</ArtTable>
|
||||||
$t('enterpriseDevices.form.selectedCount', {
|
|
||||||
count: allocateForm.virtual_nos?.length || 0
|
|
||||||
})
|
|
||||||
}}
|
|
||||||
</div>
|
|
||||||
</ElFormItem>
|
|
||||||
<ElFormItem :label="$t('enterpriseDevices.form.remark')">
|
|
||||||
<ElInput
|
|
||||||
v-model="allocateForm.remark"
|
|
||||||
type="textarea"
|
|
||||||
:rows="3"
|
|
||||||
:placeholder="$t('enterpriseDevices.form.remarkPlaceholder')"
|
|
||||||
/>
|
|
||||||
</ElFormItem>
|
|
||||||
</ElForm>
|
|
||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<div class="dialog-footer">
|
<div class="dialog-footer">
|
||||||
<ElButton @click="allocateDialogVisible = false">{{ $t('common.cancel') }}</ElButton>
|
<ElButton @click="allocateDialogVisible = false">{{ $t('common.cancel') }}</ElButton>
|
||||||
<ElButton type="primary" @click="handleAllocate" :loading="allocateLoading">
|
<ElButton
|
||||||
|
type="primary"
|
||||||
|
@click="handleAllocate"
|
||||||
|
:loading="allocateLoading"
|
||||||
|
:disabled="selectedAvailableDevices.length === 0"
|
||||||
|
>
|
||||||
{{ $t('common.confirm') }}
|
{{ $t('common.confirm') }}
|
||||||
</ElButton>
|
</ElButton>
|
||||||
</div>
|
</div>
|
||||||
@@ -225,7 +236,7 @@
|
|||||||
import { h } from 'vue'
|
import { h } from 'vue'
|
||||||
import { useRoute, useRouter } from 'vue-router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import { EnterpriseService } from '@/api/modules'
|
import { EnterpriseService, DeviceService } from '@/api/modules'
|
||||||
import { ElMessage, ElMessageBox, ElTag } from 'element-plus'
|
import { ElMessage, ElMessageBox, ElTag } from 'element-plus'
|
||||||
import type { FormInstance, FormRules } from 'element-plus'
|
import type { FormInstance, FormRules } from 'element-plus'
|
||||||
import type { SearchFormItem } from '@/types'
|
import type { SearchFormItem } from '@/types'
|
||||||
@@ -239,6 +250,7 @@
|
|||||||
FailedDeviceItem
|
FailedDeviceItem
|
||||||
} from '@/types/api/enterpriseDevice'
|
} from '@/types/api/enterpriseDevice'
|
||||||
import type { EnterpriseItem } from '@/types/api'
|
import type { EnterpriseItem } from '@/types/api'
|
||||||
|
import type { Device, DeviceStatus } from '@/types/api/device'
|
||||||
|
|
||||||
defineOptions({ name: 'EnterpriseDevices' })
|
defineOptions({ name: 'EnterpriseDevices' })
|
||||||
|
|
||||||
@@ -252,12 +264,10 @@
|
|||||||
const recallLoading = ref(false)
|
const recallLoading = ref(false)
|
||||||
const resultDialogVisible = ref(false)
|
const resultDialogVisible = ref(false)
|
||||||
const tableRef = ref()
|
const tableRef = ref()
|
||||||
const allocateFormRef = ref<FormInstance>()
|
|
||||||
const recallFormRef = ref<FormInstance>()
|
const recallFormRef = ref<FormInstance>()
|
||||||
const selectedDevices = ref<EnterpriseDeviceItem[]>([])
|
const selectedDevices = ref<EnterpriseDeviceItem[]>([])
|
||||||
const enterpriseId = ref<number>(0)
|
const enterpriseId = ref<number>(0)
|
||||||
const enterpriseInfo = ref<EnterpriseItem | null>(null)
|
const enterpriseInfo = ref<EnterpriseItem | null>(null)
|
||||||
const deviceNosText = ref('')
|
|
||||||
const operationResult = ref<AllocateDevicesResponse | RecallDevicesResponse>({
|
const operationResult = ref<AllocateDevicesResponse | RecallDevicesResponse>({
|
||||||
success_count: 0,
|
success_count: 0,
|
||||||
fail_count: 0,
|
fail_count: 0,
|
||||||
@@ -265,6 +275,28 @@
|
|||||||
authorized_devices: null
|
authorized_devices: null
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 可用设备列表相关
|
||||||
|
const availableDevicesTableRef = ref()
|
||||||
|
const availableDevicesLoading = ref(false)
|
||||||
|
const availableDevicesList = ref<Device[]>([])
|
||||||
|
const selectedAvailableDevices = ref<Device[]>([])
|
||||||
|
const allocatedDeviceVirtualNos = ref<Set<string>>(new Set())
|
||||||
|
|
||||||
|
// 设备搜索表单初始值
|
||||||
|
const initialDeviceSearchState = {
|
||||||
|
status: undefined,
|
||||||
|
virtual_no: '',
|
||||||
|
device_name: '',
|
||||||
|
shop_id: undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
const deviceSearchForm = reactive({ ...initialDeviceSearchState })
|
||||||
|
const devicePagination = reactive({
|
||||||
|
page: 1,
|
||||||
|
pageSize: 20,
|
||||||
|
total: 0
|
||||||
|
})
|
||||||
|
|
||||||
// 搜索表单初始值
|
// 搜索表单初始值
|
||||||
const initialSearchState = {
|
const initialSearchState = {
|
||||||
virtual_no: ''
|
virtual_no: ''
|
||||||
@@ -273,31 +305,6 @@
|
|||||||
// 搜索表单
|
// 搜索表单
|
||||||
const searchForm = reactive({ ...initialSearchState })
|
const searchForm = reactive({ ...initialSearchState })
|
||||||
|
|
||||||
// 授权表单
|
|
||||||
const allocateForm = reactive({
|
|
||||||
virtual_nos: [] as string[],
|
|
||||||
remark: ''
|
|
||||||
})
|
|
||||||
|
|
||||||
// 授权表单验证规则
|
|
||||||
const allocateRules = reactive<FormRules>({
|
|
||||||
virtual_nos: [
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
validator: (rule, value, callback) => {
|
|
||||||
if (!value || value.length === 0) {
|
|
||||||
callback(new Error(t('enterpriseDevices.validation.deviceNosRequired')))
|
|
||||||
} else if (value.length > 100) {
|
|
||||||
callback(new Error(t('enterpriseDevices.validation.deviceNosMaxLength')))
|
|
||||||
} else {
|
|
||||||
callback()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
trigger: 'change'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
})
|
|
||||||
|
|
||||||
// 撤销表单
|
// 撤销表单
|
||||||
const recallForm = reactive({})
|
const recallForm = reactive({})
|
||||||
|
|
||||||
@@ -324,6 +331,43 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
// 设备列表搜索表单配置
|
||||||
|
const deviceSearchFormItems: SearchFormItem[] = [
|
||||||
|
{
|
||||||
|
label: '设备状态',
|
||||||
|
prop: 'status',
|
||||||
|
type: 'select',
|
||||||
|
config: {
|
||||||
|
clearable: true,
|
||||||
|
placeholder: '全部'
|
||||||
|
},
|
||||||
|
options: () => [
|
||||||
|
{ label: '在库', value: 1 },
|
||||||
|
{ label: '已分销', value: 2 },
|
||||||
|
{ label: '已激活', value: 3 },
|
||||||
|
{ label: '已停用', value: 4 }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '设备号',
|
||||||
|
prop: 'virtual_no',
|
||||||
|
type: 'input',
|
||||||
|
config: {
|
||||||
|
clearable: true,
|
||||||
|
placeholder: '请输入设备号'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '设备名称',
|
||||||
|
prop: 'device_name',
|
||||||
|
type: 'input',
|
||||||
|
config: {
|
||||||
|
clearable: true,
|
||||||
|
placeholder: '请输入设备名称'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
// 列配置
|
// 列配置
|
||||||
const columnOptions = [
|
const columnOptions = [
|
||||||
{ label: t('enterpriseDevices.table.deviceId'), prop: 'device_id' },
|
{ label: t('enterpriseDevices.table.deviceId'), prop: 'device_id' },
|
||||||
@@ -336,6 +380,38 @@
|
|||||||
|
|
||||||
const deviceList = ref<EnterpriseDeviceItem[]>([])
|
const deviceList = ref<EnterpriseDeviceItem[]>([])
|
||||||
|
|
||||||
|
// 获取设备状态标签类型
|
||||||
|
const getDeviceStatusTag = (status: DeviceStatus) => {
|
||||||
|
switch (status) {
|
||||||
|
case 1:
|
||||||
|
return 'info'
|
||||||
|
case 2:
|
||||||
|
return 'warning'
|
||||||
|
case 3:
|
||||||
|
return 'success'
|
||||||
|
case 4:
|
||||||
|
return 'danger'
|
||||||
|
default:
|
||||||
|
return 'info'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取设备状态文本
|
||||||
|
const getDeviceStatusText = (status: DeviceStatus) => {
|
||||||
|
switch (status) {
|
||||||
|
case 1:
|
||||||
|
return '在库'
|
||||||
|
case 2:
|
||||||
|
return '已分销'
|
||||||
|
case 3:
|
||||||
|
return '已激活'
|
||||||
|
case 4:
|
||||||
|
return '已停用'
|
||||||
|
default:
|
||||||
|
return '未知'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 动态列配置
|
// 动态列配置
|
||||||
const { columnChecks, columns } = useCheckedColumns(() => [
|
const { columnChecks, columns } = useCheckedColumns(() => [
|
||||||
{
|
{
|
||||||
@@ -372,6 +448,45 @@
|
|||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
|
||||||
|
// 可用设备列表列配置
|
||||||
|
const availableDeviceColumns = computed(() => [
|
||||||
|
{
|
||||||
|
prop: 'virtual_no',
|
||||||
|
label: '设备号',
|
||||||
|
minWidth: 150
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'device_name',
|
||||||
|
label: '设备名称',
|
||||||
|
minWidth: 150
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'device_model',
|
||||||
|
label: '设备型号',
|
||||||
|
width: 120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'status',
|
||||||
|
label: '状态',
|
||||||
|
width: 100,
|
||||||
|
formatter: (row: Device) => {
|
||||||
|
return h(ElTag, { type: getDeviceStatusTag(row.status) }, () =>
|
||||||
|
getDeviceStatusText(row.status)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'shop_name',
|
||||||
|
label: '所属店铺',
|
||||||
|
width: 150
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'bound_card_count',
|
||||||
|
label: '绑定卡数',
|
||||||
|
width: 100
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
const id = route.query.id
|
const id = route.query.id
|
||||||
if (id) {
|
if (id) {
|
||||||
@@ -469,86 +584,130 @@
|
|||||||
router.back()
|
router.back()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 显示授权对话框
|
// 获取可用设备列表
|
||||||
const showAllocateDialog = () => {
|
const getAvailableDevicesList = async () => {
|
||||||
allocateDialogVisible.value = true
|
availableDevicesLoading.value = true
|
||||||
deviceNosText.value = ''
|
try {
|
||||||
allocateForm.virtual_nos = []
|
const params: any = {
|
||||||
allocateForm.remark = ''
|
page: devicePagination.page,
|
||||||
if (allocateFormRef.value) {
|
page_size: devicePagination.pageSize,
|
||||||
allocateFormRef.value.resetFields()
|
...deviceSearchForm
|
||||||
|
}
|
||||||
|
// 清理空值
|
||||||
|
Object.keys(params).forEach((key) => {
|
||||||
|
if (params[key] === '' || params[key] === undefined) {
|
||||||
|
delete params[key]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const res = await DeviceService.getDevices(params)
|
||||||
|
if (res.code === 0) {
|
||||||
|
availableDevicesList.value = res.data.items || []
|
||||||
|
devicePagination.total = res.data.total || 0
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
ElMessage.error('获取设备列表失败')
|
||||||
|
} finally {
|
||||||
|
availableDevicesLoading.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理设备号输入变化
|
// 处理设备列表选择变化
|
||||||
const handleDeviceNosChange = () => {
|
const handleAvailableDevicesSelectionChange = (selection: Device[]) => {
|
||||||
// 解析输入的设备号,支持逗号、空格、换行分隔
|
selectedAvailableDevices.value = selection
|
||||||
const deviceNos = deviceNosText.value
|
}
|
||||||
.split(/[,\s\n]+/)
|
|
||||||
.map((no) => no.trim())
|
// 设备列表搜索
|
||||||
.filter((no) => no.length > 0)
|
const handleDeviceSearch = () => {
|
||||||
allocateForm.virtual_nos = deviceNos
|
devicePagination.page = 1
|
||||||
|
getAvailableDevicesList()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设备列表重置
|
||||||
|
const handleDeviceSearchReset = () => {
|
||||||
|
Object.assign(deviceSearchForm, { ...initialDeviceSearchState })
|
||||||
|
devicePagination.page = 1
|
||||||
|
getAvailableDevicesList()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设备列表分页大小变化
|
||||||
|
const handleDevicePageSizeChange = (newPageSize: number) => {
|
||||||
|
devicePagination.pageSize = newPageSize
|
||||||
|
getAvailableDevicesList()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设备列表页码变化
|
||||||
|
const handleDevicePageChange = (newPage: number) => {
|
||||||
|
devicePagination.page = newPage
|
||||||
|
getAvailableDevicesList()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查设备是否可选(已授权的设备不可选)
|
||||||
|
const checkDeviceSelectable = (row: Device) => {
|
||||||
|
return !allocatedDeviceVirtualNos.value.has(row.virtual_no)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 显示授权对话框
|
||||||
|
const showAllocateDialog = () => {
|
||||||
|
allocateDialogVisible.value = true
|
||||||
|
selectedAvailableDevices.value = []
|
||||||
|
// 收集已授权的设备的 virtual_no
|
||||||
|
allocatedDeviceVirtualNos.value = new Set(deviceList.value.map((device) => device.virtual_no))
|
||||||
|
// 重置搜索条件
|
||||||
|
Object.assign(deviceSearchForm, { ...initialDeviceSearchState })
|
||||||
|
devicePagination.page = 1
|
||||||
|
devicePagination.pageSize = 20
|
||||||
|
// 加载可用设备列表
|
||||||
|
getAvailableDevicesList()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 执行授权
|
// 执行授权
|
||||||
const handleAllocate = async () => {
|
const handleAllocate = async () => {
|
||||||
if (!allocateFormRef.value) return
|
if (selectedAvailableDevices.value.length === 0) {
|
||||||
|
ElMessage.warning('请选择要授权的设备')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
await allocateFormRef.value.validate(async (valid) => {
|
allocateLoading.value = true
|
||||||
if (valid) {
|
try {
|
||||||
if (allocateForm.virtual_nos.length === 0) {
|
const device_nos = selectedAvailableDevices.value.map((device) => device.virtual_no)
|
||||||
ElMessage.warning(t('enterpriseDevices.messages.deviceNosEmpty'))
|
const res = await EnterpriseService.allocateDevices(enterpriseId.value, {
|
||||||
return
|
device_nos
|
||||||
}
|
})
|
||||||
|
|
||||||
if (allocateForm.virtual_nos.length > 100) {
|
if (res.code === 0) {
|
||||||
ElMessage.warning(t('enterpriseDevices.messages.deviceNosMaxLimit'))
|
operationResult.value = res.data
|
||||||
return
|
allocateDialogVisible.value = false
|
||||||
}
|
resultDialogVisible.value = true
|
||||||
|
|
||||||
allocateLoading.value = true
|
// 显示成功消息
|
||||||
try {
|
if (res.data.success_count > 0 && res.data.fail_count === 0) {
|
||||||
const res = await EnterpriseService.allocateDevices(enterpriseId.value, {
|
ElMessage.success(t('enterpriseDevices.messages.allocateSuccess'))
|
||||||
virtual_nos: allocateForm.virtual_nos,
|
} else if (res.data.success_count > 0 && res.data.fail_count > 0) {
|
||||||
remark: allocateForm.remark || undefined
|
ElMessage.warning(
|
||||||
})
|
t('enterpriseDevices.messages.allocatePartialSuccess', {
|
||||||
|
success: res.data.success_count,
|
||||||
if (res.code === 0) {
|
fail: res.data.fail_count
|
||||||
operationResult.value = res.data
|
})
|
||||||
allocateDialogVisible.value = false
|
)
|
||||||
resultDialogVisible.value = true
|
} else {
|
||||||
|
|
||||||
// 显示成功消息
|
|
||||||
if (res.data.success_count > 0 && res.data.fail_count === 0) {
|
|
||||||
ElMessage.success(t('enterpriseDevices.messages.allocateSuccess'))
|
|
||||||
} else if (res.data.success_count > 0 && res.data.fail_count > 0) {
|
|
||||||
ElMessage.warning(
|
|
||||||
t('enterpriseDevices.messages.allocatePartialSuccess', {
|
|
||||||
success: res.data.success_count,
|
|
||||||
fail: res.data.fail_count
|
|
||||||
})
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
ElMessage.error(t('enterpriseDevices.messages.allocateFailed'))
|
|
||||||
}
|
|
||||||
|
|
||||||
getTableData()
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error)
|
|
||||||
ElMessage.error(t('enterpriseDevices.messages.allocateFailed'))
|
ElMessage.error(t('enterpriseDevices.messages.allocateFailed'))
|
||||||
} finally {
|
|
||||||
allocateLoading.value = false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getTableData()
|
||||||
}
|
}
|
||||||
})
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
ElMessage.error(t('enterpriseDevices.messages.allocateFailed'))
|
||||||
|
} finally {
|
||||||
|
allocateLoading.value = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 关闭授权对话框
|
// 关闭授权对话框
|
||||||
const handleAllocateDialogClose = () => {
|
const handleAllocateDialogClose = () => {
|
||||||
if (allocateFormRef.value) {
|
selectedAvailableDevices.value = []
|
||||||
allocateFormRef.value.resetFields()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 显示撤销授权对话框
|
// 显示撤销授权对话框
|
||||||
@@ -582,7 +741,7 @@
|
|||||||
recallLoading.value = true
|
recallLoading.value = true
|
||||||
try {
|
try {
|
||||||
const res = await EnterpriseService.recallDevices(enterpriseId.value, {
|
const res = await EnterpriseService.recallDevices(enterpriseId.value, {
|
||||||
virtual_nos: selectedDevices.value.map((device) => device.virtual_no)
|
device_nos: selectedDevices.value.map((device) => device.virtual_no)
|
||||||
})
|
})
|
||||||
|
|
||||||
if (res.code === 0) {
|
if (res.code === 0) {
|
||||||
@@ -636,5 +795,12 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.device-selection-info {
|
||||||
|
margin-top: 10px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
color: var(--el-color-info);
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -83,7 +83,7 @@
|
|||||||
placeholder="请选择支付方式"
|
placeholder="请选择支付方式"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
>
|
>
|
||||||
<ElOption label="微信在线支付" value="wechat" />
|
<!--<ElOption label="微信在线支付" value="wechat" />-->
|
||||||
<!-- 只有平台用户才显示线下转账选项 -->
|
<!-- 只有平台用户才显示线下转账选项 -->
|
||||||
<ElOption
|
<ElOption
|
||||||
v-if="userStore.info.user_type === 1 || userStore.info.user_type === 2"
|
v-if="userStore.info.user_type === 1 || userStore.info.user_type === 2"
|
||||||
@@ -298,7 +298,7 @@
|
|||||||
|
|
||||||
const createForm = reactive<{ amount: number; payment_method: string; shop_id: number | null }>({
|
const createForm = reactive<{ amount: number; payment_method: string; shop_id: number | null }>({
|
||||||
amount: 100,
|
amount: 100,
|
||||||
payment_method: 'wechat',
|
payment_method: '线下转账',
|
||||||
shop_id: null
|
shop_id: null
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -537,7 +537,7 @@
|
|||||||
const handleCreateDialogClosed = () => {
|
const handleCreateDialogClosed = () => {
|
||||||
createFormRef.value?.resetFields()
|
createFormRef.value?.resetFields()
|
||||||
createForm.amount = 100
|
createForm.amount = 100
|
||||||
createForm.payment_method = 'wechat'
|
createForm.payment_method = '线下转账'
|
||||||
createForm.shop_id = null
|
createForm.shop_id = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -77,10 +77,10 @@
|
|||||||
v-model="form.provider_type"
|
v-model="form.provider_type"
|
||||||
placeholder="请选择支付渠道类型"
|
placeholder="请选择支付渠道类型"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
:disabled="dialogType === 'edit'"
|
|
||||||
@change="handleProviderTypeChange"
|
@change="handleProviderTypeChange"
|
||||||
>
|
>
|
||||||
<ElOption label="微信直连" value="wechat" />
|
<ElOption label="微信直连" value="wechat" />
|
||||||
|
<ElOption label="微信直连V2" value="wechat_v2" />
|
||||||
<ElOption label="富友支付" value="fuiou" />
|
<ElOption label="富友支付" value="fuiou" />
|
||||||
</ElSelect>
|
</ElSelect>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
@@ -96,7 +96,7 @@
|
|||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
|
|
||||||
<!-- 微信相关配置 -->
|
<!-- 微信相关配置 -->
|
||||||
<template v-if="form.provider_type === 'wechat'">
|
<template v-if="form.provider_type === 'wechat' || form.provider_type === 'wechat_v2'">
|
||||||
<ElDivider content-position="left">
|
<ElDivider content-position="left">
|
||||||
<span class="divider-title">小程序配置</span>
|
<span class="divider-title">小程序配置</span>
|
||||||
</ElDivider>
|
</ElDivider>
|
||||||
@@ -106,7 +106,6 @@
|
|||||||
<ElInput
|
<ElInput
|
||||||
v-model="form.miniapp_app_id"
|
v-model="form.miniapp_app_id"
|
||||||
placeholder="请输入小程序AppID"
|
placeholder="请输入小程序AppID"
|
||||||
:disabled="dialogType === 'edit'"
|
|
||||||
/>
|
/>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
</ElCol>
|
</ElCol>
|
||||||
@@ -131,7 +130,6 @@
|
|||||||
<ElInput
|
<ElInput
|
||||||
v-model="form.oa_app_id"
|
v-model="form.oa_app_id"
|
||||||
placeholder="请输入公众号AppID"
|
placeholder="请输入公众号AppID"
|
||||||
:disabled="dialogType === 'edit'"
|
|
||||||
/>
|
/>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
</ElCol>
|
</ElCol>
|
||||||
@@ -172,7 +170,6 @@
|
|||||||
<ElInput
|
<ElInput
|
||||||
v-model="form.oa_oauth_redirect_url"
|
v-model="form.oa_oauth_redirect_url"
|
||||||
placeholder="请输入OAuth回调地址"
|
placeholder="请输入OAuth回调地址"
|
||||||
:disabled="dialogType === 'edit'"
|
|
||||||
/>
|
/>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
|
|
||||||
@@ -185,7 +182,6 @@
|
|||||||
<ElInput
|
<ElInput
|
||||||
v-model="form.wx_mch_id"
|
v-model="form.wx_mch_id"
|
||||||
placeholder="请输入微信商户号"
|
placeholder="请输入微信商户号"
|
||||||
:disabled="dialogType === 'edit'"
|
|
||||||
/>
|
/>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
</ElCol>
|
</ElCol>
|
||||||
@@ -194,7 +190,6 @@
|
|||||||
<ElInput
|
<ElInput
|
||||||
v-model="form.wx_serial_no"
|
v-model="form.wx_serial_no"
|
||||||
placeholder="请输入微信证书序列号"
|
placeholder="请输入微信证书序列号"
|
||||||
:disabled="dialogType === 'edit'"
|
|
||||||
/>
|
/>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
</ElCol>
|
</ElCol>
|
||||||
@@ -225,7 +220,6 @@
|
|||||||
<ElInput
|
<ElInput
|
||||||
v-model="form.wx_notify_url"
|
v-model="form.wx_notify_url"
|
||||||
placeholder="请输入微信支付回调地址"
|
placeholder="请输入微信支付回调地址"
|
||||||
:disabled="dialogType === 'edit'"
|
|
||||||
/>
|
/>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
<ElRow :gutter="20">
|
<ElRow :gutter="20">
|
||||||
@@ -261,7 +255,6 @@
|
|||||||
<ElInput
|
<ElInput
|
||||||
v-model="form.miniapp_app_id"
|
v-model="form.miniapp_app_id"
|
||||||
placeholder="请输入小程序AppID"
|
placeholder="请输入小程序AppID"
|
||||||
:disabled="dialogType === 'edit'"
|
|
||||||
/>
|
/>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
</ElCol>
|
</ElCol>
|
||||||
@@ -286,7 +279,6 @@
|
|||||||
<ElInput
|
<ElInput
|
||||||
v-model="form.oa_app_id"
|
v-model="form.oa_app_id"
|
||||||
placeholder="请输入公众号AppID"
|
placeholder="请输入公众号AppID"
|
||||||
:disabled="dialogType === 'edit'"
|
|
||||||
/>
|
/>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
</ElCol>
|
</ElCol>
|
||||||
@@ -327,7 +319,6 @@
|
|||||||
<ElInput
|
<ElInput
|
||||||
v-model="form.oa_oauth_redirect_url"
|
v-model="form.oa_oauth_redirect_url"
|
||||||
placeholder="请输入OAuth回调地址"
|
placeholder="请输入OAuth回调地址"
|
||||||
:disabled="dialogType === 'edit'"
|
|
||||||
/>
|
/>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
|
|
||||||
@@ -340,7 +331,6 @@
|
|||||||
<ElInput
|
<ElInput
|
||||||
v-model="form.wx_mch_id"
|
v-model="form.wx_mch_id"
|
||||||
placeholder="请输入微信商户号"
|
placeholder="请输入微信商户号"
|
||||||
:disabled="dialogType === 'edit'"
|
|
||||||
/>
|
/>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
</ElCol>
|
</ElCol>
|
||||||
@@ -349,7 +339,6 @@
|
|||||||
<ElInput
|
<ElInput
|
||||||
v-model="form.wx_serial_no"
|
v-model="form.wx_serial_no"
|
||||||
placeholder="请输入微信证书序列号"
|
placeholder="请输入微信证书序列号"
|
||||||
:disabled="dialogType === 'edit'"
|
|
||||||
/>
|
/>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
</ElCol>
|
</ElCol>
|
||||||
@@ -380,7 +369,6 @@
|
|||||||
<ElInput
|
<ElInput
|
||||||
v-model="form.wx_notify_url"
|
v-model="form.wx_notify_url"
|
||||||
placeholder="请输入微信支付回调地址"
|
placeholder="请输入微信支付回调地址"
|
||||||
:disabled="dialogType === 'edit'"
|
|
||||||
/>
|
/>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
<ElRow :gutter="20">
|
<ElRow :gutter="20">
|
||||||
@@ -415,7 +403,6 @@
|
|||||||
<ElInput
|
<ElInput
|
||||||
v-model="form.fy_api_url"
|
v-model="form.fy_api_url"
|
||||||
placeholder="请输入富友API地址"
|
placeholder="请输入富友API地址"
|
||||||
:disabled="dialogType === 'edit'"
|
|
||||||
/>
|
/>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
</ElCol>
|
</ElCol>
|
||||||
@@ -424,7 +411,6 @@
|
|||||||
<ElInput
|
<ElInput
|
||||||
v-model="form.fy_ins_cd"
|
v-model="form.fy_ins_cd"
|
||||||
placeholder="请输入富友机构号"
|
placeholder="请输入富友机构号"
|
||||||
:disabled="dialogType === 'edit'"
|
|
||||||
/>
|
/>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
</ElCol>
|
</ElCol>
|
||||||
@@ -435,7 +421,6 @@
|
|||||||
<ElInput
|
<ElInput
|
||||||
v-model="form.fy_mchnt_cd"
|
v-model="form.fy_mchnt_cd"
|
||||||
placeholder="请输入富友商户号"
|
placeholder="请输入富友商户号"
|
||||||
:disabled="dialogType === 'edit'"
|
|
||||||
/>
|
/>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
</ElCol>
|
</ElCol>
|
||||||
@@ -444,7 +429,6 @@
|
|||||||
<ElInput
|
<ElInput
|
||||||
v-model="form.fy_term_id"
|
v-model="form.fy_term_id"
|
||||||
placeholder="请输入富友终端号"
|
placeholder="请输入富友终端号"
|
||||||
:disabled="dialogType === 'edit'"
|
|
||||||
/>
|
/>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
</ElCol>
|
</ElCol>
|
||||||
@@ -453,7 +437,6 @@
|
|||||||
<ElInput
|
<ElInput
|
||||||
v-model="form.fy_notify_url"
|
v-model="form.fy_notify_url"
|
||||||
placeholder="请输入富友支付回调地址"
|
placeholder="请输入富友支付回调地址"
|
||||||
:disabled="dialogType === 'edit'"
|
|
||||||
/>
|
/>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
<ElRow :gutter="20">
|
<ElRow :gutter="20">
|
||||||
@@ -551,6 +534,7 @@
|
|||||||
placeholder: '请选择支付渠道类型',
|
placeholder: '请选择支付渠道类型',
|
||||||
options: [
|
options: [
|
||||||
{ label: '微信直连', value: 'wechat' },
|
{ label: '微信直连', value: 'wechat' },
|
||||||
|
{ label: '微信直连V2', value: 'wechat_v2' },
|
||||||
{ label: '富友支付', value: 'fuiou' }
|
{ label: '富友支付', value: 'fuiou' }
|
||||||
],
|
],
|
||||||
config: {
|
config: {
|
||||||
@@ -607,55 +591,15 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 自定义验证器 - 编辑模式下允许为空,新增模式下必填
|
// 静态验证规则 - 只有配置名称和支付渠道类型是必填的
|
||||||
const createRequiredValidator = (fieldName: string) => {
|
|
||||||
return (rule: any, value: any, callback: any) => {
|
|
||||||
if (dialogType.value === 'add' && !value) {
|
|
||||||
callback(new Error(`请输入${fieldName}`))
|
|
||||||
} else {
|
|
||||||
callback()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 静态验证规则 - 一次性定义所有规则
|
|
||||||
const rules = reactive<FormRules>({
|
const rules = reactive<FormRules>({
|
||||||
name: [{ required: true, message: '请输入配置名称', trigger: 'blur' }],
|
name: [{ required: true, message: '请输入配置名称', trigger: 'blur' }],
|
||||||
provider_type: [{ required: true, message: '请选择支付渠道类型', trigger: 'change' }],
|
provider_type: [{ required: true, message: '请选择支付渠道类型', trigger: 'change' }],
|
||||||
// 所有字段的验证规则都定义好
|
// 其他字段都是可选的,只验证URL格式
|
||||||
miniapp_app_id: [{ required: true, validator: createRequiredValidator('小程序AppID'), trigger: 'blur' }],
|
oa_oauth_redirect_url: [{ validator: urlValidator, trigger: 'blur' }],
|
||||||
miniapp_app_secret: [{ required: true, validator: createRequiredValidator('小程序AppSecret'), trigger: 'blur' }],
|
wx_notify_url: [{ validator: urlValidator, trigger: 'blur' }],
|
||||||
oa_app_id: [{ required: true, validator: createRequiredValidator('公众号AppID'), trigger: 'blur' }],
|
fy_api_url: [{ validator: urlValidator, trigger: 'blur' }],
|
||||||
oa_app_secret: [{ required: true, validator: createRequiredValidator('公众号AppSecret'), trigger: 'blur' }],
|
fy_notify_url: [{ validator: urlValidator, trigger: 'blur' }]
|
||||||
oa_token: [{ required: true, validator: createRequiredValidator('公众号Token'), trigger: 'blur' }],
|
|
||||||
oa_aes_key: [{ required: true, validator: createRequiredValidator('公众号AES Key'), trigger: 'blur' }],
|
|
||||||
oa_oauth_redirect_url: [
|
|
||||||
{ required: true, validator: createRequiredValidator('OAuth回调地址'), trigger: 'blur' },
|
|
||||||
{ validator: urlValidator, trigger: 'blur' }
|
|
||||||
],
|
|
||||||
wx_mch_id: [{ required: true, validator: createRequiredValidator('微信商户号'), trigger: 'blur' }],
|
|
||||||
wx_api_v2_key: [{ required: true, validator: createRequiredValidator('微信APIv2密钥'), trigger: 'blur' }],
|
|
||||||
wx_api_v3_key: [{ required: true, validator: createRequiredValidator('微信APIv3密钥'), trigger: 'blur' }],
|
|
||||||
wx_serial_no: [{ required: true, validator: createRequiredValidator('微信证书序列号'), trigger: 'blur' }],
|
|
||||||
wx_cert_content: [{ required: true, validator: createRequiredValidator('微信支付证书内容'), trigger: 'blur' }],
|
|
||||||
wx_key_content: [{ required: true, validator: createRequiredValidator('微信支付密钥内容'), trigger: 'blur' }],
|
|
||||||
wx_notify_url: [
|
|
||||||
{ required: true, validator: createRequiredValidator('微信支付回调地址'), trigger: 'blur' },
|
|
||||||
{ validator: urlValidator, trigger: 'blur' }
|
|
||||||
],
|
|
||||||
fy_api_url: [
|
|
||||||
{ required: true, validator: createRequiredValidator('富友API地址'), trigger: 'blur' },
|
|
||||||
{ validator: urlValidator, trigger: 'blur' }
|
|
||||||
],
|
|
||||||
fy_ins_cd: [{ required: true, validator: createRequiredValidator('富友机构号'), trigger: 'blur' }],
|
|
||||||
fy_mchnt_cd: [{ required: true, validator: createRequiredValidator('富友商户号'), trigger: 'blur' }],
|
|
||||||
fy_term_id: [{ required: true, validator: createRequiredValidator('富友终端号'), trigger: 'blur' }],
|
|
||||||
fy_private_key: [{ required: true, validator: createRequiredValidator('富友私钥'), trigger: 'blur' }],
|
|
||||||
fy_public_key: [{ required: true, validator: createRequiredValidator('富友公钥'), trigger: 'blur' }],
|
|
||||||
fy_notify_url: [
|
|
||||||
{ required: true, validator: createRequiredValidator('富友支付回调地址'), trigger: 'blur' },
|
|
||||||
{ validator: urlValidator, trigger: 'blur' }
|
|
||||||
]
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const form = reactive({
|
const form = reactive({
|
||||||
@@ -721,6 +665,7 @@
|
|||||||
const getProviderTypeText = (type: PaymentProviderType): string => {
|
const getProviderTypeText = (type: PaymentProviderType): string => {
|
||||||
const typeMap: Record<PaymentProviderType, string> = {
|
const typeMap: Record<PaymentProviderType, string> = {
|
||||||
wechat: '微信直连',
|
wechat: '微信直连',
|
||||||
|
wechat_v2: '微信直连V2',
|
||||||
fuiou: '富友支付'
|
fuiou: '富友支付'
|
||||||
}
|
}
|
||||||
return typeMap[type] || type
|
return typeMap[type] || type
|
||||||
@@ -728,7 +673,7 @@
|
|||||||
|
|
||||||
// 获取商户号
|
// 获取商户号
|
||||||
const getMerchantId = (row: WechatConfig): string => {
|
const getMerchantId = (row: WechatConfig): string => {
|
||||||
if (row.provider_type === 'wechat') {
|
if (row.provider_type === 'wechat' || row.provider_type === 'wechat_v2') {
|
||||||
return row.wx_mch_id || '-'
|
return row.wx_mch_id || '-'
|
||||||
}
|
}
|
||||||
if (row.provider_type === 'fuiou') {
|
if (row.provider_type === 'fuiou') {
|
||||||
@@ -739,7 +684,7 @@
|
|||||||
|
|
||||||
// 获取支付回调地址
|
// 获取支付回调地址
|
||||||
const getNotifyUrl = (row: WechatConfig): string => {
|
const getNotifyUrl = (row: WechatConfig): string => {
|
||||||
if (row.provider_type === 'wechat') {
|
if (row.provider_type === 'wechat' || row.provider_type === 'wechat_v2') {
|
||||||
return row.wx_notify_url || '-'
|
return row.wx_notify_url || '-'
|
||||||
}
|
}
|
||||||
if (row.provider_type === 'fuiou') {
|
if (row.provider_type === 'fuiou') {
|
||||||
|
|||||||
Reference in New Issue
Block a user