chore: establish V1.1 recovery baseline

This commit is contained in:
2026-09-09 22:05:00 +08:00
commit b46b48eb33
947 changed files with 155471 additions and 0 deletions
@@ -0,0 +1,140 @@
<template>
<div class="page-container">
<el-card shadow="never">
<template #header>
<div class="card-header">
<span>机构管理</span>
<el-button type="primary" @click="openCreate">新增机构</el-button>
</div>
</template>
<el-table :data="tableData" v-loading="loading" border stripe>
<el-table-column prop="name" label="机构名称" width="200" />
<el-table-column prop="type" label="机构类型" width="140">
<template #default="{row}">{{ orgTypeText(row.type) }}</template>
</el-table-column>
<el-table-column prop="contactName" label="联系人" width="120" />
<el-table-column prop="status" label="状态" width="100">
<template #default="{row}">
<el-tag :type="row.status==='normal'?'success':'danger'">{{ row.status==='normal'?'正常':'已停用' }}</el-tag>
</template>
</el-table-column>
<el-table-column prop="createdAt" label="创建时间" width="180">
<template #default="{row}">{{ formatTime(row.createdAt) }}</template>
</el-table-column>
<el-table-column label="操作" width="180">
<template #default="{row}">
<el-button size="small" @click="openEdit(row)">编辑</el-button>
<el-button size="small" :type="row.status==='normal'?'warning':'success'"
@click="toggleStatus(row)">{{ row.status==='normal'?'停用':'启用' }}</el-button>
</template>
</el-table-column>
</el-table>
</el-card>
<!-- 新增/编辑对话框 -->
<el-dialog v-model="formVisible" :title="editId ? '编辑机构' : '新增机构'" width="480px">
<el-form :model="form" label-width="100px">
<el-form-item label="机构名称">
<el-input v-model="form.name" />
</el-form-item>
<el-form-item label="机构类型">
<el-select v-model="form.type" style="width:100%">
<el-option label="妇联" value="fulian" />
<el-option label="工会" value="gonghui" />
<el-option label="公益服务中心" value="public_service" />
<el-option label="志愿者团队" value="volunteer" />
<el-option label="其他合作机构" value="other" />
</el-select>
</el-form-item>
<el-form-item label="联系人">
<el-input v-model="form.contactName" />
</el-form-item>
</el-form>
<template #footer>
<el-button @click="formVisible=false">取消</el-button>
<el-button type="primary" :loading="saving" @click="save">保存</el-button>
</template>
</el-dialog>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { get, post, put } from '@/api/client'
const loading = ref(false)
const tableData = ref<any[]>([])
const formVisible = ref(false)
const editId = ref('')
const form = ref({ name: '', type: '', contactName: '' })
const saving = ref(false)
const ORG_TYPE_TEXT: Record<string, string> = {
fulian: '妇联', gonghui: '工会', public_service: '公益服务中心',
volunteer: '志愿者团队', other: '其他合作机构'
}
async function loadData() {
loading.value = true
try {
const token = localStorage.getItem('accessToken')
const res: any = await get('/operator/organizations', {}, { Authorization: `Bearer ${token}` })
tableData.value = res || []
} catch (e) { console.error(e) }
finally { loading.value = false }
}
function openCreate() {
editId.value = ''
form.value = { name: '', type: 'fulian', contactName: '' }
formVisible.value = true
}
function openEdit(row: any) {
editId.value = row.id
form.value = { name: row.name, type: row.type, contactName: row.contactName || '' }
formVisible.value = true
}
async function save() {
if (!form.value.name) return
saving.value = true
try {
const token = localStorage.getItem('accessToken')
if (editId.value) {
await put(`/operator/organizations/${editId.value}`, form.value, {
Authorization: `Bearer ${token}`
})
} else {
await post('/operator/organizations', form.value, {
Authorization: `Bearer ${token}`
})
}
formVisible.value = false
loadData()
} catch (e) { console.error(e) }
finally { saving.value = false }
}
async function toggleStatus(row: any) {
try {
const token = localStorage.getItem('accessToken')
const action = row.status === 'normal' ? 'disable' : 'enable'
await put(`/operator/organizations/${row.id}/${action}`, {}, {
Authorization: `Bearer ${token}`
})
loadData()
} catch (e) { console.error(e) }
}
function orgTypeText(t?: string) { return t && ORG_TYPE_TEXT[t] ? ORG_TYPE_TEXT[t] : (t || '-') }
function formatTime(t?: string) { return t ? new Date(t).toLocaleString('zh-CN') : '-' }
onMounted(loadData)
</script>
<style scoped>
.page-container { padding: 24px; }
.card-header { display: flex; justify-content: space-between; align-items: center; }
</style>