liyongli 1 年間 前
コミット
656a5eed47

+ 120 - 34
src/api/index.js

@@ -64,58 +64,134 @@ function user_edit_api(data) {
 }
 
 function custom_list_api(data) {
-    return service({
-        url: '/admin/custom/list',
-        method: 'POST',
-        data,
-    })
+  return service({
+    url: '/admin/custom/list',
+    method: 'POST',
+    data,
+  });
 }
 
 function custom_rule_api(data) {
-    return service({
-        url: '/admin/user-role/list',
-        method: 'POST',
-        data,
-    })
+  return service({
+    url: '/admin/user-role/list',
+    method: 'POST',
+    data,
+  });
 }
 
 function organ_api(data) {
-    return service({
-        url: '/admin/organ/list',
-        method: 'POST',
-        data,
-    })
+  return service({
+    url: '/admin/organ/list',
+    method: 'POST',
+    data,
+  });
+}
+
+function organ_update(data) {
+  return service({
+    url: '/admin/organ/update',
+    method: 'POST',
+    data,
+  });
+}
+function organ_create(data) {
+  return service({
+    url: '/admin/organ/add',
+    method: 'POST',
+    data,
+  });
+}
+function organ_del(data) {
+  return service({
+    url: '/admin/organ/delete/' + data,
+    method: 'DELETE',
+  });
 }
 
 function region_api(data) {
-    return service({
-        url: '/admin/region/tree',
-        method: 'GET',
-        data,
-    })
+  return service({
+    url: '/admin/region/tree',
+    method: 'GET',
+    data,
+  });
 }
 
 function custom_add(params) {
-    return service({
-        url: '/admin/custom/add',
-        method: 'POST',
-        data: params,
-    })
+  return service({
+    url: '/admin/custom/add',
+    method: 'POST',
+    data: params,
+  });
 }
 
 function custom_del(data) {
-    return service({
-        url: '/admin/custom/delete/' + data,
-        method: 'DELETE',
-    })
+  return service({
+    url: '/admin/custom/delete/' + data,
+    method: 'DELETE',
+  });
 }
 
 function custom_updata(data) {
+  return service({
+    url: '/admin/custom/update',
+    method: 'POST',
+    data,
+  });
+}
+
+function live_list(params) {
+  return service({
+    url: '/admin/live-stream/list',
+    method: 'GET',
+    params,
+  });
+}
+
+function live_add(data) {
+  return service({
+    url: '/admin/live-stream/add',
+    method: 'POST',
+    data,
+  });
+}
+
+function live_update(data) {
+  return service({
+    url: '/admin/live-stream/update',
+    method: 'POST',
+    data,
+  });
+}
+
+function live_del(id) {
+  return service({
+    url: '/admin/live-stream/delete/' + id,
+    method: 'DELETE',
+  });
+}
+
+function leader_api(data) {
+  return service({
+    url: '/admin/leaders/list',
+    method: 'POST',
+    data,
+  });
+}
+
+function leader_add(data) {
+    return service({
+      url: '/admin/leaders/add',
+      method: 'POST',
+      data,
+    });
+}
+
+function leader_update(data) {
     return service({
-        url: '/admin/custom/update',
-        method: 'POST',
-        data,
-    })
+      url: '/admin/leaders/update',
+      method: 'POST',
+      data,
+    });
 }
 
 export default {
@@ -130,8 +206,18 @@ export default {
   custom_list_api,
   custom_rule_api,
   organ_api,
+  organ_update,
+  organ_create,
+  organ_del,
   region_api,
   custom_add,
   custom_del,
-  custom_updata
+  custom_updata,
+  live_list,
+  live_add,
+  live_del,
+  live_update,
+  leader_api,
+  leader_add,
+  leader_update
 };

+ 45 - 6
src/router/index.js

@@ -19,22 +19,61 @@ export default vueRouter.createRouter({
       },
       children: [
         {
-          path: "/admin/users",
+          path: '/admin/users',
           meta: {
             title: '人员管理',
           },
           children: [
             {
-              path: "/admin/users/list",
-              component: () =>
-                import('../view/system/index.vue'),
+              path: '/admin/users/list',
+              component: () => import('../view/system/index.vue'),
             },
             {
-              path: "/admin/custom",
+              path: '/admin/custom',
               component: () => import('../view/user/index.vue'),
-            }
+            },
           ],
         },
+        {
+          path: '/admin/module',
+          meta: {
+            title: '菜单管理',
+          },
+          children: [],
+          component: () => import('../view/menu/index.vue'),
+        },
+        {
+          path: '/admin/region',
+          meta: {
+            title: '地域管理',
+          },
+          children: [],
+          component: () => import('../view/region/index.vue'),
+        },
+        {
+          path: '/admin/organ',
+          meta: {
+            title: '机构管理',
+          },
+          children: [],
+          component: () => import('../view/institution/index.vue'),
+        },
+        {
+          path: '/admin/live-stream',
+          meta: {
+            title: '直播流管理',
+          },
+          children: [],
+          component: () => import('../view/liveStream/index.vue'),
+        },
+        {
+          path: '/admin/leaders',
+          meta: {
+            title: '领导管理',
+          },
+          children: [],
+          component: () => import('../view/leader/index.vue'),
+        },
       ],
     },
   ],

