li.shaoyi 1 jaar geleden
bovenliggende
commit
2808bbd51a

+ 1 - 1
src/packages/pc/views/admin/role/index.vue

@@ -50,7 +50,7 @@ const { dataList, total, pageSize, pageIndex, loading, run } = useRequest(queryR
     }
 })
 
-const tableColumns = shallowRef([
+const tableColumns = shallowRef<Model.TableColumn[]>([
     { field: 'autoid', label: 'ID' },
     { field: 'rolename', label: '角色名称' },
     { field: 'modifiername', label: '创建人' },

+ 1 - 1
src/packages/pc/views/admin/user/index.vue

@@ -79,7 +79,7 @@ const { dataList: selectList } = useRequest(queryOrganSelect, {
     }
 })
 
-const tableColumns = shallowRef([
+const tableColumns = shallowRef<Model.TableColumn[]>([
     { field: 'autoid', label: 'ID' },
     { field: 'logincode', label: '登录账号' },
     { field: 'username', label: '用户名称' },

+ 3 - 3
src/packages/pc/views/investor/user/open/components/edit/index.vue

@@ -173,8 +173,8 @@ const formData = ref<Partial<Model.MemberDetail>>({
 })
 
 const getUploadFiles = (value?: string) => {
-    const paths = value?.split(',')
-    return paths ? paths.map((url) => {
+    const paths = value ? value.split(',') : []
+    return paths.map((url) => {
         const urlObj = new URL(url, service.getConfig('apiUrl'))
         const name = urlObj.pathname.split('/').pop()
         return {
@@ -184,7 +184,7 @@ const getUploadFiles = (value?: string) => {
                 data: [{ filePath: value }]
             }
         }
-    }) : []
+    })
 }
 
 const { loading, run } = useRequest(queryInvestorDetail, {

+ 1 - 1
src/packages/pc/views/investor/user/open/index.vue

@@ -71,7 +71,7 @@ const { dataList, total, pageSize, pageIndex, loading, run } = useRequest(queryI
     }
 })
 
-const tableColumns = shallowRef([
+const tableColumns = shallowRef<Model.TableColumn[]>([
     { field: 'userName', label: '用户名称' },
     { field: 'memberUserName', label: '所属会员' },
     { field: 'areaName', label: '所属机构' },

+ 3 - 3
src/packages/pc/views/member/institution/open/components/edit/index.vue

@@ -156,8 +156,8 @@ const formData = ref<Partial<Model.MemberDetail>>({
 })
 
 const getUploadFiles = (value?: string) => {
-    const paths = value?.split(',')
-    return paths ? paths.map((url) => {
+    const paths = value ? value.split(',') : []
+    return paths.map((url) => {
         const urlObj = new URL(url, service.getConfig('apiUrl'))
         const name = urlObj.pathname.split('/').pop()
         return {
@@ -167,7 +167,7 @@ const getUploadFiles = (value?: string) => {
                 data: [{ filePath: value }]
             }
         }
-    }) : []
+    })
 }
 
 const { loading, run } = useRequest(queryWskhUserinfoDetail, {

+ 1 - 1
src/packages/pc/views/member/institution/open/index.vue

@@ -71,7 +71,7 @@ const { dataList, total, pageSize, pageIndex, loading, run } = useRequest(queryW
     }
 })
 
-const tableColumns = shallowRef([
+const tableColumns = shallowRef<Model.TableColumn[]>([
     { field: 'username', label: '用户名称' },
     { field: 'openmode', label: '开户方式' },
     { field: 'userstate', label: '开户状态' },

+ 1 - 1
src/packages/pc/views/member/institution/role/index.vue

@@ -47,7 +47,7 @@ const { dataList, total, pageSize, pageIndex, loading, run } = useRequest(queryR
     }
 })
 
-const tableColumns = shallowRef([
+const tableColumns = shallowRef<Model.TableColumn[]>([
     { field: 'autoid', label: 'ID' },
     { field: 'rolename', label: '角色名称' },
     { field: 'modifiername', label: '创建人' },

+ 210 - 0
src/packages/pc/views/member/subinstitution/manage/components/details/index.vue

@@ -0,0 +1,210 @@
+<!-- 会员机构管理-子机构管理-子机构管理-详情 -->
+<template>
+    <app-drawer title="详情" width="860" v-model:show="show" :loading="loading" :refresh="refresh">
+        <app-table-details title="基本信息" :data="oldData?.userAccountDetailVo" :label-width="160"
+            :cell-props="detailProps1" :column="2">
+            <!-- 交易商名称 -->
+            <template #accountName="{ value }">
+                <p>{{ value }}</p>
+                <p class="red" v-if="newData && newData.userAccountDetailVo.accountName !== value">
+                    {{ newData.userAccountDetailVo.accountName }}
+                </p>
+            </template>
+            <!-- 开户方式 -->
+            <template #openMode>
+                {{ oldData?.userinfoDetailVo.openMode }}
+            </template>
+            <!-- 申请人 -->
+            <template #createName="{ value }">
+                <span v-if="oldData?.userinfoDetailVo.openMode === 1">{{ value }}</span>
+                <span v-else>{{ oldData?.userAccountDetailVo.accountName }}</span>
+            </template>
+        </app-table-details>
+        <app-table-details title="个人资料" :data="oldData?.userinfoDetailVo" :label-width="160" :cell-props="detailProps2"
+            :column="2" v-if="oldData?.userinfoDetailVo.userinfoType === 1">
+            <!-- 证件照正面 -->
+            <template #cardFrontPhotoUrl="{ value }">
+                <el-image :src="value" fit="cover" lazy style="width: 128px; height: 72px" />
+            </template>
+            <!-- 证件照反面 -->
+            <template #cardBackPhotoUrl="{ value }">
+                <el-image :src="value" fit="cover" lazy style="width: 128px; height: 72px" />
+            </template>
+            <!-- 通迅地址 -->
+            <template #address="{ value }">
+                {{ handleNoneValue(oldData?.userinfoDetailVo.pathName + value) }}
+            </template>
+        </app-table-details>
+        <app-table-details title="企业资料" :data="oldData?.userinfoDetailVo" :label-width="160" :cell-props="detailProps3"
+            :column="2" v-else>
+            <!-- 营业执照 -->
+            <template #cardfrontphotourl="{ value }">
+                <el-image :src="value" fit="cover" lazy style="width: 128px; height: 72px" />
+            </template>
+            <!-- 法人身份证正面 -->
+            <template #legalcardfrontphotourl="{ value }">
+                <el-image :src="value" fit="cover" lazy style="width: 128px; height: 72px" />
+            </template>
+            <!-- 法人身份证反面 -->
+            <template #legalcardbackphotourl="{ value }">
+                <el-image :src="value" fit="cover" lazy style="width: 128px; height: 72px" />
+            </template>
+            <!-- 法人授权书 -->
+            <template #otherUrl="{ value }">
+                <el-image :src="value" fit="cover" lazy style="width: 128px; height: 72px" />
+            </template>
+        </app-table-details>
+        <template #footer>
+            <el-button @click="onCancel(false)">关闭</el-button>
+        </template>
+    </app-drawer>
+</template>
+
+<script lang="ts" setup>
+import { ref, PropType } from 'vue'
+import { handleNoneValue, formatDate } from '@/filters'
+import { decryptAES } from '@/services/crypto'
+import { useEnum } from '@/hooks/enum'
+import { useRequest } from '@/hooks/request'
+import { organSonViewson } from '@/services/api/member'
+import { CellProp } from '@pc/components/base/table-details/types'
+import AppDrawer from '@pc/components/base/drawer/index.vue'
+import AppTableDetails from '@pc/components/base/table-details/index.vue'
+import service from '@/services'
+
+const props = defineProps({
+    selectedParent: {
+        type: Object as PropType<Model.AreaAndAllChildsRsp>
+    },
+    selectedRow: {
+        type: Object as PropType<Model.OrganSonRsp>
+    }
+})
+
+const show = ref(true)
+const refresh = ref(false)
+const loading = ref(false)
+const hideField = [2, 3, 4].includes(props.selectedRow?.accountstatus) // 根据状态是否隐藏字段
+const newData = ref<Model.organSonViewsonRsp['newResult']>()
+const oldData = ref<Model.organSonViewsonRsp['oldResult']>()
+
+// 是否实名
+const hasauthEnum = useEnum('hasauth')
+// 状态
+const areastatusEnum = useEnum('areastatus')
+// 变更状态
+const modifystatusEnum = useEnum('modifystatus')
+// 企业性质枚举
+const biznatureEnum = useEnum('biznature')
+// 个人证件类型
+const certypepersonEnum = useEnum('certypeperson')
+// 企业证件类型
+const certypecompanyEnum = useEnum('certypecompany')
+
+useRequest(organSonViewson, {
+    params: {
+        areaid: props.selectedRow?.userid || props.selectedParent?.userid,
+        modifystatus: props.selectedRow?.modifystatus
+    },
+    onSuccess: (res) => {
+        const { newResult, oldResult } = res.data
+        const baseUrl = service.getConfig('apiUrl')
+        const getUrl = (value: string) => value && new URL(value, baseUrl).href
+
+        if (newResult) {
+            const detail = newResult.userinfoDetailVo
+            detail.cardFrontPhotoUrl = getUrl(detail.cardFrontPhotoUrl)
+            detail.cardBackPhotoUrl = getUrl(detail.cardBackPhotoUrl)
+            detail.halfBodyPhotoUrl = getUrl(detail.halfBodyPhotoUrl)
+            detail.legalCardFrontPhotoUrl = getUrl(detail.legalCardFrontPhotoUrl)
+            detail.legalCardBackPhotoUrl = getUrl(detail.legalCardBackPhotoUrl)
+            detail.otherUrl = getUrl(detail.otherUrl)
+
+            detail.cardNum = decryptAES(detail.cardNum)
+            detail.mobile = decryptAES(detail.cardNum)
+            detail.telPhone = decryptAES(detail.telPhone)
+            detail.wechat = decryptAES(detail.wechat)
+            detail.email = decryptAES(detail.email)
+        }
+        if (oldResult) {
+            const detail = oldResult.userinfoDetailVo
+            detail.cardFrontPhotoUrl = getUrl(detail.cardFrontPhotoUrl)
+            detail.cardBackPhotoUrl = getUrl(detail.cardBackPhotoUrl)
+            detail.halfBodyPhotoUrl = getUrl(detail.halfBodyPhotoUrl)
+            detail.legalCardFrontPhotoUrl = getUrl(detail.legalCardFrontPhotoUrl)
+            detail.legalCardBackPhotoUrl = getUrl(detail.legalCardBackPhotoUrl)
+            detail.otherUrl = getUrl(detail.otherUrl)
+
+            detail.cardNum = decryptAES(detail.cardNum)
+            detail.mobile = decryptAES(detail.cardNum)
+            detail.telPhone = decryptAES(detail.telPhone)
+            detail.wechat = decryptAES(detail.wechat)
+            detail.email = decryptAES(detail.email)
+        }
+
+        newData.value = newResult
+        oldData.value = oldResult
+    }
+})
+
+const detailProps1: CellProp[] = [
+    { prop: 'userId', label: '交易商代码:' },
+    { prop: 'accountName', label: '交易商名称:' },
+    { prop: 'memberUserName', label: '所属会员:' },
+    { prop: 'parentUserName', label: '所属机构:' },
+    { prop: 'openMode', label: '开户方式:' },
+    { prop: 'createTime', label: '开户时间:', formatValue: (val) => formatDate(val) },
+    { prop: 'createName', formatLabel: () => oldData.value?.userinfoDetailVo.openMode === 1 ? '开户人' : '申请人' },
+    { prop: 'accountStatus', label: '机构状态:', formatValue: (val) => areastatusEnum.getEnumTypeName(val), show: !hideField },
+    { prop: 'modifyStatus', label: '变更状态:', formatValue: (val) => modifystatusEnum.getEnumTypeName(val) },
+    { prop: 'isAuth', label: '是否认证:', formatValue: (val) => hasauthEnum.getEnumTypeName(val) },
+    { prop: 'modifyTime', label: '修改时间:', formatValue: (val) => formatDate(val) },
+    { prop: 'modifyName', label: '修改人:' },
+    { prop: 'auditTime', label: '审核时间:', formatValue: (val) => formatDate(val), show: !hideField },
+    { prop: 'auditAccountName', label: '审核人:', show: !hideField },
+    { prop: 'modifyRemark', label: '变更审核备注:', show: hideField },
+]
+
+const detailProps2: CellProp[] = [
+    { prop: 'cardTypeId', label: '证件类型:', formatValue: (val) => certypepersonEnum.getEnumTypeName(val) },
+    { prop: 'cardNum', label: '证件号码:' },
+    { prop: 'company', label: '所属公司:' },
+    { prop: 'sex', label: '性别:' },
+    { prop: 'mobile', label: '手机号:' },
+    { prop: 'telPhone', label: '联系电话:' },
+    { prop: 'address', label: '通迅地址:' },
+    { prop: 'postalCode', label: '邮政编码:' },
+    { prop: 'wechat', label: '微信:' },
+    { prop: 'email', label: '邮箱:' },
+    { prop: 'cardFrontPhotoUrl', label: '证件照正面:' },
+    { prop: 'cardBackPhotoUrl', label: '证件照反面:' },
+    { prop: 'remark', label: '备注:' },
+]
+
+const detailProps3: CellProp[] = [
+    { prop: 'needInvoice', label: '是否需要发票:' },
+    { prop: 'cardTypeId', label: '证件类型:', formatValue: (val) => certypecompanyEnum.getEnumTypeName(val) },
+    { prop: 'cardNum', label: '证件号码:' },
+    { prop: 'customerName', label: '企业名称:' },
+    { prop: 'bizNature', label: '企业性质:', formatValue: (val) => biznatureEnum.getEnumTypeName(val) },
+    { prop: 'legalPersonName', label: '法人姓名:' },
+    { prop: 'contactName', label: '联系人:' },
+    { prop: 'sex', label: '性别:' },
+    { prop: 'mobile', label: '手机号:' },
+    { prop: 'telPhone', label: '联系电话:' },
+    { prop: 'address', label: '通迅地址:' },
+    { prop: 'postalCode', label: '邮政编码:' },
+    { prop: 'email', label: '邮箱:' },
+    { prop: 'wechat', label: '微信:' },
+    { prop: 'cardFrontPhotoUrl', label: '营业执照:' },
+    { prop: 'legalCardFrontPhotoUrl', label: '法人身份证正面照:' },
+    { prop: 'legalCardBackPhotoUrl', label: '法人身份证背面照:' },
+    { prop: 'otherUrl', label: '法人授权书:' },
+    { prop: 'remark', label: '备注:' },
+]
+
+const onCancel = (isRefresh = false) => {
+    show.value = false
+    refresh.value = isRefresh
+}
+</script>

+ 297 - 0
src/packages/pc/views/member/subinstitution/manage/components/edit/index.vue

@@ -0,0 +1,297 @@
+<!-- 会员机构管理-子机构管理-子机构管理-编辑 -->
+<template>
+    <app-drawer title="编辑" width="900" v-model:show="show" :refresh="refresh" :loading="loading">
+        <el-form ref="formRef" label-width="140px" :model="formData" :rules="formRules" :show-message="false">
+            <fieldset class="g-fieldset el-form--horizontal">
+                <legend class="g-fieldset__legend">基本信息</legend>
+                <el-form-item label="上级机构" prop="referral">
+                    {{ selectedParent?.accountname }}
+                </el-form-item>
+                <el-form-item label="机构代码" prop="userid">
+                    <el-input v-model="formData.userid" maxlength="4" placeholder="请输入" />
+                </el-form-item>
+                <el-form-item label="所有者类型" prop="userinfotype">
+                    <el-radio-group v-model="formData.userinfotype">
+                        <el-radio label="企业" :value="2" />
+                        <el-radio label="个人" :value="1" />
+                    </el-radio-group>
+                </el-form-item>
+                <el-form-item label="机构名称" prop="accountname">
+                    <el-input v-model="formData.accountname" maxlength="50" placeholder="请输入" />
+                </el-form-item>
+            </fieldset>
+            <fieldset class="g-fieldset el-form--horizontal">
+                <legend class="g-fieldset__legend">{{ isPerson ? '个人' : '企业' }}资料</legend>
+                <el-form-item label="名称" prop="customername">
+                    <el-input v-model="formData.customername" maxlength="50" placeholder="请输入" />
+                </el-form-item>
+                <el-form-item label="公司" prop="company" v-if="isPerson">
+                    <el-input v-model="formData.company" maxlength="50" placeholder="请输入" />
+                </el-form-item>
+                <el-form-item label="企业性质" prop="biznature" v-if="!isPerson">
+                    <app-enum code="biznature" v-model="formData.biznature" />
+                </el-form-item>
+                <el-form-item label="证件类型" prop="cardtypeid">
+                    <app-enum code="certypecompany" v-model="formData.cardtypeid" v-if="!isPerson" />
+                    <app-enum code="certypeperson" v-model="formData.cardtypeid" v-else />
+                </el-form-item>
+                <el-form-item label="证件号码" prop="cardnum">
+                    <el-input v-model="formData.cardnum" maxlength="50" placeholder="请输入" />
+                </el-form-item>
+                <el-form-item label="证件照正面" prop="cardfrontphotourl">
+                    <app-upload v-model="uploadFiles.cardfrontphotourl" :file-types="['image']"
+                        type-message="请选择正确的图片类型" />
+                </el-form-item>
+                <el-form-item label="证件照反面" prop="cardbackphotourl" v-if="isPerson">
+                    <app-upload v-model="uploadFiles.cardbackphotourl" :file-types="['image']"
+                        type-message="请选择正确的图片类型" />
+                </el-form-item>
+                <template v-if="!isPerson">
+                    <el-form-item label="法人姓名" prop="legalpersonname">
+                        <el-input v-model="formData.legalpersonname" maxlength="50" placeholder="请输入" />
+                    </el-form-item>
+                    <el-form-item label="法人身份证正面" prop="legalcardfrontphotourl">
+                        <app-upload v-model="uploadFiles.legalcardfrontphotourl" :file-types="['image']"
+                            type-message="请选择正确的图片类型" />
+                    </el-form-item>
+                    <el-form-item label="法人身份证反面" prop="legalcardbackphotourl">
+                        <app-upload v-model="uploadFiles.legalcardbackphotourl" :file-types="['image']"
+                            type-message="请选择正确的图片类型" />
+                    </el-form-item>
+                    <el-form-item label="联系人" prop="contactname">
+                        <el-input v-model="formData.contactname" maxlength="50" placeholder="请输入" />
+                    </el-form-item>
+                </template>
+                <el-form-item label="性别" prop="sex">
+                    <el-radio-group v-model="formData.sex">
+                        <el-radio label="男" :value="1" />
+                        <el-radio label="女" :value="0" />
+                    </el-radio-group>
+                </el-form-item>
+                <el-form-item label="手机号" prop="mobile">
+                    <el-input v-model="formData.mobile" maxlength="50" placeholder="请输入" />
+                </el-form-item>
+                <el-form-item label="联系电话" prop="telphone">
+                    <el-input v-model="formData.telphone" maxlength="50" placeholder="请输入" />
+                </el-form-item>
+                <el-form-item class="el-form-item--row" label="地区" prop="provinceid">
+                    <app-region class="el-form-item--col" v-model:province="formData.provinceid"
+                        v-model:city="formData.cityid" v-model:district="formData.districtid" />
+                </el-form-item>
+                <el-form-item class="el-form-item--row" label="地址" prop="address">
+                    <el-input v-model="formData.address" maxlength="50" placeholder="请输入" />
+                </el-form-item>
+                <el-form-item label="邮政编码" prop="postalcode">
+                    <el-input v-model="formData.postalcode" maxlength="50" placeholder="请输入" />
+                </el-form-item>
+                <el-form-item label="邮箱" prop="email">
+                    <el-input v-model="formData.email" maxlength="50" placeholder="请输入" />
+                </el-form-item>
+                <el-form-item class="el-form-item--row" label="备注" prop="remark">
+                    <el-input type="textarea" v-model="formData.remark" maxlength="200" :rows="2" placeholder="请输入" />
+                </el-form-item>
+            </fieldset>
+            <fieldset class="g-fieldset el-form--horizontal">
+                <legend class="g-fieldset__legend">管理员及账户信息</legend>
+                <el-form-item label="管理员登录账号" prop="logincode">
+                    <el-input v-model="formData.logincode" maxlength="50" placeholder="请输入" />
+                </el-form-item>
+                <el-form-item label="管理员名称" prop="username">
+                    <el-input v-model="formData.username" maxlength="50" placeholder="请输入" />
+                </el-form-item>
+                <el-form-item label="默认登录密码" prop="smpassword">
+                    <el-input value="123456" disabled />
+                </el-form-item>
+            </fieldset>
+            <fieldset class="g-fieldset el-form--horizontal">
+                <legend class="g-fieldset__legend">附件</legend>
+                <el-form-item label="附件1" prop="attachment1">
+                    <app-upload v-model="uploadFiles.attachment1" :file-types="['image', 'pdf']"
+                        type-message="请选择正确的图片类型" />
+                </el-form-item>
+                <el-form-item label="附件2" prop="attachment2">
+                    <app-upload v-model="uploadFiles.attachment2" :file-types="['image', 'pdf']"
+                        type-message="请选择正确的图片类型" />
+                </el-form-item>
+            </fieldset>
+        </el-form>
+        <template #footer>
+            <el-button @click="onCancel(false)">取消</el-button>
+            <el-button type="primary" @click="onSubmit">提交审核</el-button>
+        </template>
+    </app-drawer>
+</template>
+
+<script lang="ts" setup>
+import { ref, reactive, PropType, onMounted, computed } from 'vue'
+import { ElMessage, FormInstance, FormRules, UploadUserFile } from 'element-plus'
+import { decryptAES } from '@/services/crypto'
+import { useRequest } from '@/hooks/request'
+import { organSonViewson, organSonAdd, organSonEdit } from '@/services/api/member'
+import AppDrawer from '@pc/components/base/drawer/index.vue'
+import AppUpload from '@pc/components/base/upload/index.vue'
+import AppEnum from '@pc/components/modules/enum/index.vue'
+import AppRegion from '@pc/components/modules/region/index.vue'
+import service from '@/services'
+
+const props = defineProps({
+    selectedParent: {
+        type: Object as PropType<Model.AreaAndAllChildsRsp>
+    },
+    selectedRow: {
+        type: Object as PropType<Model.OrganSonRsp>
+    }
+})
+
+const formRef = ref<FormInstance>()
+const show = ref(true)
+const refresh = ref(false)
+
+const uploadFiles = reactive<{
+    cardfrontphotourl: UploadUserFile[];
+    cardbackphotourl: UploadUserFile[];
+    legalcardfrontphotourl: UploadUserFile[];
+    legalcardbackphotourl: UploadUserFile[];
+    attachment1: UploadUserFile[];
+    attachment2: UploadUserFile[];
+}>({
+    cardfrontphotourl: [],
+    cardbackphotourl: [],
+    legalcardfrontphotourl: [],
+    legalcardbackphotourl: [],
+    attachment1: [],
+    attachment2: []
+})
+
+
+// 是否个人
+const isPerson = computed(() => formData.value.userinfotype === 1)
+
+const formData = ref<Partial<Model.organSonUpdateReq>>({
+    parentuserid: props.selectedParent?.userid,
+    userinfotype: 2,
+    sex: 1,
+    usertype: 3
+})
+
+const getUploadFiles = (value?: string) => {
+    const paths = value ? value.split(',') : []
+    return paths.map((url) => {
+        const urlObj = new URL(url, service.getConfig('apiUrl'))
+        const name = urlObj.pathname.split('/').pop()
+        return {
+            name: name ?? urlObj.href,
+            url: urlObj.href,
+            response: {
+                data: [{ filePath: value }]
+            }
+        }
+    })
+}
+
+const { loading, run } = useRequest(organSonViewson, {
+    manual: true,
+    onSuccess: ((res) => {
+        const { logincode, username, oldResult: { userAccountDetailVo, userinfoDetailVo } } = res.data
+        formData.value = {
+            accountname: userAccountDetailVo.accountName,
+            address: userinfoDetailVo.address,
+            biznature: userinfoDetailVo.bizNature,
+            cardnum: decryptAES(userinfoDetailVo.cardNum),
+            cardtypeid: userinfoDetailVo.cardTypeId,
+            cityid: userinfoDetailVo.cityid,
+            company: userinfoDetailVo.company,
+            contactname: userinfoDetailVo.contactName,
+            customername: userinfoDetailVo.customerName,
+            districtid: userinfoDetailVo.districtid,
+            email: userinfoDetailVo.email,
+            legalpersonname: userinfoDetailVo.legalPersonName,
+            logincode: logincode,
+            mobile: userinfoDetailVo.mobile,
+            modifystatus: userAccountDetailVo.modifyStatus,
+            parentuserid: userAccountDetailVo.parentuserid,
+            postalcode: userinfoDetailVo.postalCode,
+            provinceid: userinfoDetailVo.provinceid,
+            qq: userinfoDetailVo.qq,
+            refereeuserid: userAccountDetailVo.refereeuserid,
+            remark: userinfoDetailVo.remark,
+            sex: userinfoDetailVo.sex,
+            telphone: userinfoDetailVo.telPhone,
+            userid: userAccountDetailVo.userId,
+            userinfotype: userinfoDetailVo.userinfoType,
+            username: username,
+            usertype: userAccountDetailVo.usertype,
+            wechat: userinfoDetailVo.wechat
+        }
+        uploadFiles.cardfrontphotourl = getUploadFiles(userinfoDetailVo.cardBackPhotoUrl)
+        uploadFiles.cardbackphotourl = getUploadFiles(userinfoDetailVo.cardFrontPhotoUrl)
+        uploadFiles.legalcardfrontphotourl = getUploadFiles(userinfoDetailVo.legalCardFrontPhotoUrl)
+        uploadFiles.legalcardbackphotourl = getUploadFiles(userinfoDetailVo.legalCardBackPhotoUrl)
+        uploadFiles.attachment1 = getUploadFiles(userinfoDetailVo.attachment1)
+        uploadFiles.attachment2 = getUploadFiles(userinfoDetailVo.attachment2)
+    }),
+    onError: (err) => {
+        ElMessage.error(err)
+    }
+})
+
+// 表单验证规则
+const formRules: FormRules = {
+    userid: [{ required: true }],
+    accountname: [{ required: true }],
+    cardtypeid: [{ required: true }],
+    username: [{ required: true }],
+    customername: [{ required: true }],
+    cardnum: [{ required: true }],
+    logincode: [{ required: true }],
+}
+
+const onCancel = (isRefresh = false) => {
+    show.value = false
+    refresh.value = isRefresh
+}
+
+// 更新上传文件到表单中
+const updateUploadFiles = (uploadFiles: UploadUserFile[]) => {
+    return uploadFiles.map((e) => {
+        const res = e.response as { data: { filePath: string }[] }
+        return res.data.map((e) => e.filePath)
+    }).join(',')
+}
+
+const onSubmit = () => {
+    const rawData = { ...formData.value }
+    rawData.cardfrontphotourl = updateUploadFiles(uploadFiles.cardfrontphotourl)
+    rawData.cardbackphotourl = updateUploadFiles(uploadFiles.cardbackphotourl)
+    rawData.legalcardfrontphotourl = updateUploadFiles(uploadFiles.legalcardfrontphotourl)
+    rawData.legalcardbackphotourl = updateUploadFiles(uploadFiles.legalcardbackphotourl)
+    rawData.attachment1 = updateUploadFiles(uploadFiles.attachment1)
+    rawData.attachment2 = updateUploadFiles(uploadFiles.attachment2)
+
+    formRef.value?.validate((valid) => {
+        if (valid) {
+            loading.value = true
+            organSonAdd({
+                data: rawData
+            }).then(() => {
+                ElMessage.success('保存成功')
+                onCancel(true)
+            }).catch((err) => {
+                ElMessage.error('保存失败:' + err)
+            }).finally(() => {
+                loading.value = false
+            })
+        }
+    })
+}
+
+onMounted(() => {
+    const { userid, modifystatus } = props.selectedRow ?? {}
+    if (userid) {
+        run({
+            areaid: userid,
+            modifystatus
+        })
+    }
+})
+</script>

+ 21 - 0
src/packages/pc/views/member/subinstitution/manage/index.less

@@ -0,0 +1,21 @@
+.split-layout {
+    display: flex;
+    padding: 10px;
+
+    &__left,
+    &__right {
+        background-color: #fff;
+        border-radius: 4px;
+        padding: 20px;
+        margin: 10px;
+    }
+
+    &__left{
+        min-width: 240px;
+    }
+
+    &__right{
+        flex: 1;
+        overflow-x: auto;
+    }
+}

+ 127 - 0
src/packages/pc/views/member/subinstitution/manage/index.vue

@@ -0,0 +1,127 @@
+<!-- 会员机构管理-子机构管理-子机构管理 -->
+<template>
+    <div class="split-layout">
+        <div class="split-layout__left">
+            <el-tree :data="treeList" :expand-on-click-node="false" @node-click="nodeClick" default-expand-all
+                highlight-current>
+                <template #default="{ data }">
+                    {{ `(${data.userid}) ${data.accountname}` }}
+                </template>
+            </el-tree>
+        </div>
+        <div class="split-layout__right">
+            <app-operation
+                :data-list="getFilteredButtons(['member_subinstitution_manage_details', 'member_subinstitution_manage_add'])"
+                @click="openComponent" />
+            <app-table-details :data="selectedParent" :label-width="120" label-align="left" :cell-props="detailProps"
+                :column="3" />
+            <app-table :data="dataList" v-model:columns="tableColumns">
+                <!-- 操作 -->
+                <template #operate="{ row }">
+                    <app-operation size="small"
+                        :data-list="getFilteredButtons(['member_subinstitution_manage_details', 'member_subinstitution_manage_modify'])"
+                        @click="(code: string) => openComponent(code, row)" circle />
+                </template>
+            </app-table>
+        </div>
+        <component :is="componentMap.get(componentId)" v-bind="{ selectedParent, selectedRow }" @closed="closeComponent"
+            v-if="componentId" />
+    </div>
+</template>
+
+<script lang="ts" setup>
+import { shallowRef, computed } from 'vue'
+import { ElMessage } from 'element-plus'
+import { useEnum } from '@/hooks/enum'
+import { useOperation } from '@/hooks/operation'
+import { useRequest } from '@/hooks/request'
+import { getAreaAndAllChilds, queryOrganSon } from '@/services/api/member'
+import { CellProp } from '@pc/components/base/table-details/types'
+import AppTable from '@pc/components/base/table/index.vue'
+import AppTableDetails from '@pc/components/base/table-details/index.vue'
+import AppOperation from '@pc/components/base/operation/index.vue'
+
+// 机构状态
+const areastatusEnum = useEnum('areastatus')
+
+const selectedParent = shallowRef<Model.AreaAndAllChildsRsp>()
+
+const { componentMap, componentId, selectedRow, openComponent, closeComponent, getFilteredButtons } = useOperation<Model.OrganSonRsp>({
+    //onClose: () => onSearch()
+})
+
+const treeList = computed(() => {
+    const map = new Map()
+    for (const item of nodeList.value) {
+        map.set(item.userid, { ...item, children: [] })
+    }
+    for (const item of nodeList.value) {
+        if (item.parentuserid !== item.memberuserid) {
+            const parent = map.get(item.parentuserid)
+            if (parent) {
+                parent.children.push(map.get(item.userid))
+            }
+        }
+    }
+    const roots = []
+    for (const [id, node] of map) {
+        if (node.parentuserid === node.memberuserid) {
+            roots.push(node)
+        }
+    }
+    return roots
+})
+
+const { dataList: nodeList } = useRequest(getAreaAndAllChilds, {
+    onSuccess: (res) => {
+        const { memberuserid, parentuserid, userid } = res.data[0]
+        selectedParent.value = res.data[0]
+        getOrganSonList({
+            memberuserid: memberuserid === parentuserid ? userid : parentuserid,
+            parentuserid: userid
+        })
+    },
+    onError: (err) => {
+        ElMessage.error(err)
+    }
+})
+
+const { dataList, run: getOrganSonList } = useRequest(queryOrganSon, {
+    manual: true,
+    params: {
+        pageNum: 1,
+        pageSize: 20
+    },
+    onError: (err) => {
+        ElMessage.error(err)
+    }
+})
+
+const detailProps: CellProp[] = [
+    { prop: 'userid', label: '机构代码:' },
+    { prop: 'accountname', label: '机构名称:' },
+    { prop: 'accountstatus', label: '机构状态:', formatValue: (val) => areastatusEnum.getEnumTypeName(val) },
+    { prop: 'userinfotype', label: '所有者类型:' },
+    { prop: 'contactname', label: '联系人:' },
+    { prop: 'pathname', label: '地址:' },
+]
+
+const tableColumns = shallowRef<Model.TableColumn[]>([
+    { field: 'userid', label: '机构代码' },
+    { field: 'accountname', label: '机构名称' },
+    { field: 'accountstatus', label: '机构状态', formatValue: (val) => areastatusEnum.getEnumTypeName(val) },
+    { field: 'usertype', label: '机构类型' },
+    { field: 'userinfotype', label: '所有者类型' },
+    { field: 'userName', label: '操作员' },
+    { field: 'modifytime', label: '最后更新时间' },
+    { field: 'operate', label: '操作', fixed: 'right' }
+])
+
+const nodeClick = (node: Model.AreaAndAllChildsRsp) => {
+    selectedParent.value = node
+}
+</script>
+
+<style lang="less">
+@import './index.less';
+</style>

+ 3 - 3
src/packages/pc/views/member/subinstitution/open/components/edit/index.vue → src/packages/pc/views/member/subinstitution/user/components/edit/index.vue

@@ -170,8 +170,8 @@ const formData = ref<Partial<Model.MemberDetail>>({
 })
 
 const getUploadFiles = (value?: string) => {
-    const paths = value?.split(',')
-    return paths ? paths.map((url) => {
+    const paths = value ? value.split(',') : []
+    return paths.map((url) => {
         const urlObj = new URL(url, service.getConfig('apiUrl'))
         const name = urlObj.pathname.split('/').pop()
         return {
@@ -181,7 +181,7 @@ const getUploadFiles = (value?: string) => {
                 data: [{ filePath: value }]
             }
         }
-    }) : []
+    })
 }
 
 const { loading, run } = useRequest(queryWskhUserinfoDetail, {

+ 4 - 4
src/packages/pc/views/member/subinstitution/open/index.vue → src/packages/pc/views/member/subinstitution/user/index.vue

@@ -6,7 +6,7 @@
         </template>
         <app-table :data="dataList" v-model:columns="tableColumns" :loading="loading">
             <template #headerLeft>
-                <app-operation :data-list="getFilteredButtons(['member_subinstitution_open_add'])"
+                <app-operation :data-list="getFilteredButtons(['member_subinstitution_user_add'])"
                     @click="openComponent" />
             </template>
             <!-- 开户方式 -->
@@ -71,7 +71,7 @@ const { dataList, total, pageSize, pageIndex, loading, run } = useRequest(queryW
     }
 })
 
-const tableColumns = shallowRef([
+const tableColumns = shallowRef<Model.TableColumn[]>([
     { field: 'username', label: '机构代码' },
     { field: 'openmode', label: '机构名称' },
     { field: 'userstate', label: '所属机构' },
@@ -102,9 +102,9 @@ const handleOperateButtons = (row: Model.MemberDetail) => {
     switch (row.userstate) {
         case 1:
         case 3:
-            return getFilteredButtons(['member_institution_open_modify', 'member_institution_open_delete'])
+            return getFilteredButtons(['member_subinstitution_user_modify', 'member_subinstitution_user_delete'])
         case 2:
-            return getFilteredButtons(['member_institution_open_audit', 'member_institution_open_cancel'])
+            return getFilteredButtons(['member_subinstitution_user_audit', 'member_subinstitution_user_cancel'])
         default:
             return []
     }

+ 11 - 7
src/packages/pc/views/query/order/order/index.vue

@@ -27,6 +27,7 @@
 <script lang="ts" setup>
 import { shallowRef } from 'vue'
 import { ElMessage } from 'element-plus'
+import { formatDate } from '@/filters'
 import { getBuyOrSellName } from '@/constants/order'
 import { useEnum } from '@/hooks/enum'
 import { useMarket } from '@/hooks/market'
@@ -40,7 +41,10 @@ import AppPagination from '@pc/components/base/pagination/index.vue'
 import AppOperation from '@pc/components/base/operation/index.vue'
 
 const { marketOptions, getMarketById, registerMarketReadyCallback } = useMarket()
-const { enumOptions, getEnumTypeName, registerEnumReadyCallback } = useEnum('buildtype') // 单据类型
+// 委托类型
+const buildtypeEnum = useEnum('buildtype')
+// 委托状态
+const orderstatusEnum = useEnum('orderstatus')
 
 const queryParams = shallowRef<Model.CommissionSheetReq>()
 const { filterOptons, getQueryParams } = useDataFilter<Model.CommissionSheetReq>()
@@ -66,13 +70,13 @@ const tableColumns = shallowRef<Model.TableColumn[]>([
     { field: 'orderId', label: '委托单号' },
     { field: 'accountNameId', label: '账户' },
     { field: 'goodsCodeName', label: '商品代码/名称' },
-    { field: 'buildType', label: '单据类型', formatValue: (val) => getEnumTypeName(val) },
+    { field: 'buildType', label: '单据类型', formatValue: (val) => buildtypeEnum.getEnumTypeName(val) },
     { field: 'buyOrSell', label: '方向', formatValue: (val) => getBuyOrSellName(val) },
     { field: 'orderPrice', label: '委托价格' },
     { field: 'orderQty', label: '委托数量' },
     { field: 'tradeQty', label: '成交数量' },
-    { field: 'orderStatus', label: '状态' },
-    { field: 'orderTime', label: '委托时间' },
+    { field: 'orderStatus', label: '状态', formatValue: (val) => orderstatusEnum.getEnumTypeName(val) },
+    { field: 'orderTime', label: '委托时间', formatValue: (val) => formatDate(val) },
     { field: 'tradeDate', label: '交易日' },
     { field: 'operate', label: '操作', fixed: 'right' }
 ])
@@ -140,10 +144,10 @@ const processRequiredParams = (callback: (params: Model.CommissionSheetReq) => v
 }
 
 registerMarketReadyCallback(() => {
-    filterOptons.selectList[0].options = marketOptions.value
+    filterOptons.selectList[0].options = marketOptions.value.filter((e) => ![15, 97, 99].includes(e.value))
 })
 
-registerEnumReadyCallback(() => {
-    filterOptons.selectList[2].options = enumOptions.value
+buildtypeEnum.registerEnumReadyCallback(() => {
+    filterOptons.selectList[2].options = buildtypeEnum.enumOptions.value
 })
 </script>

+ 1 - 1
src/packages/pc/views/query/order/trade/index.vue

@@ -149,7 +149,7 @@ const processRequiredParams = (callback: (params: Model.ContractSheetReq) => voi
 }
 
 registerMarketReadyCallback(() => {
-    filterOptons.selectList[0].options = marketOptions.value
+    filterOptons.selectList[0].options = marketOptions.value.filter((e) => ![15, 97, 99].includes(e.value))
 })
 
 buildtypeEnum.registerEnumReadyCallback(() => {

+ 56 - 0
src/services/api/member/index.ts

@@ -41,4 +41,60 @@ export function wskhUserinfoReBack(options: CommonFetchOptions<{ request: Model.
  */
 export function wskhUserinfoDelete(options: CommonFetchOptions<{ request: Model.WskhUserinfoDeleteReq; }>) {
     return httpClient.commonRequest('/wskhUserinfo/delete', 'get', options)
+}
+
+/**
+ * 获取机构及所有子机构
+ */
+export function getAreaAndAllChilds(options: CommonFetchOptions<{ response: Model.AreaAndAllChildsRsp[]; }>) {
+    return httpClient.commonRequest('/common/getAreaAndAllChilds', 'get', options)
+}
+
+/**
+ * 会员机构管理-->子机构管理-->新增
+ */
+export function organSonAdd(options: CommonFetchOptions<{ request: Partial<Model.organSonUpdateReq>; }>) {
+    return httpClient.commonRequest('/organSon/addsonorgan', 'post', options)
+}
+
+/**
+ * 会员机构管理-->子机构管理-->修改
+ */
+export function organSonEdit(options: CommonFetchOptions<{ request: Partial<Model.organSonUpdateReq>; }>) {
+    return httpClient.commonRequest('/organSon/editsonorgan', 'post', options)
+}
+
+/**
+ * 会员机构管理-->子机构管理-->注销
+ */
+export function organSonDelete(options: CommonFetchOptions<{ request: Model.organSonDeleteReq; }>) {
+    return httpClient.commonRequest('/organSon/delete', 'get', options)
+}
+
+/**
+ * 会员机构管理-->子机构管理-->获取机构列表
+ */
+export function queryOrganSon(options: CommonFetchOptions<{ request: Model.OrganSonReq; response: Model.OrganSonRsp[]; }>) {
+    return httpClient.commonRequest('/organSon/query', 'get', options)
+}
+
+/**
+ * 会员机构管理-->子机构管理-->撤回
+ */
+export function organSonRebackChange(options: CommonFetchOptions<{ request: Model.organSonRebackChangeReq; }>) {
+    return httpClient.commonRequest('/organSon/rebackChange', 'get', options)
+}
+
+/**
+ * 会员机构管理-->子机构管理-->恢复
+ */
+export function organSonRecover(options: CommonFetchOptions<{ request: Model.organSonRecoverReq; }>) {
+    return httpClient.commonRequest('/organSon/recover', 'get', options)
+}
+
+/**
+ * 会员机构管理-->子机构管理-->机构详情
+ */
+export function organSonViewson(options: CommonFetchOptions<{ request: Model.organSonViewsonReq; response: Model.organSonViewsonRsp; }>) {
+    return httpClient.commonRequest('/organSon/viewson', 'get', options)
 }

+ 258 - 0
src/types/model/member.d.ts

@@ -111,4 +111,262 @@ declare namespace Model {
     interface WskhUserinfoReBackReq {
         userid: number;
     }
+
+    /** 获取机构及所有子机构 响应 */
+    interface AreaAndAllChildsRsp {
+        accountname: string; // 账户名称(机构名称)
+        accountstatus: number; // code areastatus 账户状态 - 1:待激活 2:待审核 3:待复审 4:正常 5:审核拒绝 6:停用(注销) 7:注销(删除)
+        applysrc: number; // 申请来源 - 1:管理端 2:终端
+        auditremark: string; // 审核备注
+        auditsrc: number; // 审核来源 - 1:管理端 2:终端
+        audittime: string; // 审核时间
+        audituserid: number; // 审核人
+        broker: number; // 所属经纪人ID(所属客户经理-千海金)
+        canceltime: string; // 销户时间
+        canceluserid: number; // 销户人
+        canrecommend: number; // 是否可推荐 - 0:不可 1;可 (是否推荐人)
+        contactname: string; // 地址
+        createtime: string; // 创建时间
+        createtradedate: string; // 创建交易日(yyyyMMdd)
+        creatorid: number; // 创建人
+        creditquota: number; // 授信额度(金瑞)分拣室服务费(广钻)
+        hasauth: number; // 是否已实名认证 - 0:未认证 1:已认证 2:已提交(待审核) 3:已拒绝
+        hasuploaded: number; // 是否已同步(千海金) 0:未同步 1;已同步
+        isanonymous: number; // 是否匿名下单 - 0:否 1:是
+        maxLevel: number;
+        maxinvestornum: number; // 最大用户数(经纪会员下投资者个数)
+        memberuserid: number; // 所属会员ID
+        modifierid: number; // 修改人
+        modifyremark: string; // 变更备注
+        modifysrc: number; // 修改来源 - 1:管理端 2:终端
+        modifystatus: number; // 变更状态 1 未变更 2 变更中 3 变更待审核 4 变更待复核(投资者)
+        modifytime: string; // 修改时间
+        outeruserid: string; // 外部用户ID(千海金-外部门店ID)
+        parenttopuser: string; // 上级顶级机构 [092=0,1时,默认为1, 092=2时若自已为顶级,则填入自己,自己不为顶级,填入ParentUserID的ParentTopUser]
+        parentuserid: number; // 所属机构ID
+        pathname: string; // 联系人
+        reckonaccountid: number; // 默认结算资金账号ID(机构分润使用) 作废
+        refercount: number; // 推荐总人数
+        refereeuserid: number; // 推荐人ID
+        refernum: string; // 推荐码
+        roleIds: string;
+        rootuserid: number; // 根用户ID
+        secrefercount: number; // 间接推荐总人数
+        sjaccountno: string; // 送检账户(广钻)
+        subaccountlevel: number; // 子账户层数
+        subarealevel: number;
+        subarealevelpath: string; // 子机构层级路径(逗号分隔,首尾加逗号)
+        subjectid: number; // 所属部门(业务部门)
+        teammanageruserid: number; // 团队经理用户ID(千海金:门店代理)
+        uploadedtime: string; // 同步时间
+        userName: string;
+        userid: number; // 用户ID
+        userinfotype: number; // 所有者类型
+        usertype: number; // 账户类型 - 1:交易所 2:机构 3:会员子机构 4:经纪人 5:投资者 6:客户 7:企业成员(云平台)
+    }
+
+    /** 会员机构管理-->子机构管理-->新增 请求 */
+    interface organSonUpdateReq {
+        accountname: string; // 机构名称
+        address: string; // 地址
+        attachment1: string; // 附件1
+        attachment2: string; // 附件2
+        biznature: number; // 企业性质 公司
+        cardbackphotourl: string; // 证件照反面
+        cardfrontphotourl: string; // 证件照正面
+        cardnum: string; // 证件号码
+        cardtypeid: number; // 证件类型
+        cityid: number; // 市
+        company: string; // 公司 个人
+        contactname: string; // 联系人
+        customername: string; // 名称
+        districtid: number; // 区
+        email: string; // 邮箱
+        legalcardbackphotourl: string; // 法人身份证反面
+        legalcardfrontphotourl: string; // 法人身份证正面
+        legalpersonname: string; // 法人姓名
+        logincode: string; // 管理员登录帐号
+        mobile: string; // 手机号
+        modifystatus: number; // 修改用
+        parentuserid: number; // 父级userid
+        postalcode: string; // 邮政编码
+        provinceid: number; // 省
+        qq: string; // qq
+        refereeuserid: number; // 修改用 推荐人
+        remark: string; // 备注
+        sex: number; // 性别
+        telphone: string; // 联系电话
+        userid: number; // 机构代码
+        userinfotype: number; // 所有者类型
+        username: string; // 管理员名称
+        usertype: number; // 平台、机构新增、修改固定为3
+        wechat: string; // 微信
+    }
+
+    /** 会员机构管理-->子机构管理-->注销 请求 */
+    interface organSonDeleteReq {
+        areaid: number;
+    }
+
+    /** 会员机构管理-->子机构管理-->获取机构列表 请求 */
+    interface OrganSonReq {
+        accountName?: string; // 机构
+        accountStatus?: number; // 机构状态
+        memberuserid?: number; // 一级机构代码
+        pageNum: number;
+        pageSize: number;
+        parentuserid?: number;
+        usertype?: number;
+    }
+
+    /** 会员机构管理-->子机构管理-->获取机构列表 响应 */
+    interface OrganSonRsp {
+        accountname: string; // 账户名称(机构名称)
+        accountstatus: number; // code areastatus 账户状态 - 1:待激活 2:待审核 3:待复审 4:正常 5:审核拒绝 6:停用(注销) 7:注销(删除)
+        applysrc: number; // 申请来源 - 1:管理端 2:终端
+        auditremark: string; // 审核备注
+        auditsrc: number; // 审核来源 - 1:管理端 2:终端
+        audittime: string; // 审核时间
+        audituserid: number; // 审核人
+        broker: number; // 所属经纪人ID(所属客户经理-千海金)
+        canceltime: string; // 销户时间
+        canceluserid: number; // 销户人
+        cancrossadd: number;
+        canrecommend: number; // 是否可推荐 - 0:不可 1;可 (是否推荐人)
+        contactname: string; // 地址
+        createtime: string; // 创建时间
+        createtradedate: string; // 创建交易日(yyyyMMdd)
+        creatorid: number; // 创建人
+        creditquota: number; // 授信额度(金瑞)分拣室服务费(广钻)
+        curuserid: number;
+        hasauth: number; // 是否已实名认证 - 0:未认证 1:已认证 2:已提交(待审核) 3:已拒绝
+        hasuploaded: number; // 是否已同步(千海金) 0:未同步 1;已同步
+        isanonymous: number; // 是否匿名下单 - 0:否 1:是
+        maxLevel: number;
+        maxinvestornum: number; // 最大用户数(经纪会员下投资者个数)
+        memberuserid: number; // 所属会员ID
+        modifierid: number; // 修改人
+        modifyremark: string; // 变更备注
+        modifysrc: number; // 修改来源 - 1:管理端 2:终端
+        modifystatus: number; // 变更状态 1 未变更 2 变更中 3 变更待审核 4 变更待复核(投资者)
+        modifytime: string; // 修改时间
+        outeruserid: string; // 外部用户ID(千海金-外部门店ID)
+        parenttopuser: string; // 上级顶级机构 [092=0,1时,默认为1, 092=2时若自已为顶级,则填入自己,自己不为顶级,填入ParentUserID的ParentTopUser]
+        parentuserid: number; // 所属机构ID
+        pathname: string; // 联系人
+        reckonaccountid: number; // 默认结算资金账号ID(机构分润使用) 作废
+        refercount: number; // 推荐总人数
+        refereeuserid: number; // 推荐人ID
+        refernum: string; // 推荐码
+        roleIds: string;
+        rootuserid: number; // 根用户ID
+        secrefercount: number; // 间接推荐总人数
+        sjaccountno: string; // 送检账户(广钻)
+        subaccountlevel: number; // 子账户层数
+        subarealevel: number;
+        subarealevelpath: string; // 子机构层级路径(逗号分隔,首尾加逗号)
+        subjectid: number; // 所属部门(业务部门)
+        teammanageruserid: number; // 团队经理用户ID(千海金:门店代理)
+        uploadedtime: string; // 同步时间
+        userName: string;
+        userid: number; // 用户ID
+        userinfotype: number; // 所有者类型
+        usertype: number; // 账户类型 - 1:交易所 2:机构 3:会员子机构 4:经纪人 5:投资者 6:客户 7:企业成员(云平台)
+    }
+
+    /** 会员机构管理-->子机构管理-->撤回 请求 */
+    interface organSonRebackChangeReq {
+        areaid: number;
+    }
+
+    /** 会员机构管理-->子机构管理-->恢复 请求 */
+    interface organSonRecoverReq {
+        areaid: number;
+    }
+
+    /** 会员机构管理-->子机构管理-->机构详情 请求 */
+    interface organSonViewsonReq {
+        areaid: number;
+        modifystatus: number;
+    }
+
+    /** 会员机构管理-->子机构管理-->机构详情 响应 */
+    interface organSonViewsonRsp {
+        logincode: string;
+        mobileUrl: string;
+        newResult: {
+            userAccountDetailVo: UserAccountDetailVo;
+            userinfoDetailVo: UserinfoDetailVo;
+        };
+        oldResult: {
+            userAccountDetailVo: UserAccountDetailVo;
+            userinfoDetailVo: UserinfoDetailVo;
+        };
+        openUrl: string;
+        sanfangUrl: string;
+        userid: number;
+        username: string;
+        userstatus: number;
+        weixinUrl: string;
+    }
+
+    interface UserAccountDetailVo {
+        accountName: string; // userAccount – 交易商名称/申请人()
+        accountStatus: number; // userAccount – 机构状态/modifyStatus == 2,3,4 不展示
+        auditAccountName: string; // userAccount – 审核人/modifyStatus == 2,3,4 不展示
+        auditTime: string; // userAccount – 审核人时间/modifyStatus == 2,3,4 不展示
+        borkerName: string; // userAccount – 经纪人/为空不展示
+        createName: string; // userAccount – 开户人/ openmode == 1 展示,openmode != 1 展示申请人accountName
+        createTime: string; // userAccount – 开户时间
+        isAuth: number; // userAccount – isAuth/固定用before
+        memberUserName: string; // userAccount – 所属会员/ 固定用before
+        modifyName: string; // userAccount – 修改人/固定用before
+        modifyRemark: string; // userAccount – 变更审核备注/固定用before
+        modifyStatus: number; // userAccount – 变更状态/固定用before
+        modifyTime: string; // userAccount – 修改时间/固定用before
+        parentUserName: string; // userAccount – 所属机构
+        parentuserid: number;
+        refereeUserName: string; // userAccount – 推荐人/为空不展示
+        refereeuserid: number;
+        userId: number; // userAccount – 交易商代码
+        usertype: number;
+    }
+
+    interface UserinfoDetailVo {
+        address: string; // userinfo – 通讯地址/pathName+address
+        attachment1: string;
+        attachment2: string;
+        bankAccount: string; // userinfo – 银行账户/银行卡信息 bankname!=NULL 展示
+        bankCardFrontPhotoUrl: string; // userinfo – 银行卡正面/银行卡信息 bankname!=NULL 展示
+        bankName: string; // userinfo – 银行名称/银行卡信息 bankname!=NULL 展示
+        bankid: string;
+        bizNature: number; // userinfo – 企业性质/userinfotype ==2 展示
+        cardBackPhotoUrl: string; // userinfo – 证件照反面/为空不展示
+        cardFrontPhotoUrl: string; // userinfo – userinfotype = 1证件照正面 / userinfotype = 2营业执照
+        cardNum: string; // userinfo – 证件号码
+        cardTypeId: number; // userinfo – 证件类型/code-certificatetype
+        cityid: number;
+        company: string; // userinfo – 所属公司
+        contactName: string; // userinfo – 联系人/userinfotype ==2 展示
+        customerName: string; // userinfo – 企业名称/userinfotype ==2 展示
+        districtid: number;
+        email: string; // userinfo – 邮箱
+        halfBodyPhotoUrl: string; // userinfo – 手持证件照/为空不展示
+        legalCardBackPhotoUrl: string; // userinfo – 法人身份证背面照/userinfotype ==2 展示
+        legalCardFrontPhotoUrl: string; // userinfo – 法人身份证正面照/userinfotype ==2 展示
+        legalPersonName: string; // userinfo – 法人姓名/userinfotype ==2 展示
+        mobile: string; // userinfo – 手机号
+        needInvoice: number; // userinfo – 是否需要发票/modifyStatus == 2,3,4 不展示
+        openMode: number; // userinfo – 开户方式
+        otherUrl: string; // userinfo – 法人授权书/userinfotype ==2 展示
+        pathName: string; // userinfo – 通迅地址
+        postalCode: string; // userinfo – 邮政编码
+        provinceid: number;
+        remark: string; // userinfo – 备注
+        qq: string;
+        sex: number; // userinfo – 性别
+        telPhone: string; // userinfo – 联系电话
+        userinfoType: number; // userinfo – 用户类型
+        wechat: string; // userinfo – 微信
+    }
 }