|
|
@@ -88,6 +88,7 @@
|
|
|
<div class="ops-row">
|
|
|
<AppButton type="ghost" size="sm" @click="goView(row)">查看数据</AppButton>
|
|
|
<AppButton type="ghost" size="sm" @click="openEdit(row)">编辑</AppButton>
|
|
|
+ <AppButton v-if="canDelete" type="danger" size="sm" @click="askDelete(row)">删除</AppButton>
|
|
|
</div>
|
|
|
</td>
|
|
|
</tr>
|
|
|
@@ -200,22 +201,38 @@
|
|
|
<AppButton type="primary" size="sm" :loading="submitting" @click="submitForm">保存</AppButton>
|
|
|
</template>
|
|
|
</AppModal>
|
|
|
+
|
|
|
+ <!-- 删除确认 -->
|
|
|
+ <AppConfirm
|
|
|
+ v-model="confirmOpen"
|
|
|
+ title="删除指标"
|
|
|
+ :message="`确认删除指标 #${confirmRow?.id ?? ''} ${confirmRow?.name || ''}?该指标的全部时序值将一并删除,此操作不可恢复。`"
|
|
|
+ ok-text="删除"
|
|
|
+ type="danger"
|
|
|
+ :loading="confirmLoading"
|
|
|
+ @ok="doDelete"
|
|
|
+ />
|
|
|
</AdminPage>
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
|
import { computed, onMounted, reactive, ref } from 'vue'
|
|
|
import { useRouter } from 'vue-router'
|
|
|
+import { useAuth } from '@/store/auth'
|
|
|
import AdminPage from '@/components/common/AdminPage.vue'
|
|
|
import AppButton from '@/components/common/AppButton.vue'
|
|
|
import AppModal from '@/components/common/AppModal.vue'
|
|
|
+import AppConfirm from '@/components/common/AppConfirm.vue'
|
|
|
import FormField from '@/components/common/FormField.vue'
|
|
|
import { useToast } from '@/composables/useToast'
|
|
|
-import { listIndicators, createIndicator, updateIndicator } from '@/api/indicator'
|
|
|
+import { listIndicators, createIndicator, updateIndicator, deleteIndicator } from '@/api/indicator'
|
|
|
import { HttpError } from '@/utils/http'
|
|
|
|
|
|
const router = useRouter()
|
|
|
const toast = useToast()
|
|
|
+const { hasPermission, hasRole } = useAuth()
|
|
|
+
|
|
|
+const canDelete = computed(() => hasRole('ADMIN') && hasPermission('indicator:delete'))
|
|
|
|
|
|
const list = ref([])
|
|
|
const loading = ref(false)
|
|
|
@@ -226,9 +243,17 @@ const filters = reactive({
|
|
|
keyword: '',
|
|
|
})
|
|
|
|
|
|
-const CATEGORIES = ['GDP', '投资', '出口', '消费', '通胀', '供给', '景气度']
|
|
|
-const REGIONS = ['中国', '美国']
|
|
|
-const FREQUENCIES = ['日', '周', '月', '季', '年']
|
|
|
+function uniqueValues(key) {
|
|
|
+ const set = new Set()
|
|
|
+ for (const it of list.value) {
|
|
|
+ const v = it[key]
|
|
|
+ if (v !== null && v !== undefined && v !== '') set.add(v)
|
|
|
+ }
|
|
|
+ return Array.from(set)
|
|
|
+}
|
|
|
+const CATEGORIES = computed(() => uniqueValues('category'))
|
|
|
+const REGIONS = computed(() => uniqueValues('region'))
|
|
|
+const FREQUENCIES = computed(() => uniqueValues('frequency'))
|
|
|
|
|
|
const formOpen = ref(false)
|
|
|
const formMode = ref('create')
|
|
|
@@ -296,11 +321,7 @@ const categoryStats = computed(() => {
|
|
|
async function reload() {
|
|
|
loading.value = true
|
|
|
try {
|
|
|
- const params = {}
|
|
|
- if (filters.category) params.category = filters.category
|
|
|
- if (filters.region) params.region = filters.region
|
|
|
- if (filters.frequency) params.frequency = filters.frequency
|
|
|
- const data = await listIndicators(params)
|
|
|
+ const data = await listIndicators()
|
|
|
list.value = Array.isArray(data) ? data.slice() : []
|
|
|
} catch (err) {
|
|
|
if (err instanceof HttpError) toast.error(err.message || '加载元数据失败')
|
|
|
@@ -432,6 +453,38 @@ async function submitForm() {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+// ===== 删除 =====
|
|
|
+const confirmOpen = ref(false)
|
|
|
+const confirmRow = ref(null)
|
|
|
+const confirmLoading = ref(false)
|
|
|
+
|
|
|
+function askDelete(row) {
|
|
|
+ if (!canDelete.value) {
|
|
|
+ toast.warning('无删除权限(需 indicator:delete)')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ confirmRow.value = row
|
|
|
+ confirmOpen.value = true
|
|
|
+}
|
|
|
+
|
|
|
+async function doDelete() {
|
|
|
+ if (!confirmRow.value) return
|
|
|
+ confirmLoading.value = true
|
|
|
+ try {
|
|
|
+ const res = await deleteIndicator(confirmRow.value.id)
|
|
|
+ const values = res?.valuesDeleted
|
|
|
+ toast.success(`已删除 #${confirmRow.value.id}${values != null ? ` · 时序值 ${values} 条` : ''}`)
|
|
|
+ confirmOpen.value = false
|
|
|
+ confirmRow.value = null
|
|
|
+ await reload()
|
|
|
+ } catch (err) {
|
|
|
+ if (err instanceof HttpError) toast.error(err.message || '删除失败')
|
|
|
+ else toast.error('删除失败')
|
|
|
+ } finally {
|
|
|
+ confirmLoading.value = false
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
onMounted(reload)
|
|
|
</script>
|
|
|
|