From cec75849fc7db84a681b398f544e4d3e40d7d0f7 Mon Sep 17 00:00:00 2001
From: hejianhao <15708179461@qq.com>
Date: 星期四, 15 五月 2025 17:59:18 +0800
Subject: [PATCH] 菌种评定、项目管理

---
 culture/src/views/deliveryAssessment/projectTeamIntegral/service.js |   11 
 culture/src/views/system/user/components/add-edit.vue               |   44 +
 culture/src/router/index.js                                         |   48 +
 culture/src/components/Table/index.vue                              |   10 
 culture/src/views/projectList/service.js                            |   12 
 culture/src/components/SelectMember/index.vue                       |  109 ++++-
 culture/src/layouts/components/HeaderNav.vue                        |    2 
 culture/src/views/projectList/editProject.vue                       |  285 +++++++++++++++
 culture/src/views/system/user/index.vue                             |   53 +-
 culture/src/views/deliveryAssessment/projectTeamIntegral/detail.vue |   80 +++
 culture/src/components/SelectMember/service.js                      |   16 
 culture/src/views/deliveryAssessment/projectTeamIntegral/index.vue  |   70 ++-
 culture/src/views/system/user/components/reset-password.vue         |    8 
 culture/src/views/projectList/addProject.vue                        |   91 +++-
 culture/src/views/system/user/service.js                            |    2 
 culture/src/views/projectList/detailProject.vue                     |  233 ++++++++++++
 16 files changed, 915 insertions(+), 159 deletions(-)

diff --git a/culture/src/components/SelectMember/index.vue b/culture/src/components/SelectMember/index.vue
index 62039ee..7182483 100644
--- a/culture/src/components/SelectMember/index.vue
+++ b/culture/src/components/SelectMember/index.vue
@@ -1,6 +1,6 @@
 <template>
-    <el-dialog class="select-member" :visible.sync="visible" width="53.33%" :close-on-click-modal="false"
-        :show-close="false">
+    <el-dialog @open="openDialog" class="select-member" :visible.sync="visible" width="53.33%"
+        :close-on-click-modal="false" :show-close="false">
         <template #title>
             <div>选择参与人员</div>
         </template>
@@ -22,9 +22,10 @@
                         <div class="select-member-content-left-list">
                             <div class="select-member-content-left-list-title">角色列表</div>
                             <div class="select-member-content-left-list-itemBox">
-                                <div v-for="item in 10" :key="item.id"
-                                    class="select-member-content-left-list-itemBox-item">
-                                    实验员
+                                <div @click="searchUserList(item.roleId)" v-for="item in roleList" :key="item.roleId"
+                                    class="select-member-content-left-list-itemBox-item"
+                                    :class="roleId == item.roleId && 'active'">
+                                    {{ item.roleName }}
                                 </div>
                             </div>
                         </div>
@@ -35,15 +36,15 @@
                         <div class="select-member-content-right-header">
                             <div class="select-member-content-right-header-text">人员列表</div>
                             <div class="select-member-content-right-header-search">
-                                <el-input clearable v-model="searchName" placeholder="请输入姓名" />
+                                <el-input clearable v-model="nickNameOrPhone" placeholder="请输入姓名/手机号" />
                                 <el-button type="primary">搜索</el-button>
                             </div>
                         </div>
-                        <Table :data="tableData" :total="0" @selection-change="handleSelectionChange"
-                            :row-class-name="tableRowClassName">
+                        <Table ref="memberTable" :row-key="row => row.userId" :data="tableData" :total="0"
+                            @selection-change="handleSelectionChange" :row-class-name="tableRowClassName">
                             <el-table-column type="selection" width="55" />
-                            <el-table-column label="角色" prop="role" />
-                            <el-table-column label="姓名" prop="name" />
+                            <el-table-column label="角色" prop="roleName" />
+                            <el-table-column label="姓名" prop="nickName" />
                             <el-table-column label="创建时间" prop="createTime" />
                         </Table>
                     </div>
@@ -52,40 +53,79 @@
         </div>
         <div class="select-member-footer">
             <el-button @click="close" type="default">关闭</el-button>
-            <el-button type="primary">确认选择</el-button>
+            <el-button type="primary" @click="submit">确认选择</el-button>
         </div>
     </el-dialog>
 </template>
 
 <script>
-import { mapState } from 'vuex'
+import { getRoleList, getUserList } from './service'
 export default {
+    props: {
+        projectId: {
+            type: [String, Number],
+            default: null
+        }
+    },
     data() {
         return {
             visible: false,
             search: '',
-            searchName: '',
-            tableData: [
-                {
-                    name: '张三',
-                    role: '实验员',
-                    createTime: '2025-1-2 15:13:58'
-                },
-                {
-                    name: '李四',
-                    role: '实验员',
-                    createTime: '2025-1-2 15:13:58'
-                },
-            ],
-            selectData: []
+            nickNameOrPhone: '',
+            tableData: [],
+            selectData: [],
+            roleList: [],
+            roleId: null,
         }
     },
-    computed: {
-        ...mapState(['isFold'])
-    },
     methods: {
+        setSelection(selected) {
+            this.selectData = selected
+            this.$nextTick(() => {
+                // 设置新选中
+                this.tableData.forEach(row => {
+                    if (selected.some(i => i.userId === row.userId)) {
+                        this.$refs.memberTable.toggleRowSelection(row, true)
+                    }
+                })
+            })
+        },
+        openDialog() {
+            // 获取角色列表并根据项目组ID进行过滤
+            getRoleList().then(res => {
+                if (this.projectId) {
+                    // 过滤出实验员和化验师角色
+                    this.roleList = res.filter(item => item.roleId == 4 || item.roleId == 5);
+                } else {
+                    this.roleList = res;
+                }
+            });
+            this.searchUserList(null);
+        },
         handleSelectionChange(val) {
             this.selectData = val
+        },
+        async searchUserList(roleId) {
+            this.roleId = roleId
+            // 根据是否有项目组ID来决定调用不同的接口
+            const params = {
+                roleIds: roleId ? [roleId] : [],
+                nickNameOrPhone: this.searchName,
+                pageSize: 9999,
+                pageNum: 1
+            };
+
+            if (this.projectId) {
+                params.projectId = this.projectId;
+                // TODO: 这里需要替换为新的接口调用
+                // const res = await getProjectUserList(params);
+            } else {
+                const res = await getUserList(params);
+                this.tableData = res.records;
+            }
+
+            // 数据加载完成后重新应用选中状态
+            this.setSelection(this.selectData)
         },
         searchRole() {
             this.search = ''
@@ -96,8 +136,11 @@
         close() {
             this.visible = false
         },
+        submit() {
+            this.$emit('submit', this.selectData)
+        },
         tableRowClassName({ row, rowIndex }) {
-            if (this.selectData.findIndex(item => item.name === row.name) != -1) {
+            if (this.selectData.findIndex(item => item.userId === row.userId) != -1) {
                 return 'select-row';
             }
             return '';
@@ -191,6 +234,12 @@
                     &:last-child {
                         margin-bottom: 0;
                     }
+
+                    &:hover,
+                    &.active {
+                        background: rgba(4, 156, 154, 0.1);
+                        color: #049C9A;
+                    }
                 }
             }
         }
diff --git a/culture/src/components/SelectMember/service.js b/culture/src/components/SelectMember/service.js
new file mode 100644
index 0000000..cf0bc1e
--- /dev/null
+++ b/culture/src/components/SelectMember/service.js
@@ -0,0 +1,16 @@
+import axios from '@/utils/request';
+
+// 列表
+export const getProjectList = (data) => {
+    return axios.post('/api/t-project-team/pageList', { ...data })
+}
+
+// 用户列表
+export const getUserList = (data) => {
+    return axios.post('/system/user/list', { ...data })
+}
+
+// 角色列表不分页
+export const getRoleList = (data) => {
+    return axios.post('/system/role/listNotPage', { ...data })
+}
\ No newline at end of file
diff --git a/culture/src/components/Table/index.vue b/culture/src/components/Table/index.vue
index 82bc91c..30aefbd 100644
--- a/culture/src/components/Table/index.vue
+++ b/culture/src/components/Table/index.vue
@@ -1,6 +1,6 @@
 <template>
     <div class="table-container" style="width: 100%;">
-        <el-table border v-bind="$attrs" v-on="$listeners" :height="height">
+        <el-table ref="elTable"  border v-bind="$attrs" v-on="$listeners" :height="height">
             <slot></slot>
         </el-table>
         <div v-if="total > 0">
@@ -42,6 +42,14 @@
         }
     },
     methods: {
+        toggleRowSelection(row, selected) {
+            this.$refs.elTable.toggleRowSelection(row, selected)
+            this.$forceUpdate()
+        },
+        clearSelection() {
+            this.$refs.elTable.clearSelection()
+            this.$forceUpdate()
+        },
         handleCurrentChange(page) {
             this.$emit('handleCurrentChange', page)
         },
diff --git a/culture/src/layouts/components/HeaderNav.vue b/culture/src/layouts/components/HeaderNav.vue
index 570103c..5af7e7e 100644
--- a/culture/src/layouts/components/HeaderNav.vue
+++ b/culture/src/layouts/components/HeaderNav.vue
@@ -17,7 +17,7 @@
       </div>
       <div class="user-info">
         <img src="@/assets/public/photo.png" />
-        <div class="user-info-text">欢迎您,admin</div>
+        <div class="user-info-text">欢迎您,{{ userInfo.nickName }}</div>
         <div class="user-info-line"></div>
         <div @click="outLogin" class="user-info-out">
           <img src="@/assets/public/logOut.png" />
diff --git a/culture/src/router/index.js b/culture/src/router/index.js
index 07c3c42..eb36616 100644
--- a/culture/src/router/index.js
+++ b/culture/src/router/index.js
@@ -61,6 +61,24 @@
                     keepAlive: true,
                 },
                 component: () => import("../views/projectList/addProject"),
