feat(license): 支持在租户平台修改 License 过期时间
描述详情框中的过期时间行增加内联日期选择器,与最大设备数保持 相同的行内编辑交互,支持设置具体日期或留空(永久有效)。 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
这个提交包含在:
父节点
c4373c8cc1
当前提交
f3c58866df
@ -104,7 +104,7 @@ export const licenseApi = {
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
||||||
updateAppLicense(appKey: string, data: { maxDevices?: number; isActive?: boolean; remark?: string }) {
|
updateAppLicense(appKey: string, data: { maxDevices?: number; isActive?: boolean; remark?: string; expiresAt?: string }) {
|
||||||
return licenseClient.patch<{ data: AppLicense }>(
|
return licenseClient.patch<{ data: AppLicense }>(
|
||||||
`/api/license/admin/apps/${encodeURIComponent(appKey)}`,
|
`/api/license/admin/apps/${encodeURIComponent(appKey)}`,
|
||||||
data,
|
data,
|
||||||
|
|||||||
@ -64,7 +64,22 @@
|
|||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="已注册设备">{{ license?.registeredDevices ?? devices.length }}</el-descriptions-item>
|
<el-descriptions-item label="已注册设备">{{ license?.registeredDevices ?? devices.length }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="过期时间">
|
<el-descriptions-item label="过期时间">
|
||||||
{{ license?.expiresAt ? formatDate(license.expiresAt) : '永久' }}
|
<div v-if="!editingExpiresAt" class="max-devices-display">
|
||||||
|
<span>{{ license?.expiresAt ? formatDate(license.expiresAt) : '永久' }}</span>
|
||||||
|
<el-button link type="primary" size="small" style="margin-left:8px" @click="startEditExpiresAt">修改</el-button>
|
||||||
|
</div>
|
||||||
|
<div v-else class="max-devices-edit">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="editExpiresAtValue"
|
||||||
|
type="datetime"
|
||||||
|
placeholder="留空表示永久"
|
||||||
|
clearable
|
||||||
|
style="width:200px"
|
||||||
|
size="small"
|
||||||
|
/>
|
||||||
|
<el-button type="primary" size="small" :loading="savingExpiresAt" style="margin-left:8px" @click="saveExpiresAt">保存</el-button>
|
||||||
|
<el-button size="small" style="margin-left:4px" @click="editingExpiresAt = false">取消</el-button>
|
||||||
|
</div>
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
</div>
|
</div>
|
||||||
@ -163,6 +178,9 @@ const loading = ref(false)
|
|||||||
const editingMaxDevices = ref(false)
|
const editingMaxDevices = ref(false)
|
||||||
const editMaxDevicesValue = ref(1)
|
const editMaxDevicesValue = ref(1)
|
||||||
const savingMaxDevices = ref(false)
|
const savingMaxDevices = ref(false)
|
||||||
|
const editingExpiresAt = ref(false)
|
||||||
|
const editExpiresAtValue = ref<Date | null>(null)
|
||||||
|
const savingExpiresAt = ref(false)
|
||||||
|
|
||||||
const appName = computed(() => currentApp.value?.name || license.value?.name || appKey.value || '-')
|
const appName = computed(() => currentApp.value?.name || license.value?.name || appKey.value || '-')
|
||||||
const activeDevices = computed(() => devices.value.filter(d => d.isActive).length)
|
const activeDevices = computed(() => devices.value.filter(d => d.isActive).length)
|
||||||
@ -213,6 +231,28 @@ async function saveMaxDevices() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function startEditExpiresAt() {
|
||||||
|
editExpiresAtValue.value = license.value?.expiresAt ? new Date(license.value.expiresAt) : null
|
||||||
|
editingExpiresAt.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
async function saveExpiresAt() {
|
||||||
|
const key = appKey.value
|
||||||
|
if (!key) return
|
||||||
|
savingExpiresAt.value = true
|
||||||
|
try {
|
||||||
|
const expiresAt = editExpiresAtValue.value ? editExpiresAtValue.value.toISOString() : ''
|
||||||
|
const res = await licenseApi.updateAppLicense(key, { expiresAt })
|
||||||
|
license.value = res.data.data
|
||||||
|
editingExpiresAt.value = false
|
||||||
|
ElMessage.success('过期时间已更新')
|
||||||
|
} catch {
|
||||||
|
ElMessage.error('更新失败')
|
||||||
|
} finally {
|
||||||
|
savingExpiresAt.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function revokeDevice(row: LicenseDevice) {
|
async function revokeDevice(row: LicenseDevice) {
|
||||||
try {
|
try {
|
||||||
await ElMessageBox.confirm('确认吊销该设备?', '吊销确认', { type: 'warning' })
|
await ElMessageBox.confirm('确认吊销该设备?', '吊销确认', { type: 'warning' })
|
||||||
|
|||||||
正在加载...
在新工单中引用
屏蔽一个用户