|
|
@@ -0,0 +1,248 @@
|
|
|
+<template>
|
|
|
+ <div class="org-detail">
|
|
|
+ <el-card>
|
|
|
+ <PageHeader slot="header" :title="'组织详情 — ' + (org.name || '')">
|
|
|
+ <el-button size="mini" @click="$router.push('/org')">返回列表</el-button>
|
|
|
+ </PageHeader>
|
|
|
+
|
|
|
+ <el-descriptions :column="3" border v-if="org.id">
|
|
|
+ <el-descriptions-item label="ID">{{ org.id }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="组织编号">{{ org.code }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="类型">{{ typeLabel(org.type) }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="联系人">{{ org.contactName || '-' }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="联系电话">{{ org.contactPhone || '-' }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="状态">
|
|
|
+ <StatusTag :type="org.status === 'active' ? 'success' : 'danger'"
|
|
|
+ :text="org.status === 'active' ? '启用' : '停用'" />
|
|
|
+ </el-descriptions-item>
|
|
|
+ <el-descriptions-item label="简介" :span="3">{{ org.description || '-' }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="创建时间">{{ formatTime(org.createdAt) }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="查看大屏">
|
|
|
+ <el-button size="mini" type="text" @click="$router.push('/org/' + org.id + '/dashboard')">统计大屏</el-button>
|
|
|
+ </el-descriptions-item>
|
|
|
+ </el-descriptions>
|
|
|
+ </el-card>
|
|
|
+
|
|
|
+ <el-card style="margin-top: 15px">
|
|
|
+ <PageHeader slot="header" title="组织成员">
|
|
|
+ <el-button type="primary" size="small" @click="showAddDialog">+ 添加成员</el-button>
|
|
|
+ </PageHeader>
|
|
|
+
|
|
|
+ <div class="adm-table-wrap">
|
|
|
+ <el-table :data="members" stripe v-loading="memberLoading" height="100%">
|
|
|
+ <el-table-column prop="userId" label="用户ID" width="100"></el-table-column>
|
|
|
+ <el-table-column prop="nickname" label="昵称" min-width="140"></el-table-column>
|
|
|
+ <el-table-column prop="phone" label="手机号" width="140"></el-table-column>
|
|
|
+ <el-table-column label="类型" width="100">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <StatusTag :type="scope.row.memberType === 'planner' ? 'primary' : 'info'"
|
|
|
+ :text="scope.row.memberType === 'planner' ? '规划师' : '普通用户'" />
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="familyCount" label="家庭数" width="90"></el-table-column>
|
|
|
+ <el-table-column prop="totalOrders" label="订单数" width="90"></el-table-column>
|
|
|
+ <el-table-column prop="totalConsumption" label="消费总额(分)" width="130"></el-table-column>
|
|
|
+ <el-table-column prop="joinedAt" label="加入时间" width="170">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ {{ formatTime(scope.row.joinedAt) }}
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="操作" width="170" fixed="right">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <el-button size="mini" type="primary" @click="openChangeType(scope.row)">改类型</el-button>
|
|
|
+ <el-button size="mini" type="danger" @click="removeMember(scope.row)">移除</el-button>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ </div>
|
|
|
+ </el-card>
|
|
|
+
|
|
|
+ <!-- 添加成员对话框 -->
|
|
|
+ <el-dialog title="添加成员" :visible.sync="addDialogVisible" width="460px" :close-on-click-modal="false">
|
|
|
+ <el-form label-width="100px">
|
|
|
+ <el-form-item label="搜索用户">
|
|
|
+ <el-select v-model="addForm.userId" filterable remote placeholder="按手机号/昵称搜索平台用户"
|
|
|
+ :remote-method="searchUsers" :loading="searchLoading" style="width: 100%">
|
|
|
+ <el-option v-for="item in searchResults" :key="item.id"
|
|
|
+ :label="item.nickname + ' (' + item.phone + ')'" :value="item.id" />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="成员类型">
|
|
|
+ <el-radio-group v-model="addForm.memberType">
|
|
|
+ <el-radio label="planner">规划师</el-radio>
|
|
|
+ <el-radio label="user">普通用户</el-radio>
|
|
|
+ </el-radio-group>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ <div slot="footer">
|
|
|
+ <el-button @click="addDialogVisible = false">取消</el-button>
|
|
|
+ <el-button type="primary" @click="submitAddMember" :loading="adding">确定</el-button>
|
|
|
+ </div>
|
|
|
+ </el-dialog>
|
|
|
+
|
|
|
+ <!-- 变更类型对话框 -->
|
|
|
+ <el-dialog title="变更成员类型" :visible.sync="changeTypeVisible" width="400px" :close-on-click-modal="false">
|
|
|
+ <el-form label-width="100px">
|
|
|
+ <el-form-item label="成员类型">
|
|
|
+ <el-radio-group v-model="changeTypeForm.memberType">
|
|
|
+ <el-radio label="planner">规划师</el-radio>
|
|
|
+ <el-radio label="user">普通用户</el-radio>
|
|
|
+ </el-radio-group>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ <div slot="footer">
|
|
|
+ <el-button @click="changeTypeVisible = false">取消</el-button>
|
|
|
+ <el-button type="primary" @click="submitChangeType" :loading="changing">确定</el-button>
|
|
|
+ </div>
|
|
|
+ </el-dialog>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import { orgDetail, orgMemberList, orgMemberAdd, orgMemberRemove, orgMemberChangeType, orgUserSearch } from '@/api/org'
|
|
|
+
|
|
|
+export default {
|
|
|
+ name: 'OrgDetail',
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ org: {},
|
|
|
+ members: [],
|
|
|
+ memberLoading: false,
|
|
|
+ addDialogVisible: false,
|
|
|
+ searchLoading: false,
|
|
|
+ searchResults: [],
|
|
|
+ addForm: { userId: null, memberType: 'user' },
|
|
|
+ adding: false,
|
|
|
+ changeTypeVisible: false,
|
|
|
+ changeTypeForm: { userId: null, memberType: 'user' },
|
|
|
+ changing: false
|
|
|
+ }
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ orgId() {
|
|
|
+ return this.$route.params.id
|
|
|
+ }
|
|
|
+ },
|
|
|
+ created() {
|
|
|
+ this.loadDetail()
|
|
|
+ this.loadMembers()
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ formatTime(t) {
|
|
|
+ return t ? t.replace('T', ' ').substring(0, 19) : '-'
|
|
|
+ },
|
|
|
+ typeLabel(t) {
|
|
|
+ const map = { enterprise: '企业', institution: '机构', other: '其他' }
|
|
|
+ return t ? (map[t] || t) : '-'
|
|
|
+ },
|
|
|
+ async loadDetail() {
|
|
|
+ try {
|
|
|
+ const res = await orgDetail({ id: this.orgId })
|
|
|
+ if (res.data) {
|
|
|
+ this.org = res.data
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ this.$message.error('加载失败')
|
|
|
+ }
|
|
|
+ },
|
|
|
+ async loadMembers() {
|
|
|
+ this.memberLoading = true
|
|
|
+ try {
|
|
|
+ const res = await orgMemberList({ orgId: this.orgId })
|
|
|
+ if (res.data) {
|
|
|
+ this.members = res.data
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ this.$message.error('加载失败')
|
|
|
+ } finally {
|
|
|
+ this.memberLoading = false
|
|
|
+ }
|
|
|
+ },
|
|
|
+ showAddDialog() {
|
|
|
+ this.addDialogVisible = true
|
|
|
+ this.addForm = { userId: null, memberType: 'user' }
|
|
|
+ this.searchResults = []
|
|
|
+ },
|
|
|
+ async searchUsers(keyword) {
|
|
|
+ if (!keyword) {
|
|
|
+ this.searchResults = []
|
|
|
+ return
|
|
|
+ }
|
|
|
+ this.searchLoading = true
|
|
|
+ try {
|
|
|
+ const res = await orgUserSearch({ keyword })
|
|
|
+ if (res.data) {
|
|
|
+ this.searchResults = res.data
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ this.searchResults = []
|
|
|
+ } finally {
|
|
|
+ this.searchLoading = false
|
|
|
+ }
|
|
|
+ },
|
|
|
+ async submitAddMember() {
|
|
|
+ if (!this.addForm.userId) {
|
|
|
+ this.$message.warning('请选择用户')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ this.adding = true
|
|
|
+ try {
|
|
|
+ await orgMemberAdd({
|
|
|
+ orgId: this.orgId,
|
|
|
+ userId: this.addForm.userId,
|
|
|
+ memberType: this.addForm.memberType
|
|
|
+ })
|
|
|
+ this.$message.success('添加成功')
|
|
|
+ this.addDialogVisible = false
|
|
|
+ this.loadMembers()
|
|
|
+ } catch (e) {
|
|
|
+ this.$message.error('操作失败')
|
|
|
+ } finally {
|
|
|
+ this.adding = false
|
|
|
+ }
|
|
|
+ },
|
|
|
+ removeMember(row) {
|
|
|
+ this.$confirm('确认移除该成员?(软删,不再计入统计)', '提示', {
|
|
|
+ confirmButtonText: '确定',
|
|
|
+ cancelButtonText: '取消',
|
|
|
+ type: 'warning'
|
|
|
+ }).then(async () => {
|
|
|
+ try {
|
|
|
+ await orgMemberRemove({ orgId: this.orgId, userId: row.userId })
|
|
|
+ this.$message.success('已移除')
|
|
|
+ this.loadMembers()
|
|
|
+ } catch (e) {
|
|
|
+ this.$message.error('移除失败')
|
|
|
+ }
|
|
|
+ }).catch(() => {})
|
|
|
+ },
|
|
|
+ openChangeType(row) {
|
|
|
+ this.changeTypeForm = { userId: row.userId, memberType: row.memberType || 'user' }
|
|
|
+ this.changeTypeVisible = true
|
|
|
+ },
|
|
|
+ async submitChangeType() {
|
|
|
+ this.changing = true
|
|
|
+ try {
|
|
|
+ await orgMemberChangeType({
|
|
|
+ orgId: this.orgId,
|
|
|
+ userId: this.changeTypeForm.userId,
|
|
|
+ memberType: this.changeTypeForm.memberType
|
|
|
+ })
|
|
|
+ this.$message.success('已变更')
|
|
|
+ this.changeTypeVisible = false
|
|
|
+ this.loadMembers()
|
|
|
+ } catch (e) {
|
|
|
+ this.$message.error('变更失败')
|
|
|
+ } finally {
|
|
|
+ this.changing = false
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+.org-detail {
|
|
|
+ padding: 20px;
|
|
|
+}
|
|
|
+</style>
|