+            },
+            {
+                path: "editProject",
+                name: "EditProject",
+                meta: {
+                    title: "编辑菌种库项目组",
+                    hide: true,
+                },
+                component: () => import("../views/projectList/editProject"),
+            },
+            {
+                path: "detailProject",
+                name: "DetailProject",
+                meta: {
+                    title: "菌种库项目组详情",
+                    hide: true,
+                },
+                component: () => import("../views/projectList/detailProject"),
             }
         ]
     },
@@ -244,7 +262,7 @@
             {
                 path: 'breeding-record',
                 name: 'BreedingRecord',
-                meta: { 
+                meta: {
                     title: "菌种选育保藏记录",
                 },
                 component: () => import("../views/strain-library/breeding-record"),
@@ -408,21 +426,21 @@
 
     // 登录验证
     // 排除登录页的校验
-    // if (to.path === "/login") {
-    //     if (sessionStorage.getItem('token')) {
-    //         next('/projectList');  // 已登录状态访问登录页时重定向到系统首页
-    //         return;
-    //     }
-    //     next();
-    //     return;
-    // }
+    if (to.path === "/login") {
+        if (sessionStorage.getItem('token')) {
+            next('/projectList');  // 已登录状态访问登录页时重定向到系统首页
+            return;
+        }
+        next();
+        return;
+    }
 
-    // // 登录状态校验
-    // const isAuthenticated = sessionStorage.getItem('token');
-    // if (!isAuthenticated) {
-    //     next('/login');  // 未登录用户重定向到登录页
-    //     return;
-    // }
+    // 登录状态校验
+    const isAuthenticated = sessionStorage.getItem('token');
+    if (!isAuthenticated) {
+        next('/login');  // 未登录用户重定向到登录页
+        return;
+    }
 
     // 判断是否拥有要跳转菜单权限
     let menus = store.state.menus
diff --git a/culture/src/views/deliveryAssessment/projectTeamIntegral/detail.vue b/culture/src/views/deliveryAssessment/projectTeamIntegral/detail.vue
index 3c17bbb..94eda43 100644
--- a/culture/src/views/deliveryAssessment/projectTeamIntegral/detail.vue
+++ b/culture/src/views/deliveryAssessment/projectTeamIntegral/detail.vue
@@ -1,20 +1,23 @@
 <template>
-    <div>
+    <div v-if="Object.keys(detailData).length">
         <div class="top-box-header">
             <div class="top-box-header-title">
                 <div>项目组总积分表</div>
                 <div class="top-box-header-time">
-                    <div>评定开始时间:2024-02-09</div>
-                    <div>评定结束始时间:2024-02-09</div>
+                    <div>评定开始时间:{{ detailData.startTime }}</div>
+                    <div>评定结束始时间:{{ detailData.endTime }}</div>
                 </div>
             </div>
             <div class="top-box-integral">
                 <div :style="{ backgroundColor: ['rgba(232, 250, 246, 1)', 'rgba(254, 237, 220, 1)', 'rgba(239, 248, 255, 1)', 'rgba(255, 237, 238, 1)'][item - 1] }"
                     v-for="item in 4" :key="item" class="top-box-integral-card">
-                    <div class="top-box-integral-card-title">{{ ['项目组总积分', '化验师积分', '实验员积分', '实验终止次数'][item -
+                    <div class="top-box-integral-card-title">{{ ['项目组总积分', '菌种工程师积分', '菌种实验员积分', '菌种实验失败次数'][item -
                         1] }}</div>
                     <div :style="{ color: ['rgba(4, 156, 154, 1)', 'rgba(255, 147, 0, 1)', 'rgba(23, 119, 213, 1)', 'rgba(255, 73, 85, 1)'][item - 1] }"
-                        class="top-box-integral-card-num">99.9</div>
+                        class="top-box-integral-card-num">{{
+                            detailData[['teamIntegral', 'engineerIntegral', 'experimenterIntegral', 'failCount'][item - 1]]
+                        }}
+                    </div>
                 </div>
             </div>
         </div>
@@ -27,8 +30,13 @@
                     </div>
                 </div>
                 <div class="integral-content-box-right">
-                    <div v-show="actionsLeftTab != 1" @wheel.prevent="handleWheel" class="integral-content-box-right-nameTab">
-                        <div @click="changeActiveName(item)" :class="activeNameTab == item && 'activeName'" class="integral-content-box-right-nameTab-name" v-for="item in 8" :key="item">张三</div>
+                    <div v-show="actionsLeftTab != 1" @wheel.prevent="handleWheel"
+                        class="integral-content-box-right-nameTab">
+                        <div @click="changeActiveName(item.userName)"
+                            :class="activeNameTab == item.userName && 'activeName'"
+                            class="integral-content-box-right-nameTab-name"
+                            v-for="{ item, index } in detailData.detailExperimentVOS" :key="index">{{ item.userName }}
+                        </div>
                     </div>
                     <div class="integral-content-box-right-thead">
                         <div>评定项</div>
@@ -37,14 +45,31 @@
                         <div>结束时间</div>
                     </div>
                     <div class="integral-content-box-right-body">
-                        <div v-for="item in itemList" :key="item" class="integral-content-box-right-body-item">
+                        <div v-for="(item, index) in itemList" :key="index"
+                            class="integral-content-box-right-body-item">
                             <div>{{ item.gainer }}</div>
                             <div>
-                                <div v-if="item.situationOne">{{ item.situationOne }}</div>
-                                <div v-if="item.situationTwo">{{ item.situationTwo }}</div>
+                                <div>{{ item.situationOne }}{{
+                                    actionsLeftTab === 2 ?
+                                        (selectedExperimenter || {})[item.keys[0]] :
+                                        detailData[item.keys[0]]
+                                }}</div>
+                                <div>{{ item.situationTwo }}{{
+                                    actionsLeftTab === 2 ?
+                                        (selectedExperimenter || {})[item.keys[1]] :
+                                        detailData[item.keys[1]]
+                                }}</div>
                             </div>
-                            <div></div>
-                            <div></div>
+                            <div>{{
+                                actionsLeftTab === 2 ?
+                                    (selectedExperimenter || {})[item.keys[2]] :
+                                    detailData[item.keys[2]]
+                            }}</div>
+                            <div>{{
+                                actionsLeftTab === 2 ?
+                                    (selectedExperimenter || {})[item.keys[3]] :
+                                    detailData[item.keys[3]]
+                            }}</div>
                         </div>
                     </div>
                 </div>
@@ -54,27 +79,30 @@
 </template>
 
 <script>
+import { getDetailData } from './service'
 export default {
     data() {
         return {
             actionsLeftTab: 1,
-            activeNameTab: 1,
-            actionspPersonnel: null,
+            activeNameTab: '',
             craftList: [
                 {
                     gainer: '1、创新型课题',
                     situationOne: '课题数:',
                     situationTwo: '积分数:',
+                    keys: ['innovateCount', 'innovateIntegral', 'innovateStartTime', 'innovateEndTime']
                 },
                 {
                     gainer: '2、规程型课题',
                     situationOne: '课题数:',
                     situationTwo: '积分数:',
+                    keys: ['regulationCount', 'regulationIntegral', 'regulationStartTime', 'regulationEndTime']
                 },
                 {
                     gainer: '3、实验操作评定',
                     situationOne: '考核数:',
                     situationTwo: '积分数:',
+                    keys: ['handleCount', 'handleIntegral', 'handleStartTime', 'handleEndTime']
                 },
             ],//菌种工程师
             assayList: [
@@ -82,8 +110,11 @@
                     gainer: '1、实验操作评定',
                     situationOne: '考核数:',
                     situationTwo: '积分数:',
+                    keys: ['handleCount', 'handleIntegral', 'handleStartTime', 'handleEndTime']
                 },
             ],//菌种实验员
+            detailData: {},
+            selectedExperimenter: null
         }
     },
     computed: {
@@ -99,14 +130,29 @@
         }
     },
     created() {
-
+        getDetailData(this.$route.query.id).then(res => {
+            this.detailData = res;
+            // 确保detailExperimentVOS存在且是数组
+            this.detailData.detailExperimentVOS = this.detailData.detailExperimentVOS || [];
+            if (this.detailData.detailExperimentVOS.length) {
+                this.selectedExperimenter = this.detailData.detailExperimentVOS[0];
+                this.activeNameTab = this.selectedExperimenter.userName;
+            } else {
+                // 设置空对象保护
+                this.selectedExperimenter = {};
+                this.activeNameTab = '';
+            }
+        })
     },
     methods: {
         changeActiveItem(item) {
             this.actionsLeftTab = item
         },
-        changeActiveName(item) {
-            this.activeNameTab = item
+        changeActiveName(userName) {
+            this.activeNameTab = userName;
+            this.selectedExperimenter = this.detailData.detailExperimentVOS.find(
+                item => item.userName === userName
+            );
         },
         handleWheel(e) {
             if (this.scrollTimer) {
diff --git a/culture/src/views/deliveryAssessment/projectTeamIntegral/index.vue b/culture/src/views/deliveryAssessment/projectTeamIntegral/index.vue
index 03c4dfb..b80896b 100644
--- a/culture/src/views/deliveryAssessment/projectTeamIntegral/index.vue
+++ b/culture/src/views/deliveryAssessment/projectTeamIntegral/index.vue
@@ -5,34 +5,38 @@
             <template #search>
                 <el-form :model="form" label-width="140px" inline>
                     <el-form-item label="项目组名称:">
-                        <el-input v-model="form.name" placeholder="请输入"></el-input>
+                        <el-input v-model="form.teamName" placeholder="请输入"></el-input>
                     </el-form-item>
                     <el-form-item label="创建日期:">
-                        <el-date-picker v-model="value1" type="daterange" range-separator="至" start-placeholder="开始日期"
-                            end-placeholder="结束日期">
+                        <el-date-picker v-model="form.date" type="daterange" range-separator="至"
+                            start-placeholder="开始日期" end-placeholder="结束日期">
                         </el-date-picker>
                     </el-form-item>
                     <el-form-item label="状态:">
-                        <el-select placeholder="请选择"></el-select>
+                        <el-select placeholder="请选择" v-model="form.status">
+                            <el-option label="待审核" :value="1"></el-option>
+                            <el-option label="待评定" :value="2"></el-option>
+                            <el-option label="已评定" :value="3"></el-option>
+                            <el-option label="已驳回" :value="4"></el-option>
+                        </el-select>
                     </el-form-item>
                     <el-form-item class="search-btn-box">
-                        <el-button>重置</el-button>
-                        <el-button type="primary">查询</el-button>
+                        <el-button @click="reset">重置</el-button>
+                        <el-button type="primary" @click="search">查询</el-button>
                     </el-form-item>
                 </el-form>
             </template>
             <template #table>
-                <el-table-column prop="name" label="项目组名称" />
-                <el-table-column prop="age" label="项目组总积分" />
-                <el-table-column prop="age" label="工艺工程师积分" />
-                <el-table-column prop="age" label="化验师积分" />
-                <el-table-column prop="age" label="实验员积分" />
-                <el-table-column prop="age" label="评定开始时间" />
-                <el-table-column prop="age" label="评定结束时间" />
-                <el-table-column prop="age" label="状态" />
-                <el-table-column prop="age" label="操作">
+                <el-table-column prop="teamName" label="所属项目组" />
+                <el-table-column prop="teamIntegral" label="菌种项目组总积分" />
+                <el-table-column prop="engineerIntegral" label="菌种工程师积分" />
+                <el-table-column prop="experimenterIntegral" label="菌种实验员积分" />
+                <el-table-column prop="failCount" label="菌种实验员失败次数" />
+                <el-table-column prop="startTime" label="评定开始时间" />
+                <el-table-column prop="endTime" label="评定结束时间" />
+                <el-table-column label="操作">
                     <template #default="{ row }">
-                        <el-button @click="goDetail" type="text">详情</el-button>
+                        <el-button @click="goDetail(row.projectId)" type="text">详情</el-button>
                     </template>
                 </el-table-column>
             </template>
@@ -41,12 +45,12 @@
 </template>
 
 <script>
+import { getListData } from './service'
 export default {
     name: 'ProjectTeamIntegral',
     data() {
         return {
-            form: {
-            },
+            form: {},
             tableData: [],
             queryForm: {
                 pageSize: 10,
@@ -55,10 +59,13 @@
             total: 0
         }
     },
+    created() {
+        this.getList()
+    },
     methods: {
-        goDetail() {
+        goDetail(id) {
             this.$router.push({
-                path: '/projectList/addProject'
+                path: `/deliveryAssessment/projectTeamIntegral-detail?id=${id}`,
             })
         },
         handleCurrentChange(page) {
@@ -70,7 +77,28 @@
             this.getList()
         },
         getList() {
-
+            let obj = {
+                ...this.queryForm
+            }
+            if (obj.date) {
+                obj.startTime = moment(obj.date[0]).format('YYYY-MM-DD')
+                obj.endTime = moment(obj.date[1]).format('YYYY-MM-DD')
+                delete obj.date
+            }
+            getListData(obj).then(res => {
+                this.tableData = res.data.records
+                this.total = res.data.total
+            })
+        },
+        reset() {
+            this.queryForm = {
+                pageSize: 10,
+                pageNum: 1
+            }
+            this.getList()
+        },
+        search() {
+            this.getList()
         }
     }
 }
diff --git a/culture/src/views/deliveryAssessment/projectTeamIntegral/service.js b/culture/src/views/deliveryAssessment/projectTeamIntegral/service.js
new file mode 100644
index 0000000..0d13bca
--- /dev/null
+++ b/culture/src/views/deliveryAssessment/projectTeamIntegral/service.js
@@ -0,0 +1,11 @@
+import axios from '@/utils/request';
+
+// 列表
+export const getListData = (data) => {
+    return axios.post('/api/t-strain-report/pageListProject', { ...data })
+}
+
+// 详情
+export const getDetailData = (id) => {
+    return axios.get(`/open/t-strain-report/getDetailByIdProject?id=${id}`)
+}
\ No newline at end of file
diff --git a/culture/src/views/projectList/addProject.vue b/culture/src/views/projectList/addProject.vue
index 5bfdd34..9c2e21d 100644
--- a/culture/src/views/projectList/addProject.vue
+++ b/culture/src/views/projectList/addProject.vue
@@ -2,11 +2,11 @@
     <Card>
         <template>
             <el-form ref="form" :model="form" :rules="rules" inline label-position="top">
-                <el-form-item prop="name" label="项目组名称">
-                    <el-input v-model="form.name" placeholder="请输入" />
+                <el-form-item prop="teamName" label="项目组名称">
+                    <el-input v-model="form.teamName" placeholder="请输入" />
                 </el-form-item>
-                <el-form-item prop="description" label="项目负责人">
-                    <el-input v-model="form.description" placeholder="请输入" />
+                <el-form-item prop="personCharge" label="项目负责人">
+                    <el-input v-model="form.personCharge" placeholder="请输入" />
                 </el-form-item>
             </el-form>
             <div class="header-title">
@@ -17,41 +17,73 @@
                 <el-button class="el-icon-plus" type="primary" @click="addMember"> 添加项目组成员</el-button>
             </div>
             <div class="member-list">
-                <div v-for="(item,index) in ['审批人', '菌种工程师', '菌种实验员']" :key="item" class="member-list-card">
+                <div v-for="item in 3" :key="item" class="member-list-card">
                     <div class="member-item">
-                        <div class="member-title">{{ item }}</div>
-                        <div :class="index == 0 || index == 1 ? 'member-name-box' : 'member-name-box-2'">
-                            <div v-for="i in memberList(index+1)" :key="i" class="member-name">张三</div>
+                        <div class="member-title">{{ ['菌种审批人', '菌种工程师', '菌种实验员'][item - 1] }}</div>
+                        <div :class="item == 1 || item == 2 ? 'member-name-box' : 'member-name-box-2'">
+                            <el-tooltip v-for="i in memberList(item)" :key="i.userId" class="member-name" effect="dark"
+                                :content="i.nickName" placement="top">
+                                <span>{{ i.nickName }}</span>
+                            </el-tooltip>
                         </div>
-                        <div class="member-edit">修改</div>
+                        <div class="member-edit" v-if="memberList(item).length != 0" @click="editUserList">修改</div>
                     </div>
                 </div>
             </div>
             <div class="add-project-footer">
-                <el-button type="primary">保存</el-button>
+                <el-button @click="submitForm" type="primary">保存</el-button>
             </div>
         </template>
-        <SelectMember ref="selectMember" />
+        <SelectMember ref="selectMember" @submit="selectUser" />
     </Card>
 </template>
 
 <script>
+import { addProject } from './service'
 export default {
     name: 'AddProject',
     data() {
         return {
             form: {},
             rules: {
-                name: [{ required: true, message: '请输入项目组名称', trigger: 'blur' }],
-                description: [{ required: true, message: '请输入项目组描述', trigger: 'blur' }]
-            }
+                teamName: [{ required: true, message: '请输入项目组名称', trigger: 'blur' }],
+                personCharge: [{ required: true, message: '请输入项目组描述', trigger: 'blur' }]
+            },
+            selectMemberData: [],
+            // 角色配置常量
+            ROLE_CONFIG: {
+                1: { key: 'approver', limit: 1, label: '菌种审批人' },
+                2: { key: 'engineer', limit: 1, label: '菌种工程师' },
+            },
         }
     },
     methods: {
         submitForm() {
             this.$refs.form.validate((valid) => {
                 if (valid) {
-                    console.log('submit!')
+                    if (this.selectMemberData.length == 0) {
+                        this.$message.error('请选择项目组成员')
+                        return
+                    }
+                    const ROLE_NAME_TO_TYPE = {
+                        '菌种审批人': 1,
+                        '菌种工程师': 2,
+                        '菌种实验员': 3,
+                    };
+                    const data = {
+                        teamName: this.form.teamName,
+                        personCharge: this.form.personCharge,
+                        staffs: this.selectMemberData.map(member => ({
+                            userId: member.userId,
+                            roleType: ROLE_NAME_TO_TYPE[member.roleName]
+                        }))
+                    }
+                    addProject(data).then(res => {
+                        if (res.code == 200) {
+                            this.$message.success('添加成功')
+                            this.$router.push({ name: 'ProjectList' })
+                        }
+                    })
                 }
             })
         },
@@ -61,16 +93,31 @@
         memberList(i) {
             switch (i) {
                 case 1:
-                    return [1]
+                    return this.selectMemberData.filter(item => item.roleName == '菌种审批人')
                 case 2:
-                    return [1]
+                    return this.selectMemberData.filter(item => item.roleName == '菌种工程师')
                 case 3:
-                    return [1, 2, 3, 4, 5, 6, 7, 8]
-                case 4:
-                    return [1, 2, 3, 4, 5, 6, 7, 8]
+                    return this.selectMemberData.filter(item => item.roleName == '菌种实验员')
                 default:
                     break;
             }
+        },
+        selectUser(data) {
+            for (const [roleId, config] of Object.entries(this.ROLE_CONFIG)) {
+                const members = data.filter(item => item.roleName === config.label);
+                if (members.length > config.limit) {
+                    this.$message.error(`${config.label}最多只能选择${config.limit}个`);
+                    return
+                }
+            }
+            this.selectMemberData = data;
+            this.$refs.selectMember.close();
+        },
+        editUserList() {
+            this.$refs.selectMember.open();
+            this.$nextTick(() => {
+                this.$refs.selectMember.setSelection(this.selectMemberData);
+            });
         }
     }
 }
@@ -188,6 +235,10 @@
                 font-weight: 500;
                 font-size: 16px;
                 color: #FFFFFF;
+                overflow: hidden;
+                text-overflow: ellipsis;
+                white-space: nowrap;
+                box-sizing: border-box;
             }
 
             .member-edit {
diff --git a/culture/src/views/projectList/detailProject.vue b/culture/src/views/projectList/detailProject.vue
new file mode 100644
index 0000000..bb0b3c1
--- /dev/null
+++ b/culture/src/views/projectList/detailProject.vue
@@ -0,0 +1,233 @@
+<template>
+    <Card>
+        <template>
+            <el-form disabled ref="form" :model="form" :rules="rules" inline label-position="top">
+                <el-form-item prop="teamName" label="项目组名称">
+                    <el-input v-model="form.teamName" placeholder="请输入" />
+                </el-form-item>
+                <el-form-item prop="personCharge" label="项目组负责人">
+                    <el-input v-model="form.personCharge" placeholder="请输入" />
+                </el-form-item>
+            </el-form>
+            <div class="header-title">
+                <div class="header-title-left">
+                    <img src="@/assets/public/headercard.png" />
+                    <div>项目组成员</div>
+                </div>
+            </div>
+            <div class="member-list">
+                <div v-for="item in 3" :key="item" class="member-list-card">
+                    <div class="member-item">
+                        <div class="member-title">{{ ['菌种审批人', '菌种工程师', '菌种实验员'][item - 1] }}</div>
+                        <div :class="item == 1 || item == 2 ? 'member-name-box' : 'member-name-box-2'">
+                            <el-tooltip v-for="i in memberList(item)" :key="i.userId" class="member-name" effect="dark"
+                                :content="i.nickName" placement="top">
+                                <span>{{ i.nickName }}</span>
+                            </el-tooltip>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </template>
+        <SelectMember ref="selectMember" @submit="selectUser" />
+    </Card>
+</template>
+
+<script>
+import { getProjectDetail } from './service'
+export default {
+    name: 'EddProject',
+    data() {
+        return {
+            form: {},
+            rules: {
+                teamName: [{ required: true, message: '请输入项目组名称', trigger: 'blur' }],
+                personCharge: [{ required: true, message: '请输入项目组描述', trigger: 'blur' }]
+            },
+            selectMemberData: [],
+            ROLE_NAME_TO_TYPE: {
+                '菌种审批人': 1,
+                '菌种工程师': 2,
+                '菌种实验员': 3,
+            }
+        }
+    },
+    created() {
+        getProjectDetail({ id: this.$route.query.id }).then(res => {
+            this.form = {
+                teamName: res.teamName,
+                personCharge: res.personCharge
+            }
+            this.selectMemberData = res.staffs.map(item => ({
+                userId: Number(item.userId),
+                roleName: ['菌种审批人', '菌种工程师', '菌种实验员'][item.roleType - 1],
+                nickName: item.nickName
+            }))
+        })
+    },
+    methods: {
+        addMember() {
+            this.$refs.selectMember.open()
+        },
+        memberList(i) {
+            switch (i) {
+                case 1:
+                    return this.selectMemberData.filter(item => item.roleName == '菌种审批人')
+                case 2:
+                    return this.selectMemberData.filter(item => item.roleName == '菌种工程师')
+                case 3:
+                    return this.selectMemberData.filter(item => item.roleName == '菌种实验员')
+                default:
+                    break;
+            }
+        },
+    }
+}
+</script>
+
+<style scoped lang="less">
+.el-form--inline .el-form-item {
+    margin-right: 83px;
+}
+
+.header-title {
+    display: flex;
+    align-items: center;
+    flex-wrap: wrap;
+    gap: 13px;
+
+    .header-title-left {
+        display: flex;
+        align-items: center;
+        gap: 13px;
+
+        img {
+            width: 12px;
+            height: 19px;
+        }
+
+        div {
+            flex-shrink: 0;
+            font-weight: bold;
+            font-size: 18px;
+            color: #222222;
+            line-height: 27px;
+            font-family: 'Source Han Sans CN Bold Bold';
+
+            &:before {
+                content: '*';
+                color: #F56C6C;
+                margin-right: 4px;
+            }
+        }
+    }
+}
+
+.member-list {
+    margin-top: 18px;
+    display: flex;
+    flex-wrap: wrap;
+    gap: 28px;
+
+    .member-list-card {
+        position: relative;
+        width: 340px;
+        height: 400px;
+        border-radius: 8px;
+        border: 1px solid #DCDFE6;
+
+        &:nth-child(1) {
+            background: linear-gradient(to bottom, rgba(4, 156, 154, 0.2) 0%, rgba(5, 242, 194, 0) 70%);
+        }
+
+        &:nth-child(2) {
+            background: linear-gradient(to bottom, rgba(5, 160, 193, 0.2) 0%, rgba(5, 242, 194, 0) 70%);
+        }
+
+        &:nth-child(3) {
+            background: linear-gradient(to bottom, rgba(255, 77, 79, 0.20) 0%, rgba(255, 242, 194, 0) 70%);
+        }
+
+        &:nth-child(4) {
+            background: linear-gradient(to bottom, rgba(250, 199, 20, 0.21) 0%, rgba(255, 242, 194, 0) 70%);
+        }
+
+        .member-item {
+            height: 100%;
+            display: flex;
+            flex-direction: column;
+
+            .member-title {
+                margin-top: 20px;
+                width: 100%;
+                font-family: 'Source Han Sans CN Bold Bold';
+                font-weight: bold;
+                font-size: 16px;
+                color: rgba(0, 0, 0, 0.8);
+                line-height: 16px;
+                text-align: center;
+            }
+
+            .member-name-box {
+                flex: 1;
+                display: flex;
+                align-items: center;
+                justify-content: center;
+
+            }
+
+            .member-name-box-2 {
+                padding: 0 20px;
+                padding-top: 40px;
+                display: grid;
+                grid-template-columns: repeat(4, 1fr);
+                align-items: flex-start;
+                flex-wrap: wrap;
+                gap: 20px;
+                justify-content: center;
+            }
+
+            .member-name {
+                width: 60px;
+                height: 60px;
+                background: #7D8B79;
+                border-radius: 50%;
+                text-align: center;
+                line-height: 60px;
+                font-weight: 500;
+                font-size: 16px;
+                color: #FFFFFF;
+                overflow: hidden;
+                text-overflow: ellipsis;
+                white-space: nowrap;
+                box-sizing: border-box;
+            }
+
+            .member-edit {
+                cursor: pointer;
+                position: absolute;
+                bottom: 10px;
+                left: 50%;
+                transform: translateX(-50%);
+                font-weight: 400;
+                font-size: 12px;
+                color: #FF4D4F;
+                line-height: 22px;
+                width: 40px;
+                background: #FFF1F0;
+                border-radius: 4px;
+                border: 1px solid #FFCCC7;
+                text-align: center;
+            }
+        }
+    }
+}
+
+.add-project-footer {
+    margin-top: 43px;
+
+    button {
+        width: 220px;
+    }
+}
+</style>
\ No newline at end of file
diff --git a/culture/src/views/projectList/editProject.vue b/culture/src/views/projectList/editProject.vue
new file mode 100644
index 0000000..1ac2bd5
--- /dev/null
+++ b/culture/src/views/projectList/editProject.vue
@@ -0,0 +1,285 @@
+<template>
+    <Card>
+        <template>
+            <el-form ref="form" :model="form" :rules="rules" inline label-position="top">
+                <el-form-item prop="teamName" label="项目组名称">
+                    <el-input v-model="form.teamName" placeholder="请输入" />
+                </el-form-item>
+                <el-form-item prop="personCharge" label="项目组负责人">
+                    <el-input v-model="form.personCharge" placeholder="请输入" />
+                </el-form-item>
+            </el-form>
+            <div class="header-title">
+                <div class="header-title-left">
+                    <img src="@/assets/public/headercard.png" />
+                    <div>项目组成员</div>
+                </div>
+                <el-button class="el-icon-plus" type="primary" @click="addMember"> 添加项目组成员</el-button>
+            </div>
+            <div class="member-list">
+                <div v-for="item in 3" :key="item" class="member-list-card">
+                    <div class="member-item">
+                        <div class="member-title">{{ ['菌种审批人', '菌种工程师', '菌种实验员'][item - 1] }}</div>
+                        <div :class="item == 1 || item == 2 ? 'member-name-box' : 'member-name-box-2'">
+                            <el-tooltip v-for="i in memberList(item)" :key="i.userId" class="member-name" effect="dark"
+                                :content="i.nickName" placement="top">
+                                <span>{{ i.nickName }}</span>
+                            </el-tooltip>
+                        </div>
+                        <div class="member-edit" v-if="memberList(item).length != 0" @click="editUserList">修改</div>
+                    </div>
+                </div>
+            </div>
+            <div class="add-project-footer">
+                <el-button @click="submitForm" type="primary">保存</el-button>
+            </div>
+        </template>
+        <SelectMember ref="selectMember" @submit="selectUser" />
+    </Card>
+</template>
+
+<script>
+import { getProjectDetail, editProject } from './service'
+export default {
+    name: 'EddProject',
+    data() {
+        return {
+            form: {},
+            rules: {
+                teamName: [{ required: true, message: '请输入项目组名称', trigger: 'blur' }],
+                personCharge: [{ required: true, message: '请输入项目组描述', trigger: 'blur' }]
+            },
+            selectMemberData: [],
+            // 角色配置常量
+            ROLE_CONFIG: {
+                1: { key: 'approver', limit: 1, label: '菌种审批人' },
+                2: { key: 'engineer', limit: 1, label: '菌种工程师' },
+            },
+            ROLE_NAME_TO_TYPE: {
+                '菌种审批人': 1,
+                '菌种工程师': 2,
+                '菌种实验员': 3,
+            }
+        }
+    },
+    created() {
+        getProjectDetail({ id: this.$route.query.id }).then(res => {
+            this.form = {
+                teamName: res.teamName,
+                personCharge: res.personCharge
+            }
+            this.selectMemberData = res.staffs.map(item => ({
+                userId: Number(item.userId),
+                roleName: ['菌种审批人', '菌种工程师', '菌种实验员'][item.roleType - 1],
+                nickName: item.nickName
+            }))
+        })
+    },
+    methods: {
+        submitForm() {
+            this.$refs.form.validate((valid) => {
+                if (valid) {
+                    if (this.selectMemberData.length == 0) {
+                        this.$message.error('请选择项目组成员')
+                        return
+                    }
+                    const data = {
+                        id: this.$route.query.id,
+                        teamName: this.form.teamName,
+                        personCharge: this.form.personCharge,
+                        staffs: this.selectMemberData.map(member => ({
+                            userId: member.userId,
+                            roleType: this.ROLE_NAME_TO_TYPE[member.roleName]
+                        }))
+                    }
+                    editProject(data).then(res => {
+                        if (res.code == 200) {
+                            this.$message.success('添加成功')
+                            this.$router.push({ name: 'ProjectList' })
+                        }
+                    })
+                }
+            })
+        },
+        addMember() {
+            this.$refs.selectMember.open()
+        },
+        memberList(i) {
+            switch (i) {
+                case 1:
+                    return this.selectMemberData.filter(item => item.roleName == '菌种审批人')
+                case 2:
+                    return this.selectMemberData.filter(item => item.roleName == '菌种工程师')
+                case 3:
+                    return this.selectMemberData.filter(item => item.roleName == '菌种实验员')
+                default:
+                    break;
+            }
+        },
+        selectUser(data) {
+            for (const [roleId, config] of Object.entries(this.ROLE_CONFIG)) {
+                const members = data.filter(item => item.roleName === config.label);
+                if (members.length > config.limit) {
+                    this.$message.error(`${config.label}最多只能选择${config.limit}个`);
+                    return
+                }
+            }
+            this.selectMemberData = data;
+            this.$refs.selectMember.close();
+        },
+        editUserList() {
+            this.$refs.selectMember.open();
+            this.$nextTick(() => {
+                this.$refs.selectMember.setSelection(this.selectMemberData);
+            });
+        }
+    }
+}
+</script>
+
+<style scoped lang="less">
+.el-form--inline .el-form-item {
+    margin-right: 83px;
+}
+
+.header-title {
+    display: flex;
+    align-items: center;
+    flex-wrap: wrap;
+    gap: 13px;
+
+    .header-title-left {
+        display: flex;
+        align-items: center;
+        gap: 13px;
+
+        img {
+            width: 12px;
+            height: 19px;
+        }
+
+        div {
+            flex-shrink: 0;
+            font-weight: bold;
+            font-size: 18px;
+            color: #222222;
+            line-height: 27px;
+            font-family: 'Source Han Sans CN Bold Bold';
+
+            &:before {
+                content: '*';
+                color: #F56C6C;
+                margin-right: 4px;
+            }
+        }
+    }
+}
+
+.member-list {
+    margin-top: 18px;
+    display: flex;
+    flex-wrap: wrap;
+    gap: 28px;
+
+    .member-list-card {
+        position: relative;
+        width: 340px;
+        height: 400px;
+        border-radius: 8px;
+        border: 1px solid #DCDFE6;
+
+        &:nth-child(1) {
+            background: linear-gradient(to bottom, rgba(4, 156, 154, 0.2) 0%, rgba(5, 242, 194, 0) 70%);
+        }
+
+        &:nth-child(2) {
+            background: linear-gradient(to bottom, rgba(5, 160, 193, 0.2) 0%, rgba(5, 242, 194, 0) 70%);
+        }
+
+        &:nth-child(3) {
+            background: linear-gradient(to bottom, rgba(255, 77, 79, 0.20) 0%, rgba(255, 242, 194, 0) 70%);
+        }
+
+        &:nth-child(4) {
+            background: linear-gradient(to bottom, rgba(250, 199, 20, 0.21) 0%, rgba(255, 242, 194, 0) 70%);
+        }
+
+        .member-item {
+            height: 100%;
+            display: flex;
+            flex-direction: column;
+
+            .member-title {
+                margin-top: 20px;
+                width: 100%;
+                font-family: 'Source Han Sans CN Bold Bold';
+                font-weight: bold;
+                font-size: 16px;
+                color: rgba(0, 0, 0, 0.8);
+                line-height: 16px;
+                text-align: center;
+            }
+
+            .member-name-box {
+                flex: 1;
+                display: flex;
+                align-items: center;
+                justify-content: center;
+
+            }
+
+            .member-name-box-2 {
+                padding: 0 20px;
+                padding-top: 40px;
+                display: grid;
+                grid-template-columns: repeat(4, 1fr);
+                align-items: flex-start;
+                flex-wrap: wrap;
+                gap: 20px;
+                justify-content: center;
+            }
+
+            .member-name {
+                width: 60px;
+                height: 60px;
+                background: #7D8B79;
+                border-radius: 50%;
+                text-align: center;
+                line-height: 60px;
+                font-weight: 500;
+                font-size: 16px;
+                color: #FFFFFF;
+                overflow: hidden;
+                text-overflow: ellipsis;
+                white-space: nowrap;
+                box-sizing: border-box;
+            }
+
+            .member-edit {
+                cursor: pointer;
+                position: absolute;
+                bottom: 10px;
+                left: 50%;
+                transform: translateX(-50%);
+                font-weight: 400;
+                font-size: 12px;
+                color: #FF4D4F;
+                line-height: 22px;
+                width: 40px;
+                background: #FFF1F0;
+                border-radius: 4px;
+                border: 1px solid #FFCCC7;
+                text-align: center;
+            }
+        }
+    }
+}
+
+.add-project-footer {
+    margin-top: 43px;
+
+    button {
+        width: 220px;
+    }
+}
+</style>
\ No newline at end of file
diff --git a/culture/src/views/projectList/service.js b/culture/src/views/projectList/service.js
index 2ee56f9..427d2d1 100644
--- a/culture/src/views/projectList/service.js
+++ b/culture/src/views/projectList/service.js
@@ -2,30 +2,30 @@
 
 // 列表
 export const getProjectList = (data) => {
-    return axios.post('/t_project_team/api/pageList', { ...data })
+    return axios.post('/api/t_project_team/pageList', { ...data })
 }
 
 // 新增
 export const addProject = (data) => {
-    return axios.post('/t_project_team/api/add', { ...data })
+    return axios.post('/api/t_project_team/add', { ...data })
 }
 
 // 编辑
 export const editProject = (data) => {
-    return axios.post('/t_project_team/api/update', { ...data })
+    return axios.post('/api/t_project_team/update', { ...data })
 }
 
 // 详情
 export const getProjectDetail = (data) => {
-    return axios.get(`/t_project_team/open/getDetailById?id=${data.id}`)
+    return axios.get(`/open/t_project_team/getDetailById?id=${data.id}`)
 }
 
 // 修改项目组状态
 export const changeStatus = (data) => {
-    return axios.post('/t_project_team/api/upAndDown', { ...data })
+    return axios.post('/api/t_project_team/upAndDown', { ...data })
 }
 
 // 删除项目组
 export const deleteProject = (data) => {
-    return axios.delete(`/t_project_team/open/deleteById?id=${data.id}`)
+    return axios.delete(`/open/t_project_team/deleteById?id=${data.id}`)
 }
diff --git a/culture/src/views/system/user/components/add-edit.vue b/culture/src/views/system/user/components/add-edit.vue
index d9d53a2..eb57919 100644
--- a/culture/src/views/system/user/components/add-edit.vue
+++ b/culture/src/views/system/user/components/add-edit.vue
@@ -20,7 +20,7 @@
               :value="item.roleId"></el-option>
           </el-select>
         </el-form-item>
-        <el-form-item label="登录状态" prop="status">
+        <el-form-item label="启动状态" prop="status">
           <el-switch v-model="form.status"></el-switch>
         </el-form-item>
         <el-form-item label="备注" prop="remark">
@@ -56,33 +56,51 @@
     },
   },
   data() {
+    var validatePhone = (rule, value, callback) => {
+      if (!value) {
+        // The 'required' rule will handle empty value, so we can make this optional here
+        // or keep it for a more specific message if needed.
+        // For now, let's assume 'required' handles the empty case.
+        callback();
+        return;
+      }
+      const phoneRegex = new RegExp(/^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/,'g'); // Regex for 11-digit Chinese mobile numbers
+      if (!phoneRegex.test(value)) {
+        callback(new Error('请输入有效的11位手机号码'));
+      } else {
+        callback();
+      }
+    };
     return {
       form: { status: true },
       userDeptId: '',
       rules: {
         nickName: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
-        phonenumber: [{ required: true, message: '请输入联系电话', trigger: 'blur' }],
-        roleId: [{ required: true, message: '请选择角色', trigger: 'blur' }],
+        phonenumber: [
+          { required: true, message: '请输入联系电话', trigger: 'blur' },
+          { validator: validatePhone, trigger: 'blur' }
+        ],
+        roleId: [{ required: true, message: '请选择角色', trigger: 'change' }],
         userName: [{ required: true, message: '请输入登陆账号', trigger: 'blur' }],
         status: [{ required: true, message: '请选择启动状态', trigger: 'blur' }],
       },
     }
   },
   created() {
-    this.form = { status: true }
-
-    if (Object.keys(this.row).length) {
+    if (this.row && this.row.userId) {
       this.form = {
-        userId: this.row.userId,
-        nickName: this.row.nickName,
-        phonenumber: this.row.phonenumber,
-        roleId: this.row.roleId,
-        userName: this.row.userName,
-        remark: this.row.remark,
+        ...this.row,
         status: this.row.status == 0 ? true : false,
       }
     } else {
-      this.form = {}
+      this.form = {
+        nickName: '',
+        phonenumber: '',
+        userName: '',
+        roleId: '',
+        status: true,
+        remark: '',
+      }
     }
   },
   mounted() { },
diff --git a/culture/src/views/system/user/components/reset-password.vue b/culture/src/views/system/user/components/reset-password.vue
index d3695d3..b5b1260 100644
--- a/culture/src/views/system/user/components/reset-password.vue
+++ b/culture/src/views/system/user/components/reset-password.vue
@@ -3,16 +3,16 @@
     <el-dialog :visible.sync="dialogVisible" @close="$emit('close')" title="重置密码" width="30%">
       <el-form ref="form" :model="form" :rules="rules" label-width="80px">
         <el-form-item label="姓名" prop="nickName">
-          <el-input :disabled="true" v-model="form.nickName" placeholder="请输入" style="width: 50%;"></el-input>
+          <el-input :disabled="true" v-model="form.nickName" placeholder="请输入" style="width: 95%;"></el-input>
         </el-form-item>
         <el-form-item label="登陆账号" prop="account">
-          <el-input :disabled="true" v-model="form.account" placeholder="请输入" style="width: 50%;"></el-input>
+          <el-input :disabled="true" v-model="form.account" placeholder="请输入" style="width: 95%;"></el-input>
         </el-form-item>
         <el-form-item label="新密码" prop="password">
-          <el-input v-model="form.password" placeholder="请输入" style="width: 50%;"></el-input>
+          <el-input v-model="form.password" type="password" placeholder="请输入" style="width: 95%;"></el-input>
         </el-form-item>
         <el-form-item label="确认密码" prop="confirmPassword">
-          <el-input v-model="form.confirmPassword" placeholder="请输入" style="width: 50%;"></el-input>
+          <el-input v-model="form.confirmPassword" type="password" placeholder="请输入" style="width: 95%;"></el-input>
         </el-form-item>
       </el-form>
       <div class="select-member-footer">
diff --git a/culture/src/views/system/user/index.vue b/culture/src/views/system/user/index.vue
index 2a06bf3..49fabfd 100644
--- a/culture/src/views/system/user/index.vue
+++ b/culture/src/views/system/user/index.vue
@@ -1,7 +1,7 @@
 <template>
   <div class="list">
     <TableCustom :queryForm="pagination" :tableData="data" :total="pagination.total"
-      @currentChange="handleCurrentChange" @sizeChange="handleSizeChange">
+      @handleCurrentChange="handleCurrentChange" @handleSizeChange="handleSizeChange">
       <template #search>
         <el-form label-width="100px" inline>
           <el-form-item label="人员搜索">
@@ -24,7 +24,7 @@
           </el-form-item>
           <el-form-item style="margin-left: 63px;">
             <el-button @click="reset">重置</el-button>
-            <el-button type="primary" @click="onSubmit">查询</el-button>
+            <el-button type="primary" @click="onSubmit" style="margin-left: 10px;">查询</el-button>
           </el-form-item>
         </el-form>
       </template>
@@ -45,10 +45,6 @@
             <div class="status_class">
               <div :class="row.status == 0 ? 'green' : 'red'"></div>
               <div>{{ row.status == 0 ? '正常' : '禁用' }}</div>
-              <div v-if="row.status == 1" style="cursor: pointer"
-                @click="; (dialogVisibleView = true), (rowView = row), $forceUpdate()">
-                <i class="el-icon-warning"></i>
-              </div>
             </div>
           </template>
         </el-table-column>
@@ -56,28 +52,26 @@
         <el-table-column label="操作" width="300">
           <template slot-scope="{ row }">
             <div>
-              <el-button type="text" @click="edit(row)">编辑</el-button>
-              <el-button type="text" @click="edit(row)">账号继承</el-button>
-              <el-button v-if="row.status != 0" type="text" @click="updateStatus(row, true)">
+              <el-button type="text" @click="edit(row)" class="action-button">编辑</el-button>
+              <el-button type="text" @click="inherit(row)" class="action-button">账号继承</el-button>
+              <el-button v-if="row.status != 0" type="text" @click="updateStatus(row, true)" class="action-button">
                 启用
               </el-button>
-              <el-button v-if="row.status == 0" type="text" @click="updateStatus(row, false)">
+              <el-button v-if="row.status == 0" type="text" @click="updateStatus(row, false)" class="action-button">
                 禁用
               </el-button>
-              <el-button type="text" @click="detail(row)">重置密码</el-button>
-              <el-button type="text" @click="del(row)">删除</el-button>
+              <el-button type="text" @click="detail(row)" class="action-button">重置密码</el-button>
+              <el-button type="text" @click="del(row)" class="action-button">删除</el-button>
             </div>
           </template>
         </el-table-column>
       </template>
     </TableCustom>
 
-    <AddEdit v-if="dialogVisible" :row="row" :deptList="deptList" :deptType="deptTypeList" :roleList="roleList"
+    <AddEdit v-if="dialogVisible" :row="row" :deptType="deptTypeList" :roleList="roleList"
       :dialogVisible="dialogVisible" @close="dialogVisible = false, row = {}" @confirm="confirm" />
     <ResetPassword v-if="passwordVisible" :row="row" :dialogVisible="passwordVisible"
       @close="passwordVisible = false, row = {}" @confirm="passwordConfirm" />
-    <ViewData v-if="dialogVisibleView" :row="rowView" :dialogVisible="dialogVisibleView"
-      @close="dialogVisibleView = false, rowView = {}" />
     <Disb v-if="disbDialogVisible" :row="disbRow" :dialogVisible="disbDialogVisible"
       @close="disbDialogVisible = false, disbRow = {}" @confirm="disbConfirm" />
     <ShowDelConfirm :show="delShow" @close="delShow = false" @confirm="delConfirm" title="确认要删除该人员吗?"
@@ -90,7 +84,6 @@
 <script>
 import { getList, add, edit, delDept, roleList, updatePwd, changeStatus, typeList } from './service'
 import AddEdit from './components/add-edit.vue'
-import ViewData from './components/view-data.vue'
 import Disb from './components/disb.vue'
 import ResetPassword from './components/reset-password.vue'
 import Inherit from './components/inherit.vue'
@@ -98,7 +91,6 @@
   name: 'User',
   components: {
     AddEdit,
-    ViewData,
     Disb,
     ResetPassword,
     Inherit,
@@ -113,7 +105,6 @@
       inheritDialogVisible: false,//账号继承
       data: [],//列表数据
       nickNameOrPhone: '',//人员搜索
-      deptId: [],//部门
       roleId: [],//角色
       status: '',//状态
       roleList: [],//角色列表
@@ -137,9 +128,8 @@
   },
   watch: {},
   created() {
-    // this.getRoleList()
-    // this.getListData()
-    // this.getTypeList()
+    this.getRoleList()
+    this.getListData()
   },
   mounted() { },
   methods: {
@@ -150,7 +140,7 @@
     },
     getRoleList() {
       roleList().then((res) => {
-        this.roleList = res.data.data
+        this.roleList = res
       })
     },
     delConfirm() {
@@ -201,6 +191,10 @@
       this.row = row
       this.dialogVisible = true
     },
+    inherit(row) {
+      this.inheritRow = row
+      this.inheritDialogVisible = true
+    },
     updateStatus(row, type) {
       if (type) {
         changeStatus({ ...row, status: 0 }).then(() => {
@@ -220,18 +214,14 @@
     },
     async getListData() {
       let obj = {
-        ...this.pagination,
+        pageNum: this.pagination.pageNum,
+        pageSize: this.pagination.pageSize,
         nickNameOrPhone: this.nickNameOrPhone,
-        deptIds: this.deptId,
         roleIds: this.roleId,
         status: this.status,
       }
       this.listLoading = true
-      const {
-        data: {
-          data: { records, total },
-        },
-      } = await getList(obj)
+      const { records,total } = await getList(obj)
       this.data = records
       this.pagination.total = total
       this.timeOutID = setTimeout(() => {
@@ -241,7 +231,6 @@
     reset() {
       this.nickNameOrPhone = ''
       this.roleId = []
-      this.deptId = []
       this.status = ''
       this.pagination.pageNum = 1
       this.getListData()
@@ -267,6 +256,10 @@
   height: 100%;
 }
 
+.action-button {
+  margin-right: 8px;
+}
+
 .green {
   background-color: green;
 }
diff --git a/culture/src/views/system/user/service.js b/culture/src/views/system/user/service.js
index 16ee333..2aa9696 100644
--- a/culture/src/views/system/user/service.js
+++ b/culture/src/views/system/user/service.js
@@ -36,6 +36,6 @@
 export const updatePwd = (data) => {
   return axios.post(`/system/user/resetPwd`, { ...data })
 }
-export const typeList = (data) => {
+export const typeList = () => {
   return axios.get(`/t-business-dept/list/type?type=1`,)
 }
\ No newline at end of file

--
Gitblit v1.7.1