+ 6 - 3
src/view/home/index.vue

@@ -14,19 +14,22 @@
             :active-name="active_name"
             theme="primary"
             width="auto"
-            :open-names="['home']"
             @on-select="changePage"
             accordion
+            v-if="menu_list.length"
           >
             <div v-for="(item, i) in menu_list" :key="i">
-              <Submenu v-if="item.children && item.children.length" :name="item.router">
+              <Submenu
+                v-if="item.children && item.children.length"
+                :name="item.router"
+              >
                 <template #title>
                   <Icon :type="item.icon || 'ios-browsers'" />
                   {{ item.name }}
                 </template>
                 <MenuItem
                   v-for="v in item.children"
-                  :key="v.router"
+                  :key="v.moduleId"
                   :name="v.router"
                 >
                   {{ v.name }}

+ 263 - 0
src/view/institution/index.vue

@@ -0,0 +1,263 @@
+<!-- vue 页面模板 -->
+<template>
+  <div class="user">
+    <Space wrap style="margin-bottom: 1em">
+      <Button type="primary" icon="ios-search" @click="() => show_edit()">
+        新增
+      </Button>
+      <Input
+        v-model="searchText"
+        placeholder="请输入搜索内容"
+        icon="ios-search"
+        @on-click="() => change(1)"
+        @on-enter="() => change(1)"
+      >
+      </Input>
+    </Space>
+    <Table highlight-row ref="currentRowTable" :columns="columns" :data="list">
+      <template #tool="{ row }">
+        <Space wrap>
+          <Poptip
+            transfer
+            confirm
+            width="90"
+            title="删除该用户?"
+            @on-ok="() => del_user(row)"
+          >
+            <Button size="small" type="error"> 删 除 </Button>
+          </Poptip>
+          <Button size="small" type="primary" @click="() => show_edit(row)">
+            修 改
+          </Button>
+        </Space>
+      </template>
+    </Table>
+    <br />
+    <Page
+      :total="total"
+      show-sizer
+      v-model="page"
+      @on-change="change"
+      @on-page-size-change="sizeChange"
+    />
+
+    <Drawer
+      :mask-closable="false"
+      title="机构详情"
+      placement="right"
+      v-model="show_user_edit"
+    >
+      <Form
+        ref="formInline"
+        :model="user"
+        :rules="ruleInline"
+        :label-width="80"
+      >
+        <FormItem label="机构名">
+          <Input v-model="user.name" placeholder="请输入机构名"></Input>
+        </FormItem>
+        <FormItem label="类型">
+          <Input v-model="user.category" placeholder="请输入机构类型"></Input>
+        </FormItem>
+        <FormItem label="所属机构">
+          <Select
+            v-model="user.pid"
+            filterable
+            :remote-method="get_regan_data"
+            :loading="isLoad"
+            @on-change="change_regan"
+          >
+            <Option
+              v-for="(option, index) in organ"
+              :value="option.organId"
+              :key="index"
+            >
+              {{ option.name }}
+            </Option>
+          </Select>
+        </FormItem>
+        <FormItem label="地域">
+          <TreeSelect v-model="user.regionId" :data="region" />
+        </FormItem>
+        <FormItem label="简介">
+          <Input
+            v-model="user.info"
+            type="textarea"
+            :rows="4"
+            placeholder="请输入简介"
+          ></Input>
+        </FormItem>
+        <FormItem>
+          <Button type="primary" @click="save_user">保 存</Button>
+        </FormItem>
+      </Form>
+    </Drawer>
+  </div>
+</template>
+
+<script setup>
+import { ref, onMounted } from 'vue';
+import { Image, Message } from 'view-ui-plus';
+
+import api from '../../api/index.js';
+
+const searchText = ref('');
+const total = ref(0);
+const page = ref(1);
+const pageSize = ref(10);
+const formInline = ref(null);
+const list = ref([]);
+const user = ref({
+  headSculpture: [],
+  regionId: '',
+});
+const organ = ref([]);
+const region = ref([]);
+const show_user_edit = ref(false);
+const isLoad = ref(false);
+
+const columns = [
+  {
+    title: '机构名称',
+    key: 'name',
+    align: 'center',
+  },
+  {
+    title: '简介',
+    key: 'info',
+    align: 'center',
+  },
+  {
+    title: '操作',
+    slot: 'tool',
+    align: 'center',
+  },
+];
+const ruleInline = {
+  name: [
+    {
+      required: true,
+      message: '请输入姓名',
+      trigger: 'blur',
+    },
+  ],
+};
+
+onMounted(() => {});
+get_list();
+get_regan_data();
+get_region_api();
+
+function change(p) {
+  page.value = p;
+  get_list();
+}
+
+function sizeChange(pageSize) {
+  pageSize.value = pageSize;
+  get_list();
+}
+
+function get_list() {
+  api
+    .organ_api({
+      page: page.value,
+      pageSize: pageSize.value,
+      name: searchText.value,
+    })
+    .then(r => {
+      list.value = r.records || [];
+      total.value = r.total || 0;
+    });
+}
+
+function show_edit(data) {
+  const row = JSON.parse(JSON.stringify(data || {}));
+  show_user_edit.value = true;
+  user.value = row || {
+    headSculpture: [],
+    regionId: '',
+  };
+}
+
+function save_user() {
+  formInline.value.validate(valid => {
+    if (!valid) return;
+    const U = user.value;
+    const p = {
+      organId: U.organId,
+      regionId: U.regionId,
+      pid: U.pid,
+      level: U.level,
+      name: U.name,
+      category: U.category,
+      authType: U.authType,
+      info: U.info,
+    };
+    if (!U.organId)
+      api.organ_create(p).then(() => {
+        Message.info('新增成功');
+        show_user_edit.value = false;
+        get_list();
+      });
+    else
+      api.organ_update(p).then(() => {
+        Message.info('修改成功');
+        show_user_edit.value = false;
+        get_list();
+      });
+  });
+}
+
+function get_regan_data(query) {
+  api
+    .organ_api({
+      page: 1,
+      pageSize: 100000,
+      name: query,
+    })
+    .then(r => {
+      const li = r.records || [];
+      organ.value = li;
+    });
+}
+
+function get_region_api() {
+  api.region_api().then(r => {
+    region.value = tree_change(r || []);
+  });
+}
+
+function tree_change(list) {
+  const li = [];
+  for (let i = 0; i < list.length; i++) {
+    const v = list[i];
+    v.title = v.name;
+    v.value = v.regionId;
+    v.expand = false;
+    v.selected = false;
+    v.checked = false;
+    li.children = tree_change(v.children || []);
+    li.push(v);
+  }
+  return li;
+}
+
+function del_user(row) {
+  api.organ_del(row.organId).then(() => {
+    Message.info('删除成功');
+    get_list();
+  });
+}
+
+function change_regan(val) {
+  const v = organ.value.find(v => v.organId == val);
+  if (!v) {
+    user.value.level = 1;
+  } else {
+    user.value.level = Number(v.level) + 1;
+  }
+}
+</script>
+
+<style lang="scss"></style>

+ 244 - 0
src/view/leader/index.vue

@@ -0,0 +1,244 @@
+<!-- vue 页面模板 -->
+<template>
+  <div class="user">
+    <Space wrap style="margin-bottom: 1em">
+      <Button type="primary" icon="ios-search" @click="() => show_edit()">
+        新增
+      </Button>
+      <Input
+        v-model="searchText"
+        placeholder="请输入搜索内容"
+        icon="ios-search"
+        @on-click="() => change(1)"
+        @on-enter="() => change(1)"
+      >
+      </Input>
+      <Select v-model="organ_val" style="width: 200px">
+        <Option
+          v-for="item in organ"
+          :value="item.organId"
+          :key="item.organId"
+          >{{ item.name }}</Option
+        >
+      </Select>
+    </Space>
+    <Table highlight-row ref="currentRowTable" :columns="columns" :data="list">
+      <template #tool="{ row }">
+        <Space wrap>
+          <Poptip
+            transfer
+            confirm
+            width="90"
+            title="删除该用户?"
+            @on-ok="() => del_user(row)"
+          >
+            <Button size="small" type="error"> 删 除 </Button>
+          </Poptip>
+          <Button size="small" type="primary" @click="() => show_edit(row)">
+            修 改
+          </Button>
+        </Space>
+      </template>
+      <template #photo="{ row }">
+        <img :src="row.photo" alt="暂无图片" style="width: 60px" />
+      </template>
+    </Table>
+    <br />
+    <Page
+      :total="total"
+      show-sizer
+      v-model="page"
+      @on-change="change"
+      @on-page-size-change="sizeChange"
+    />
+
+    <Drawer
+      :mask-closable="false"
+      title="直播流详情"
+      placement="right"
+      v-model="show_user_edit"
+    >
+      <Form
+        ref="formInline"
+        :model="user"
+        :rules="ruleInline"
+        :label-width="80"
+      >
+        <FormItem label="姓名">
+          <Input v-model="user.name" placeholder="请输入姓名"></Input>
+        </FormItem>
+        <FormItem label="简述">
+          <Input v-model="user.info" placeholder="请输入简述"></Input>
+        </FormItem>
+        <FormItem label="头像">
+        </FormItem>
+        <FormItem label="职位">
+          <Input
+            v-model="user.position"
+            :row="4"
+            placeholder="请输入职位"
+          ></Input>
+        </FormItem>
+        <FormItem label="级别">
+          <Input
+            v-model="user.position"
+            :row="4"
+            placeholder="请输入职位"
+          ></Input>
+        </FormItem>
+        <FormItem label="职位">
+          <Input
+            v-model="user.position"
+            :row="4"
+            placeholder="请输入职位"
+          ></Input>
+        </FormItem>
+        <FormItem>
+          <Button type="primary" @click="save_user">保 存</Button>
+        </FormItem>
+      </Form>
+    </Drawer>
+  </div>
+</template>
+
+<script setup>
+import { ref, onMounted } from 'vue';
+import { Message } from 'view-ui-plus';
+
+import api from '../../api/index.js';
+
+const searchText = ref('');
+const total = ref(0);
+const page = ref(1);
+const pageSize = ref(10);
+const formInline = ref(null);
+const list = ref([]);
+const user = ref({
+  headSculpture: [],
+  regionId: '',
+});
+const organ = ref([]);
+const organ_val = ref('');
+const show_user_edit = ref(false);
+
+const columns = [
+  {
+    title: '姓名',
+    key: 'name',
+    align: 'center',
+  },
+  {
+    title: '职位',
+    key: 'position',
+    align: 'center',
+  },
+  {
+    title: '头像',
+    slot: 'photo',
+    align: 'center',
+  },
+  {
+    title: '操作',
+    slot: 'tool',
+    align: 'center',
+  },
+];
+const ruleInline = {
+  name: [
+    {
+      required: true,
+      message: '请输入姓名',
+      trigger: 'blur',
+    },
+  ],
+};
+
+onMounted(() => {});
+get_list();
+get_organ_api();
+
+function change(p) {
+  page.value = p;
+  get_list();
+}
+
+function sizeChange(pageSize) {
+  pageSize.value = pageSize;
+  get_list();
+}
+
+function get_list() {
+  api
+    .leader_api({
+      page: page.value,
+      pageSize: pageSize.value,
+      name: searchText.value,
+    })
+    .then(r => {
+      console.log(r);
+      list.value = r.records || [];
+      total.value = r.total || 0;
+    });
+}
+
+function show_edit(data) {
+  const row = JSON.parse(JSON.stringify(data || {}));
+  show_user_edit.value = true;
+  user.value = row || {
+    headSculpture: [],
+    organId: '',
+  };
+}
+
+function save_user() {
+  formInline.value.validate(valid => {
+    if (!valid) return;
+    const U = user.value;
+    const p = {
+      info: U.info,
+      photo: U.photo,
+      position: U.position,
+      resume: U.resume,
+      level: U.level,
+      regionId: U.regionId,
+      sort: U.sort,
+      organId: U.organId,
+      name: U.name,
+      leaderId: U.leaderId,
+    };
+    console.log(p);
+    // if (!U.leaderId)
+    //   api.leader_add(p).then(() => {
+    //     Message.info('新增成功');
+    //     show_user_edit.value = false;
+    //     get_list();
+    //   });
+    // else
+    //   api.leader_update(p).then(() => {
+    //     Message.info('修改成功');
+    //     show_user_edit.value = false;
+    //     get_list();
+    //   });
+  });
+}
+
+function get_organ_api() {
+  api
+    .organ_api({
+      page: 1,
+      pageSize: 100000,
+    })
+    .then(r => {
+      organ.value = r.records || [];
+    });
+}
+
+function del_user(row) {
+  api.live_del(row.liveId).then(() => {
+    Message.info('删除成功');
+    get_list();
+  });
+}
+</script>
+
+<style lang="scss"></style>

+ 209 - 0
src/view/liveStream/index.vue

@@ -0,0 +1,209 @@
+<!-- vue 页面模板 -->
+<template>
+  <div class="user">
+    <Space wrap style="margin-bottom: 1em">
+      <Button type="primary" icon="ios-search" @click="() => show_edit()">
+        新增
+      </Button>
+      <Input
+        v-model="searchText"
+        placeholder="请输入搜索内容"
+        icon="ios-search"
+        @on-click="() => change(1)"
+        @on-enter="() => change(1)"
+      >
+      </Input>
+    </Space>
+    <Table highlight-row ref="currentRowTable" :columns="columns" :data="list">
+      <template #tool="{ row }">
+        <Space wrap>
+          <Poptip
+            transfer
+            confirm
+            width="90"
+            title="删除该用户?"
+            @on-ok="() => del_user(row)"
+          >
+            <Button size="small" type="error"> 删 除 </Button>
+          </Poptip>
+          <Button size="small" type="primary" @click="() => show_edit(row)">
+            修 改
+          </Button>
+        </Space>
+      </template>
+    </Table>
+    <br />
+    <Page
+      :total="total"
+      show-sizer
+      v-model="page"
+      @on-change="change"
+      @on-page-size-change="sizeChange"
+    />
+
+    <Drawer
+      :mask-closable="false"
+      title="直播流详情"
+      placement="right"
+      v-model="show_user_edit"
+    >
+      <Form
+        ref="formInline"
+        :model="user"
+        :rules="ruleInline"
+        :label-width="80"
+      >
+        <FormItem label="直播流名">
+          <Input v-model="user.name" placeholder="请输入直播流名"></Input>
+        </FormItem>
+        <FormItem label="流地址">
+          <Input v-model="user.url" placeholder="请输入直播流地址"></Input>
+        </FormItem>
+        <FormItem label="简介">
+          <Input
+            v-model="user.remark"
+            :row="4"
+            placeholder="请输入直播简介"
+          ></Input>
+        </FormItem>
+        <FormItem>
+          <Button type="primary" @click="save_user">保 存</Button>
+        </FormItem>
+      </Form>
+    </Drawer>
+  </div>
+</template>
+
+<script setup>
+import { ref, onMounted } from 'vue';
+import { Message } from 'view-ui-plus';
+
+import api from '../../api/index.js';
+
+const searchText = ref('');
+const total = ref(0);
+const page = ref(1);
+const pageSize = ref(10);
+const formInline = ref(null);
+const list = ref([]);
+const user = ref({
+  headSculpture: [],
+});
+const show_user_edit = ref(false);
+
+const columns = [
+  {
+    title: '直播流名称',
+    key: 'name',
+    align: 'center',
+  },
+  {
+    title: '简介',
+    key: 'remark',
+    align: 'center',
+  },
+  {
+    title: '流地址',
+    key: 'url',
+    align: 'center',
+  },
+  {
+    title: '操作',
+    slot: 'tool',
+    align: 'center',
+  },
+];
+const ruleInline = {
+  name: [
+    {
+      required: true,
+      message: '请输入姓名',
+      trigger: 'blur',
+    },
+  ],
+};
+
+onMounted(() => {});
+get_list();
+
+function change(p) {
+  page.value = p;
+  get_list();
+}
+
+function sizeChange(pageSize) {
+  pageSize.value = pageSize;
+  get_list();
+}
+
+function get_list() {
+  api
+    .live_list({
+      page: page.value,
+      pageSize: pageSize.value,
+      name: searchText.value,
+    })
+    .then(r => {
+      list.value = r || [];
+      total.value = r.total || 0;
+    });
+}
+
+function show_edit(data) {
+  const row = JSON.parse(JSON.stringify(data || {}));
+  show_user_edit.value = true;
+  user.value = row || {
+    headSculpture: [],
+  };
+}
+
+function save_user() {
+  formInline.value.validate(valid => {
+    if (!valid) return;
+    const U = user.value;
+    const p = {
+      name: U.name,
+      url: U.url,
+      remark: U.remark,
+      liveId: U.liveId
+    };
+    console.log(p);
+    if (!U.liveId)
+      api.live_add(p).then(() => {
+        Message.info('新增成功');
+        show_user_edit.value = false;
+        get_list();
+      });
+    else
+      api.live_update(p).then(() => {
+        Message.info('修改成功');
+        show_user_edit.value = false;
+        get_list();
+      });
+  });
+}
+
+function tree_change(list) {
+  const li = [];
+  for (let i = 0; i < list.length; i++) {
+    const v = list[i];
+    v.title = v.name;
+    v.value = v.regionId;
+    v.expand = false;
+    v.selected = false;
+    v.checked = false;
+    li.children = tree_change(v.children || []);
+    li.push(v);
+  }
+  return li;
+}
+
+function del_user(row) {
+  api.live_del(row.liveId).then(() => {
+    Message.info('删除成功');
+    get_list();
+  });
+}
+</script>
+
+<style lang="scss"></style>

+ 438 - 0
src/view/menu/index.vue

@@ -0,0 +1,438 @@
+<!-- vue 页面模板 -->
+<template>
+    <div class="user">
+      <Space wrap style="margin-bottom: 1em">
+        <Button type="primary" icon="ios-search" @click="() => show_edit()">
+          新增
+        </Button>
+        <Input
+          v-model="searchText"
+          placeholder="请输入搜索内容"
+          icon="ios-search"
+          @on-click="() => change(1)"
+          @on-enter="() => change(1)"
+        >
+        </Input>
+      </Space>
+      <Table highlight-row ref="currentRowTable" :columns="columns" :data="list">
+        <template #tool="{ row }">
+          <Space wrap>
+            <Poptip
+              transfer
+              confirm
+              width="90"
+              title="删除该用户?"
+              @on-ok="() => del_user(row)"
+            >
+              <Button size="small" type="error"> 删 除 </Button>
+            </Poptip>
+            <Button size="small" type="primary" @click="() => show_edit(row)">
+              修 改
+            </Button>
+          </Space>
+        </template>
+        <template #photo="{ row }">
+          <Image :src="row.photo" fit="cover" width="58px" height="58px">
+            <template #error>
+              <Icon type="ios-image-outline" size="24" color="#ccc" />
+            </template>
+          </Image>
+        </template>
+      </Table>
+      <br />
+      <Page
+        :total="total"
+        show-sizer
+        v-model="page"
+        @on-change="change"
+        @on-page-size-change="sizeChange"
+      />
+  
+      <Drawer
+        :mask-closable="false"
+        title="用户详情"
+        placement="right"
+        v-model="show_user_edit"
+      >
+        <Form
+          ref="formInline"
+          :model="user"
+          :rules="ruleInline"
+          :label-width="80"
+        >
+          <FormItem label="用户名">
+            <Input v-model="user.name" placeholder="请输入用户名"></Input>
+          </FormItem>
+          <FormItem label="头像">
+            <div class="img-box" v-if="user.photo && user.photo.url">
+              <Image
+                :src="user.photo.url"
+                fit="cover"
+                width="100%"
+                height="100%"
+              />
+              <Icon
+                type="ios-trash-outline"
+                class="check-icon"
+                size="25"
+                @click="handleRemove"
+              ></Icon>
+            </div>
+            <Upload
+              ref="upload"
+              v-else
+              :show-upload-list="false"
+              :on-success="handle_success"
+              :format="['jpg', 'jpeg', 'png']"
+              :max-size="5120"
+              :on-format-error="handle_format_error"
+              :headers="{
+                Authorization: token,
+              }"
+              type="drag"
+              :action="base_url + '/admin/leaders/upload'"
+              style="display: inline-block; width: 58px"
+            >
+              <div style="width: 58px; height: 58px; line-height: 58px">
+                <Icon type="ios-camera" size="20"></Icon>
+              </div>
+            </Upload>
+          </FormItem>
+          <FormItem label="角色">
+            <Select
+              v-model="user.roleId"
+              filterable
+              :remote-method="get_role_data"
+              :loading="isLoad"
+            >
+              <Option
+                v-for="(option, index) in rules"
+                :value="option.roleId"
+                :key="index"
+              >
+                {{ option.name }}
+              </Option>
+            </Select>
+          </FormItem>
+          <FormItem label="机构">
+            <Select
+              v-model="user.organId"
+              filterable
+              :remote-method="get_regan_data"
+              :loading="isLoad"
+            >
+              <Option
+                v-for="(option, index) in organ"
+                :value="option.organId"
+                :key="index"
+              >
+                {{ option.name }}
+              </Option>
+            </Select>
+          </FormItem>
+          <FormItem label="地域">
+            <TreeSelect v-model="user.regionId" :data="region" />
+          </FormItem>
+          <FormItem label="手机号">
+            <Input v-model="user.phone" placeholder="请输入手机号"></Input>
+          </FormItem>
+          <FormItem label="密码">
+            <Input
+              v-model="user.newpassword"
+              type="password"
+              placeholder="请输入密码"
+            ></Input>
+          </FormItem>
+          <FormItem label="简介">
+            <Input
+              v-model="user.info"
+              type="textarea"
+              :rows="4"
+              placeholder="请输入简介"
+            ></Input>
+          </FormItem>
+          <FormItem label="职位">
+            <Input v-model="user.position" placeholder="请输入职位"></Input>
+          </FormItem>
+          <FormItem label="职级">
+            <Input v-model="user.level" placeholder="请输入职级"></Input>
+          </FormItem>
+          <FormItem label="履历">
+            <Input
+              v-model="user.resume"
+              type="textarea"
+              :rows="4"
+              placeholder="请输入履历"
+            ></Input>
+          </FormItem>
+          <FormItem>
+            <Button type="primary" @click="save_user">保 存</Button>
+          </FormItem>
+        </Form>
+      </Drawer>
+    </div>
+  </template>
+  
+  <script setup>
+  import { ref, onMounted } from 'vue';
+  import { Image, Message } from 'view-ui-plus';
+  
+  import api from '../../api/index.js';
+  import { base_url } from '../../config/index';
+  
+  const token = localStorage.getItem('neican_token');
+  const searchText = ref('');
+  const total = ref(0);
+  const page = ref(1);
+  const pageSize = ref(10);
+  const formInline = ref(null);
+  const upload = ref(null);
+  const list = ref([]);
+  const user = ref({
+    headSculpture: [],
+    photo: {},
+    regionId: '',
+  });
+  const rules = ref([]);
+  const organ = ref([]);
+  const region = ref([]);
+  const show_user_edit = ref(false);
+  const isLoad = ref(false);
+  
+  const columns = [
+    {
+      title: '名字',
+      key: 'name',
+      align: 'center',
+    },
+    {
+      title: '头像',
+      slot: 'photo',
+      align: 'center',
+    },
+    {
+      title: '手机号',
+      key: 'phone',
+      align: 'center',
+    },
+    {
+      title: '级别',
+      key: 'level',
+      align: 'center',
+    },
+    {
+      title: '操作',
+      slot: 'tool',
+      align: 'center',
+    },
+  ];
+  const ruleInline = {
+    name: [
+      {
+        required: true,
+        message: '请输入姓名',
+        trigger: 'blur',
+      },
+    ],
+    newpassword: [
+      {
+        required: true,
+        message: '请输入密码',
+        trigger: 'blur',
+      },
+    ],
+    phone: [
+      {
+        required: true,
+        message: '请输入手机号',
+        trigger: 'blur',
+      },
+    ],
+  };
+  
+  onMounted(() => {});
+  get_list();
+  get_role_data();
+  get_regan_data();
+  get_region_api();
+  
+  function change(p) {
+    page.value = p;
+    get_list();
+  }
+  
+  function sizeChange(pageSize) {
+    pageSize.value = pageSize;
+    get_list();
+  }
+  
+  function get_list() {
+    api
+      .custom_list_api({
+        page: page.value,
+        pageSize: pageSize.value,
+        name: searchText.value,
+      })
+      .then(r => {
+        list.value = r.records || [];
+        total.value = r.total || 0;
+      });
+  }
+  
+  function show_edit(data) {
+    const row = JSON.parse(JSON.stringify(data || {}));
+    show_user_edit.value = true;
+    if (row.photo)
+      row.photo = {
+        url: row.photo,
+      };
+    user.value = row || {
+      headSculpture: [],
+      photo: {},
+      regionId: '',
+    };
+  }
+  
+  function save_user() {
+    formInline.value.validate(valid => {
+      if (!valid) return;
+      const U = user.value;
+      if (!U.userId)
+        api
+          .custom_add({
+            name: U.name,
+            regionId: U.regionId,
+            organId: U.organId,
+            phone: U.phone,
+            password: U.newpassword,
+            info: U.info,
+            photo: U.photo.url,
+            position: U.position,
+            resume: U.resume,
+            level: U.level,
+            roleId: U.roleId,
+          })
+          .then(() => {
+            Message.info('新增成功');
+            show_user_edit.value = false;
+            get_list();
+          });
+      else
+        api
+          .custom_updata({
+            name: U.name,
+            regionId: U.regionId,
+            organId: U.organId,
+            phone: U.phone,
+            password: U.newpassword,
+            info: U.info,
+            photo: U.photo.url,
+            position: U.position,
+            resume: U.resume,
+            level: U.level,
+            roleId: U.roleId,
+            userId: U.userId,
+          })
+          .then(() => {
+            Message.info('修改成功');
+            show_user_edit.value = false;
+            get_list();
+          });
+    });
+  }
+  
+  function get_role_data(query) {
+    isLoad.value = true;
+    api
+      .user_role_api({
+        page: 1,
+        pageSize: 100000,
+        name: query,
+      })
+      .then(r => {
+        isLoad.value = false;
+        rules.value = r.records || [];
+      })
+      .catch(err => {
+        isLoad.value = false;
+      });
+  }
+  
+  function get_regan_data(query) {
+    api
+      .organ_api({
+        page: 1,
+        pageSize: 100000,
+        name: query,
+      })
+      .then(r => {
+        organ.value = r.records || [];
+      });
+  }
+  
+  function get_region_api() {
+    api.region_api().then(r => {
+      region.value = tree_change(r || []);
+    });
+  }
+  
+  function tree_change(list) {
+    const li = [];
+    for (let i = 0; i < list.length; i++) {
+      const v = list[i];
+      v.title = v.name;
+      v.value = v.regionId;
+      v.expand = false;
+      v.selected = false;
+      v.checked = false;
+      li.children = tree_change(v.children || []);
+      li.push(v);
+    }
+    return li;
+  }
+  
+  function handle_success(response, file, fileList) {
+    user.value.photo.url = response.data.url || '';
+    user.value.photo.file = file || null;
+    Message.info('头像上传成功');
+  }
+  
+  function handle_format_error(file) {
+    Message.info('头像上传失败');
+  }
+  
+  function handleRemove() {
+    user.value.photo.url = '';
+    user.value.photo.file = null;
+  }
+  
+  function del_user(row) {
+    api.custom_del(row.userId).then(() => {
+      Message.info('删除成功');
+      get_list();
+    });
+  }
+  </script>
+  
+  <style lang="scss">
+  .img-box {
+    width: 58px;
+    height: 58px;
+    position: relative;
+  
+    .check-icon {
+      opacity: 0;
+      transition: all 0.5s;
+      position: absolute;
+      top: 50%;
+      left: 50%;
+      transform: translate(-50%, -50%);
+      z-index: 1;
+  
+      &:hover {
+        opacity: 1;
+      }
+    }
+  }
+  </style>
+  

+ 39 - 0
src/view/region/index.vue

@@ -0,0 +1,39 @@
+<!-- vue 页面模板 -->
+<template>
+  <Tree :data="list"></Tree>
+</template>
+
+<script setup>
+import { ref, onMounted } from 'vue';
+
+import api from '../../api/index.js';
+
+const list = ref([]);
+
+onMounted(() => {});
+get_list();
+
+function get_list() {
+  api.region_api().then(r => {
+    list.value = tree_change(r || []);
+  });
+}
+
+
+function tree_change(list) {
+  const li = [];
+  for (let i = 0; i < list.length; i++) {
+    const v = list[i];
+    v.title = v.name;
+    v.value = v.regionId;
+    v.expand = false;
+    v.selected = false;
+    v.checked = false;
+    li.children = tree_change(v.children || []);
+    li.push(v);
+  }
+  return li;
+}
+</script>
+
+<style lang="scss"></style>