Переглянути джерело

项目管理接口联调(部分);颜色修改;按钮权限添加;接口地址改为线上等

htc 3 днів тому
батько
коміт
f89605d7fa

+ 3 - 8
public/index.html

@@ -28,22 +28,17 @@
     window.SITE_CONFIG['dynamicRoutes'] = [];                // 动态路由列表
     window.SITE_CONFIG['dynamicMenuRoutes'] = [];            // 动态(菜单)路由列表
     window.SITE_CONFIG['dynamicMenuRoutesHasAdded'] = false; // 动态(菜单)路由是否已经添加的状态标示(用于判断是否需要重新拉取数据并进行动态添加操作)
-    window.SITE_CONFIG['scene'] = '跨境电商';
+    window.SITE_CONFIG['scene'] = '';
 
 
   </script>
   <!-- 开发环境 -->
   <% if (process.env.VUE_APP_NODE_ENV==='dev' ) { %>
     <script>
-
-      // window.SITE_CONFIG['apiURL'] = 'https://glt.ringzle.com:8033/witcarbon-admin';
-      window.SITE_CONFIG['apiURL'] = 'http://192.168.2.19:9011/chuangheng-admin';
+      window.SITE_CONFIG['apiURL'] = 'http://36.134.23.41:8843/chuangheng-admin';
+      // window.SITE_CONFIG['apiURL'] = 'http://192.168.2.19:9011/chuangheng-admin';
       window.SITE_CONFIG['apiURL1'] = 'http://gpu.ringzle.com:8082/iot';
-
-
       window.SITE_CONFIG['apiURL2'] = 'http://gpu.ringzle.com:8082/witcarbon-gica';
-
-
       // 李勇本机地址
       // WebSocket地址
       window.SITE_CONFIG['socketURL'] = 'ws://https://s.ringzle.com/witcarbon-admin/websocket';

+ 78 - 5
src/api/agent/index.js

@@ -1,8 +1,81 @@
 import request from '@/utils/request2'
 
 export function getContractList(query) {
-    return request({
-      url: 'core/chat/messages?query='+query,
-      method: 'get'
-    })
-  }
+  return request({
+    url: '/core/chat/messages?query='+query,
+    method: 'get'
+  })
+}
+
+// ---start 项目管理
+export function getCoachProgramList(query) {
+  return request({
+    url: '/core/project/listByCoach',
+    method: 'get',
+    params: query
+  })
+}
+export function addCoachProgram(data) {
+  return request({
+    url: '/core/project',
+    method: 'post',
+    data
+  })
+}
+export function updateCoachProgram(data) {
+  return request({
+    url: '/core/project',
+    method: 'put',
+    data
+  })
+}
+export function getCoachProgramInfo(query) {
+  return request({
+    url: `core/project/${query}`,
+    method: 'get'
+  })
+}
+export function deleteCoachProgram(query) {
+  return request({
+    url: `/core/project/deleteOneById/${query}`,
+    method: 'delete'
+  })
+}
+// ---end 项目管理
+
+// ---start 教练管理
+export function getCoachList(query) {
+  return request({
+    url: '/sys/user/page',
+    method: 'get',
+    params: query
+  })
+}
+export function addCoach(data) {
+  return request({
+    url: '/sys/user',
+    method: 'post',
+    data
+  })
+}
+export function updateCoach(data) {
+  return request({
+    url: '/sys/user',
+    method: 'put',
+    data
+  })
+}
+export function getCoachInfo(query) {
+  return request({
+    url: `/sys/user/${query}`,
+    method: 'get'
+  })
+}
+export function deleteCoach(data) {
+  return request({
+    url: '/sys/user',
+    method: 'delete',
+    data
+  })
+}
+// ---end 教练管理

+ 51 - 0
src/mixins/region-module.js

@@ -0,0 +1,51 @@
+import { ref, getCurrentInstance } from 'vue';
+
+export function useRegion(){
+    const { proxy } = getCurrentInstance();
+    const provinceOptions = ref([])
+    const cityOptions = ref([])
+    const areaOptions = ref([])
+    const provinceValue = ref([])
+    
+    const provincAreaDetailInfoList = val => {
+        proxy.$http.get('/sys/region/list', { params: { pid: val } }).then((res) => {
+            if (res.msg = 'success') {
+                provinceOptions.value = res.data.data || []
+            }
+        })
+    }
+    const cityAreaDetailInfoList = val => {
+        proxy.$http.get('/sys/region/list', { params: { pid: val } }).then((res) => {
+            if (res.msg = 'success') {
+                cityOptions.value = res.data.data || []
+            }
+        })
+    }
+    
+    const countyAreaDetailInfoList = val => {
+        proxy.$http.get('/sys/region/list', { params: { pid: val } }).then((res) => {
+            if (res.msg = 'success') {
+                areaOptions.value = res.data.data || []
+            }
+        })
+    }
+    
+    const regionChange = (val, type) => {
+        if (type == 'province') {
+            cityAreaDetailInfoList(val)
+        } else if (type == 'city') {
+            countyAreaDetailInfoList(val)
+        }
+    }
+
+    return {
+        provinceOptions,
+        cityOptions,
+        areaOptions,
+        provinceValue,
+        provincAreaDetailInfoList,
+        cityAreaDetailInfoList,
+        countyAreaDetailInfoList,
+        regionChange
+    }
+}

+ 25 - 0
src/store_v3/modules/agent.js

@@ -0,0 +1,25 @@
+import {defineStore} from "pinia";
+import {ref} from "vue";
+
+import { getCoachList } from '@/api/agent/index.js'
+
+export const useAgentStore = defineStore('agent', () => {
+    const coachList = ref([]);
+    const coachMap = ref(new Map());
+    const getCoachData = () => {
+        getCoachList({page:1,limit:-1}).then((res) => {
+            coachList.value = res.data.list;
+            const map = new Map();
+            coachList.value.forEach((supplier) => {
+                map.set(supplier.id, supplier);
+            });
+            coachMap.value = map;
+        });
+    };
+
+    return {
+        coachList,
+        coachMap,
+        getCoachData,
+    };
+})

+ 0 - 236
src/store_v3/modules/wms.js

@@ -1,236 +0,0 @@
-import { listWarehouseNoPage } from '@/api/wms/warehouse';
-import { listMerchantNoPage } from "@/api/wms/merchant";
-import { listItemCategory, treeSelectItemCategory } from "@/api/wms/itemCategory";
-import { listItemBrand } from "@/api/wms/itemBrand";
-import { listProject } from "@/api/wms/project";
-import { listCompany,listEmployee,listWork } from "@/api/wms/employee";
-import { listOrder,getOrderDetail } from "@/api/wms/product";
-import { listItemPage2 } from "@/api/wms/item";
-import { listItemSkuPage } from "@/api/wms/itemSku";
-import {defineStore} from "pinia";
-import {ref} from "vue";
-
-export const useWmsStore = defineStore('wms', () => {
-
-  // 仓库管理
-  const warehouseList = ref([]);
-  const warehouseMap = ref(new Map());
-  const getWarehouseList = () => {
-    listWarehouseNoPage({}).then((res) => {
-      warehouseList.value = res.data.list;
-      const map = new Map();
-      warehouseList.value.forEach((supplier) => {
-        map.set(supplier.id, supplier);
-      });
-      warehouseMap.value = map;
-    });
-  };
-
-  // 企业管理
-  const merchantList = ref([]);
-  const merchantMap = ref(new Map());
-  const getMerchantList = () => {
-    listMerchantNoPage({}).then((res) => {
-      merchantList.value = res.data.list;
-      const map = new Map();
-      merchantList.value.forEach((supplier) => {
-        map.set(supplier.id, supplier);
-      });
-      merchantMap.value = map;
-    });
-  }
-
-  // 产品分类管理
-  const itemCategoryList = ref([])
-  const itemCategoryTreeList = ref([])
-  const itemCategoryMap = ref(new Map())
-  const getItemCategoryList = () => {
-    return new Promise((resolve, reject) => {
-      listItemCategory({page:1,limit:-1}).then(res => {
-        itemCategoryList.value = res.data.list;
-        const map = new Map()
-        itemCategoryList.value.forEach(supplier => {
-          map.set(supplier.id, supplier)
-        })
-        itemCategoryMap.value = map
-        resolve()
-      }).catch(() => reject())
-    })
-  }
-
-  const getItemCategoryTreeList = async () => {
-    return new Promise((resolve, reject) => {
-      treeSelectItemCategory().then(res => {
-        itemCategoryTreeList.value = res.data
-        resolve(res.data)
-      }).catch(() => reject())
-    })
-  }
-
-  // 产品品牌管理
-  const itemBrandList = ref([])
-  const itemBrandMap = ref(new Map())
-  const getItemBrandList =  (queryParams) => {
-    return new Promise((resolve, reject) => {
-      listItemBrand(queryParams).then(res => {
-        itemBrandList.value = res.data.list
-        const map = new Map()
-        itemBrandList.value.forEach(supplier => {
-          map.set(supplier.id, {...supplier})
-        })
-        itemBrandMap.value = map
-        resolve()
-      }).catch(() => reject())
-    })
-  }
-
-  // 合同管理
-  const projectList = ref([])
-  const projectMap = ref(new Map())
-  const getProjectList =  (queryParams) => {
-    return new Promise((resolve, reject) => {
-      listProject(queryParams).then(res => {
-        projectList.value = res.data.list
-        const map = new Map()
-        projectList.value.forEach(supplier => {
-          map.set(supplier.id, {...supplier})
-        })
-        projectMap.value = map
-        resolve()
-      }).catch(() => reject())
-    })
-  }
-  
-  // 外包公司管理
-  const companyList = ref([]);
-  const companyMap = ref(new Map());
-  const getCompanyList = () => {
-    listCompany({page:1,limit:-1}).then((res) => {
-      companyList.value = res.data.list;
-      const map = new Map();
-      companyList.value.forEach((supplier) => {
-        map.set(supplier.id, supplier);
-      });
-      companyMap.value = map;
-    });
-  }
-
-  // 员工管理
-  const employeeList = ref([]);
-  const employeeMap = ref(new Map());
-  const getEmployeeList = () => {
-    listEmployee({page:1,limit:-1}).then((res) => {
-      employeeList.value = res.data.list;
-      const map = new Map();
-      employeeList.value.forEach((supplier) => {
-        map.set(supplier.id, supplier);
-      });
-      employeeMap.value = map;
-    });
-  }
-
-  // 生产订单
-  const orderList = ref([]);
-  const orderMap = ref(new Map());
-  const getOrderList = () => {
-    listOrder({page:1,limit:-1}).then((res) => {
-      orderList.value = res.data.list;
-      const map = new Map();
-      orderList.value.forEach((supplier) => {
-        map.set(supplier.id, supplier);
-      });
-      orderMap.value = map;
-    });
-  }
-
-  // 生产订单产品
-  const skuList = ref([]);
-  const skuMap = ref(new Map());
-  const getSkuList = (orderId) => {
-    getOrderDetail(orderId).then((res) => {
-      skuList.value = res.data;
-      const map = new Map();
-      skuList.value.forEach((supplier) => {
-        map.set(supplier.id, supplier);
-      });
-      skuMap.value = map;
-    });
-  }
-  
-  // 产品管理产品(成品)
-  const productList = ref([]);
-  const productMap = ref(new Map());
-  const getProductList = () => {
-    listItemSkuPage({page:1,limit:-1,categoryType:1}).then((res) => {
-      productList.value = res.data.list;
-      const map = new Map();
-      productList.value.forEach((supplier) => {
-        map.set(supplier.id, supplier);
-      });
-      productMap.value = map;
-    });
-  }
-
-  // 外包人员工种
-  const employeeWorkList = ref([]);
-  const employeeWorkMap = ref(new Map());
-  const getEmployeeWorkList = () => {
-    listWork({page:1,limit:-1}).then((res) => {
-      employeeWorkList.value = res.data.list;
-      const map = new Map();
-      employeeWorkList.value.forEach((supplier) => {
-        map.set(supplier.id, supplier);
-      });
-      employeeWorkMap.value = map;
-    });
-  }
-
-  return {
-    // 仓库管理
-    warehouseList,
-    warehouseMap,
-    getWarehouseList,
-    // 企业管理
-    merchantList,
-    merchantMap,
-    getMerchantList,
-    // 产品分类管理
-    itemCategoryList,
-    itemCategoryTreeList,
-    itemCategoryMap,
-    getItemCategoryList,
-    getItemCategoryTreeList,
-    // 产品品牌管理
-    itemBrandList,
-    itemBrandMap,
-    getItemBrandList,
-    // 合同管理
-    projectList,
-    projectMap,
-    getProjectList,
-    // 外包公司
-    companyList,
-    companyMap,
-    getCompanyList,
-    // 员工管理
-    employeeList,
-    employeeMap,
-    getEmployeeList,
-    // 生产订单
-    orderList,
-    orderMap,
-    getOrderList,
-    //生产订单产品sku
-    skuList,
-    skuMap,
-    getSkuList,
-    //产品管理中产品
-    productList,
-    productMap,
-    getProductList,
-    // 外包人员工种
-    employeeWorkList,
-    employeeWorkMap,
-    getEmployeeWorkList,
-  };
-});

+ 1 - 1
src/views/main-sidebar.vue

@@ -89,7 +89,7 @@ export default {
 .create_dialog{
   width: 100%;
   height: 42px;
-  background: #904A87;
+  background: #761E6A;
   border-radius: 8px;
   font-family: PingFang-SC, PingFang-SC;
   font-weight: bold;

+ 1 - 1
src/views/modules/agent/knowledge/detail.vue

@@ -115,7 +115,7 @@
     const handleDelete = (item) => {
         proxy.$confirm('删除后无法恢复,确认删除吗?', '提示', {
             confirmButtonText: '确定',
-            confirmButtonColor: '#833478',
+            confirmButtonColor: '#761E6A',
             cancelButtonText: '取消',
             type: 'warning'
         }).then(() => {

+ 5 - 5
src/views/modules/agent/knowledgeCategory.vue

@@ -247,7 +247,7 @@
                         line-height: 14px;
                         &:last-child{
                             font-size: 20px;
-                            color: #833478;
+                            color: #761E6A;
                             cursor: pointer;
                         }
                     }
@@ -269,9 +269,9 @@
                         cursor: pointer;
                         &:hover,&.active{
                             background: #F0F2F8;
-                            color: #833478;
+                            color: #761E6A;
                             i{
-                                color: #833478 !important;
+                                color: #761E6A !important;
                             }
                         }
                         
@@ -346,7 +346,7 @@
                             line-height: 36px;
                             text-align: center;
                             &:last-child{
-                                background: #833478;
+                                background: #761E6A;
                                 color: #FFFFFF;
                             }
                         }
@@ -374,7 +374,7 @@
                 padding-bottom: 0;
             }
             &:hover{
-                color: #833478;
+                color: #761E6A;
             }
         }
     }

+ 43 - 50
src/views/modules/agent/program.vue

@@ -4,8 +4,8 @@
         <div class="tabs">
             <div class="t_pre" :class="{'active':tidx===1}" @click="handleChangeTab(1)">活动项目</div>
             <div class="t_pre" :class="{'active':tidx===2}" @click="handleChangeTab(2)">已完成</div>
-            <div class="t_pre" :class="{'active':tidx===3}" @click="handleChangeTab(3)">已归档</div>
-            <div class="t_add" @click="handleAdd">+ 创建新项目</div>
+            <!-- <div class="t_pre" :class="{'active':tidx===3}" @click="handleChangeTab(3)">已归档</div>-->
+            <div class="t_add" @click="handleAdd" v-hasPermi="['core:project:add']">+ 创建新项目</div>
         </div>
         <template v-if="tidx===1">
             <div class="content">
@@ -14,29 +14,28 @@
                         <div class="tul_left">
                             <div class="tull_top">
                                 <div class="tullt_l">项目管理</div>
-                                <div class="tullt_r" @click="handleAddTeam">+添加团队</div>
+                                <div class="tullt_r" @click="handleAddTeam" v-hasPermi="['core:project:addTeam']">+添加团队</div>
                             </div>
                             <div class="tull_query queryInput">
-                                <el-input v-model="companyName" placeholder="请输入公司名称"></el-input>
+                                <el-input v-model="programName" placeholder="请输入项目名称"></el-input>
                                 <img src="@/assets/images/agent/query_mini.png">
                             </div>
                             <div class="tull_list">
                                 <div class="tull_item" v-for="(item,index) in companyList" :key="index" @click="handleExpand(item,index)">
                                     <div class="tname">
                                         <img src="@/assets/images/agent/down_sj.png">
-                                        <span>{{ item.name }}</span>
+                                        <span>{{ item.enterpriseName }}</span>
                                     </div>
                                     <template v-if="item.expand&&item.teams&&item.teams.length">
                                         <div class="tuser_list" :class="{'active':team.select}" v-for="(team,idx) in item.teams" :key="idx" @click.stop="handleSelect(team,idx)">
-                                            <span>{{ team.name }}</span>
-                                            <span>({{ team.num }}人)</span>
-                                            <!-- <i class="el-icon-more" style="font-size: 14px;color: #999; transform: rotate(90deg);" @click.stop="handleSetTeam(team,idx)"></i> -->
+                                            <span>{{ team.teamName }}</span>
+                                            <span>({{ team.teamNum }}人)</span>
                                             <el-popover placement="right" width="177" trigger="click">
                                                 <div class="tl_czs">
-                                                    <div class="tlc_pre">修改团队教练</div>
-                                                    <div class="tlc_pre">修改团队名称</div>
-                                                    <div class="tlc_pre" @click="handleTeamDetail(item)">团队详情</div>
-                                                    <div class="tlc_pre">删除团队</div>
+                                                    <div class="tlc_pre" v-hasPermi="['core:project:updateTeamCoach']">修改团队教练</div>
+                                                    <div class="tlc_pre" v-hasPermi="['core:project:updateTeamName']">修改团队名称</div>
+                                                    <div class="tlc_pre" @click="handleTeamDetail(item)" v-hasPermi="['core:project:teamInfo']">团队详情</div>
+                                                    <div class="tlc_pre" v-hasPermi="['core:project:deleteTeam']">删除团队</div>
                                                 </div>
                                                 <i slot="reference" class="el-icon-more" style="font-size: 14px;color: #999; transform: rotate(90deg);" @click.stop="handleSetTeam(team,idx)"></i>
                                             </el-popover>
@@ -52,8 +51,8 @@
                                     <img src="@/assets/images/agent/query_mini.png">
                                 </div>
                                 <div class="tulrt_r">
-                                    <div class="tr_btn">批量导入</div>
-                                    <div class="tr_btn" @click="userShow=true">添加成员</div>
+                                    <div class="tr_btn" v-hasPermi="['sys:user:export']">批量导入</div>
+                                    <div class="tr_btn" @click="userShow=true" v-hasPermi="['sys:user:add']">添加成员</div>
                                 </div>
                             </div>
                             <el-table :data="userList" border cell-class-name="vertical-top-cell" v-loading="loading" empty-text="暂无人员" max-height="578px" style="margin-top: 16px;">
@@ -76,8 +75,8 @@
                                 <el-table-column label="创建时间" prop="aaa"></el-table-column>
                                 <el-table-column label="操作" width="150">
                                     <template #default="scope">
-                                        <el-button link type="text" size="mini" @click="handleEdit(scope.row)">编辑</el-button>
-                                        <el-button link type="text" size="mini" @click="handleDelete(scope.row)">删除</el-button>
+                                        <el-button link type="text" size="mini" @click="handleEdit(scope.row)" v-hasPermi="['sys:user:update']">编辑</el-button>
+                                        <el-button link type="text" size="mini" @click="handleDelete(scope.row)" v-hasPermi="['sys:user:delete']">删除</el-button>
                                     </template>
                                 </el-table-column>
                             </el-table>
@@ -100,7 +99,7 @@
                     <div class="empty">
                         <img src="@/assets/images/agent/team.png">
                         <p>您还没有任何项目及团队成员信息</p>
-                        <div class="e_add" @click="handleAdd">+ 创建新项目</div>
+                        <div class="e_add" @click="handleAdd" v-hasPermi="['core:project:add']">+ 创建新项目</div>
                     </div>
                 </template>
             </div>
@@ -171,7 +170,7 @@
                 </el-row>
             </el-form>
             <div class="demo-drawer__footer" style="display: flex;justify-content: end;">
-                <el-button :loading="buttonLoading2" type="primary" @click="submitForm2">保 存</el-button>
+                <el-button :loading="buttonLoading2" type="primary" @click="submitForm2" v-hasPermi="['sys:user:save']">保 存</el-button>
                 <el-button @click="cancel2" style="margin-right: 5%;">取 消</el-button>
             </div>
         </el-drawer>
@@ -220,32 +219,14 @@
 </template>
 
 <script setup name="">
-    import { ref, getCurrentInstance } from 'vue'
+    import { ref, getCurrentInstance,onMounted } from 'vue'
     const { proxy } = getCurrentInstance();
+    import { getCoachProgramList,getCoachProgramInfo,deleteCoachProgram } from '@/api/agent/index.js'
 
     const tidx = ref(1);
     const teamList = ref([1]);
-    const companyName = ref('')
-    const companyList = ref([
-        {
-            id:1,
-            name: '合肥市传秀科技公司项目',
-            teams:[
-                {id:1,name:'研发团队',num:24,select:false},
-                {id:2,name:'外勤团队',num:3,select:false}
-            ],
-            expand:false
-        },
-        {
-            id:2,
-            name: '合肥市润泽科技公司项目',
-            teams:[
-                {id:1,name:'研发团队',num:7,select:false},
-                {id:2,name:'外勤团队',num:3,select:false}
-            ],
-            expand:false
-        }
-    ]);
+    const programName = ref('')
+    const companyList = ref([]);
     const loading = ref(false);
     const queryParams = ref({
         page:1,
@@ -375,6 +356,18 @@
     const handleTeamDetail = team => {
         teamShow.value = true;
     }
+
+    const getProgramList = async () => {
+        loading.value = true;
+        const res = await getCoachProgramList(programName.value);
+        companyList.value = res.data;
+        companyList.value.forEach(t => t.expand = false);
+        companyList.value.teams.forEach(t => t.select = false);
+        loading.value = false;
+    }
+    onMounted(() => {
+        getProgramList();
+    });
 </script>
 
 <style scoped lang="scss">
@@ -416,7 +409,7 @@
                 cursor: pointer;
                 &.active{
                     font-weight: bold;
-                    color: #833478;
+                    color: #761E6A;
                     &::after{
                         content: '';
                         position: absolute;
@@ -424,14 +417,14 @@
                         left: 0;
                         width: 100%;
                         height: 2px;
-                        background: #833478;
+                        background: #761E6A;
                     }
                 }
             }
             .t_add{
                 width: 114px;
                 height: 32px;
-                background: #833478;
+                background: #761E6A;
                 border-radius: 6px;
                 font-family: PingFangSC, PingFang SC;
                 font-weight: 400;
@@ -478,11 +471,11 @@
                             width: 73px;
                             height: 28px;
                             border-radius: 6px;
-                            border: 1px solid #833478;
+                            border: 1px solid #761E6A;
                             font-family: PingFangSC, PingFang SC;
                             font-weight: 400;
                             font-size: 12px;
-                            color: #833478;
+                            color: #761E6A;
                             line-height: 24px;
                             text-align: center;
                             cursor: pointer;
@@ -555,10 +548,10 @@
                                     border-radius: 6px;
                                     span{
                                         font-weight: bold;
-                                        color: #833478;
+                                        color: #761E6A;
                                     }
                                     i{
-                                        color: #833478 !important;
+                                        color: #761E6A !important;
                                     }
                                 }
                                 i{
@@ -610,7 +603,7 @@
                                 line-height: 36px;
                                 text-align: center;
                                 &:last-child{
-                                    background: #833478;
+                                    background: #761E6A;
                                     color: #FFFFFF;
                                 }
                             }
@@ -641,7 +634,7 @@
                 .e_add{
                     width: 114px;
                     height: 32px;
-                    background: #833478;
+                    background: #761E6A;
                     border-radius: 6px;
                     font-family: PingFangSC, PingFang SC;
                     font-weight: 400;
@@ -675,7 +668,7 @@
                 padding-bottom: 0;
             }
             &:hover{
-                color: #833478;
+                color: #761E6A;
             }
         }
     }

+ 190 - 116
src/views/modules/agent/program/addTeam.vue

@@ -27,66 +27,76 @@
                 <template v-if="step===1">
                     <el-form ref="programRef" :model="programForm" :rules="programRules" label-width="140px" style="width: 90%;margin: 0 auto;">
                         <div class="f_title">创建新项目</div>
-                        <el-form-item label="企业名称" prop="aaa">
-                            <el-input v-model="programForm.aaa" placeholder="请输入企业名称" />
+                        <el-form-item label="企业名称" prop="enterpriseName">
+                            <el-input v-model="programForm.enterpriseName" placeholder="请输入企业名称" />
                         </el-form-item>
-                        <el-form-item label="统一社会信用代码" prop="bbb">
-                            <el-input v-model="programForm.bbb" placeholder="请输入统一社会信用代码" />
+                        <el-form-item label="统一社会信用代码" prop="creditCode">
+                            <el-input v-model="programForm.creditCode" placeholder="请输入统一社会信用代码" />
                         </el-form-item>
-                        <el-form-item label="所在地区" prop="ccc">
-                            <el-select v-model="programForm.ccc" placeholder="请选择所在地区" style="width: 100%;">
-                                <el-option label="区域一" value="shanghai"></el-option>
+                        <el-form-item label="所在地区" prop="area">
+                            <el-select v-model="programForm.province" :placeholder="disabled ? '' : '省'" clearable style="width: 32%"
+                                @change="(val) => {  regionChange(val, 'province'); }">
+                                <el-option v-for="item in provinceOptions" :key="item.id" :label="item.name" :value="item.id">
+                                </el-option>
+                            </el-select>
+                            <el-select v-model="programForm.city" :placeholder="disabled ? '' : '市'" clearable style="width: 32%;margin: 0 2%"
+                                @change="(val) => {  regionChange(val, 'city'); }">
+                                <el-option v-for="item in cityOptions" :key="item.id" :label="item.name" :value="item.id">
+                                </el-option>
+                            </el-select>
+                            <el-select v-model="programForm.area" :placeholder="disabled ? '' : '区'" clearable style="width: 32%;"
+                                @change="(val) => {  regionChange(val, 'area'); }">
+                                <el-option v-for="item in areaOptions" :key="item.id" :label="item.name" :value="item.id">
+                                </el-option>
                             </el-select>
                         </el-form-item>
-                        <el-form-item label="所在行业" prop="ddd">
-                            <el-select v-model="programForm.ddd" placeholder="请选择所在行业" style="width: 100%;">
-                                <el-option label="行业一" value="shanghai"></el-option>
+                        <el-form-item label="所在行业" prop="industryCode">
+                            <el-select v-model="programForm.industryCode" placeholder="请选择所在行业" style="width: 100%;">
+                                <el-option v-for="item in companyIndustry" :label="item.label" :value="item.value"></el-option>
                             </el-select>
                         </el-form-item>
-                        <el-form-item label="人员规模" prop="eee">
-                            <el-select v-model="programForm.eee" placeholder="请选择人员规模" style="width: 100%;">
-                                <el-option label="规模一" value="shanghai"></el-option>
+                        <el-form-item label="人员规模" prop="staffSizeCode">
+                            <el-select v-model="programForm.staffSizeCode" placeholder="请选择人员规模" style="width: 100%;">
+                                <el-option v-for="item in staffSize" :label="item.label" :value="item.value"></el-option>
                             </el-select>
                         </el-form-item>
-                        <el-form-item label="项目教练" prop="eee">
-                            <div class="f_s adfacjb" @click="hangleSelectCoach">
+                        <el-form-item label="项目教练" prop="">
+                            <div class="f_s adfacjb" @click="hangleSelectCoach" v-if="programForm.coachList.length===0">
                                 <div class="fs_text" :class="{'active':coachs!=='请选择'}">{{ coachs }}</div>
                                 <i class="el-icon-arrow-down" style="color: #C0C4CC;"></i>
                             </div>
+                            <div class="f_s adfac" @click="hangleSelectCoach" v-else>
+                                <p>{{ cocahNames }}</p>
+                            </div>
                         </el-form-item>
                     </el-form>
                 </template>
                 <template v-else>
-                    <el-form :model="teamDto" :rules="rules" ref="teamDtoRef" label-width="130px">
+                    <el-form :model="programForm.team" :rules="rules" ref="teamDtoRef" label-width="130px">
                         <div class="f_title">添加团队</div>
                         <el-row style="width: 100%;">
-                            <el-col :span="8">
-                                <el-form-item label="所属项目" prop="aaa">
-                                    <el-select v-model="teamDto.aaa" placeholder="请选择所属项目" style="width: 100%;"></el-select>
-                                </el-form-item>
-                            </el-col>
-                            <el-col :span="8">
-                                <el-form-item label="团队名称" prop="bbb">
-                                    <el-input v-model="teamDto.bbb" clearable placeholder="请输入团队名称"></el-input>
+                            <el-col :span="12">
+                                <el-form-item label="团队名称" prop="teamName">
+                                    <el-input v-model="programForm.team.teamName" clearable placeholder="请输入团队名称"></el-input>
                                 </el-form-item>
                             </el-col>
-                            <el-col :span="8">
-                                <el-form-item label="工作任务" prop="ccc">
-                                    <el-input v-model="teamDto.ccc" clearable placeholder="请输入工作任务"></el-input>
+                            <el-col :span="12">
+                                <el-form-item label="工作任务" prop="workTasks">
+                                    <el-input v-model="programForm.team.workTasks" clearable placeholder="请输入工作任务"></el-input>
                                 </el-form-item>
                             </el-col>
                         </el-row>
                         <el-row style="width: 100%;">
                             <el-col :span="24">
-                                <el-form-item label="团队介绍" prop="ddd">
-                                    <el-input type="textarea" v-model="teamDto.ddd" clearable placeholder="请输入团队介绍"></el-input>
+                                <el-form-item label="团队介绍" prop="introduce">
+                                    <el-input type="textarea" v-model="programForm.team.introduce" clearable placeholder="请输入团队介绍"></el-input>
                                 </el-form-item>
                             </el-col>
                         </el-row>
                         <el-row style="width: 100%;">
                             <el-col :span="24">
-                                <el-form-item label="团队项目情况" prop="eee">
-                                    <el-input type="textarea" v-model="teamDto.eee" clearable placeholder="请输入团队项目情况"></el-input>
+                                <el-form-item label="团队项目情况" prop="projectSituation">
+                                    <el-input type="textarea" v-model="programForm.team.projectSituation" clearable placeholder="请输入团队项目情况"></el-input>
                                 </el-form-item>
                             </el-col>
                         </el-row>
@@ -104,15 +114,22 @@
                                         <div class="f_pldr">
                                             <div class="fp_box">
                                                 <div class="fpb_pre">
-                                                    <div class="fpbp_btn">下载Excel示例文件</div>
+                                                    <div class="fpbp_btn" @click="handleDownloadExcel" v-hasPermi="['core:project:downloadExcel']">下载Excel示例文件</div>
                                                 </div>
                                                 <img src="@/assets/images/agent/arrow_right_two.png">
                                                 <div class="fpb_pre sc">
-                                                    <div class="fpbp_btn">上传Excel文件</div>
+                                                    <el-upload
+                                                        :action="uploadUrl"
+                                                        :headers="uploadHeaders"
+                                                        :on-success="uploadFileSuccess"
+                                                        :before-upload="beforeAvatarUpload"
+                                                        :limit="1">
+                                                        <div class="fpbp_btn" v-hasPermi="['core:project:uploadExcel']">上传Excel文件</div>
+                                                    </el-upload> 
                                                 </div>
                                             </div>
                                             <p>
-                                                1、Excel文件后缀名为xls或者xlsx,文件中所含烈数请勿超过20列<br>
+                                                1、Excel文件后缀名为xls或者xlsx,文件中所含数请勿超过20列<br>
                                                 2、模版中用户姓名为必填,其他为选填,且不能对已有字段进行删除、修改<br>
                                                 3、部门:上下级部门间用“/”符号隔开,且从最上级部门开始,例如“产品部门/设计”。若存在属于多个部门的情况,不同部门之间用 ; 隔开。
                                             </p>
@@ -120,65 +137,64 @@
                                     </template>
                                     <template v-else-if="addType===2">
                                         <div class="f_sdlr">
-                                            <div class="fs_item" v-for="(item,index) in teamDto.userList" :key="index">
-                                                <el-form :model="teamDto.userList[index]" label-width="100px">
+                                            <div class="fs_item" v-for="(item,index) in programForm.team.users" :key="index">
+                                                <el-form :model="programForm.team.users[index]" label-width="100px">
                                                     <el-row style="width: 100%;">
                                                         <el-col :span="8">
-                                                            <el-form-item label="姓名" prop="aa">
-                                                                <el-input v-model="teamDto.userList[index].aa" clearable placeholder="请输入"></el-input>
+                                                            <el-form-item label="姓名" prop="realName">
+                                                                <el-input v-model="programForm.team.users[index].realName" clearable placeholder="请输入"></el-input>
                                                             </el-form-item>
                                                         </el-col>
                                                         <el-col :span="8">
-                                                            <el-form-item label="性别" prop="bb">
-                                                                <el-select v-model="teamDto.userList[index].bb" placeholder="请选择" style="width: 100%;"></el-select>
+                                                            <el-form-item label="性别" prop="gender">
+                                                                <el-select v-model="programForm.team.users[index].gender" placeholder="请选择" style="width: 100%;">
+                                                                    <el-option label="男" :value="0"></el-option>
+                                                                    <el-option label="女" :value="1"></el-option>
+                                                                    <el-option label="保密" :value="2"></el-option>
+                                                                </el-select>
                                                             </el-form-item>
                                                         </el-col>
                                                         <el-col :span="8">
-                                                            <el-form-item label="出生日期" prop="cc">
-                                                                <el-select v-model="teamDto.userList[index].cc" placeholder="请选择" style="width: 100%;"></el-select>
+                                                            <el-form-item label="出生日期" prop="birthdate">
+                                                                <el-date-picker v-model="programForm.team.users[index].birthdate" type="date" placeholder="请选择" style="width: 100%;"></el-date-picker>
                                                             </el-form-item>
                                                         </el-col>
                                                     </el-row>
                                                     <el-row style="width: 100%;">
                                                         <el-col :span="8">
-                                                            <el-form-item label="手机号码" prop="dd">
-                                                                <el-input v-model="teamDto.userList[index].dd" clearable placeholder="请输入"></el-input>
+                                                            <el-form-item label="手机号码" prop="mobile">
+                                                                <el-input type="number" v-model="programForm.team.users[index].mobile" clearable placeholder="请输入"></el-input>
                                                             </el-form-item>
                                                         </el-col>
                                                         <el-col :span="8">
-                                                            <el-form-item label="所属部门" prop="ee">
-                                                                <el-input v-model="teamDto.userList[index].ee" clearable placeholder="请输入"></el-input>
+                                                            <el-form-item label="所属部门" prop="dept">
+                                                                <el-input v-model="programForm.team.users[index].dept" clearable placeholder="请输入"></el-input>
                                                             </el-form-item>
                                                         </el-col>
                                                         <el-col :span="8">
-                                                            <el-form-item label="职位" prop="ff">
-                                                                <el-select v-model="teamDto.userList[index].ff" placeholder="请选择" style="width: 100%;"></el-select>
+                                                            <el-form-item label="职位" prop="post">
+                                                                <el-input v-model="programForm.team.users[index].post" clearable placeholder="请输入"></el-input>
                                                             </el-form-item>
                                                         </el-col>
                                                     </el-row>
                                                     <el-row style="width: 100%;">
                                                         <el-col :span="8">
-                                                            <el-form-item label="分工" prop="gg">
-                                                                <el-input v-model="teamDto.userList[index].gg" clearable placeholder="请输入"></el-input>
+                                                            <el-form-item label="分工" prop="divisionOfLabour">
+                                                                <el-input v-model="programForm.team.users[index].divisionOfLabour" clearable placeholder="请输入"></el-input>
                                                             </el-form-item>
                                                         </el-col>
                                                         <el-col :span="8">
-                                                            <el-form-item label="上级" prop="hh">
-                                                                <el-input v-model="teamDto.userList[index].hh" clearable placeholder="请输入"></el-input>
+                                                            <el-form-item label="教育程度" prop="education">
+                                                                <el-input v-model="programForm.team.users[index].education" clearable placeholder="请输入"></el-input>
                                                             </el-form-item>
                                                         </el-col>
                                                         <el-col :span="8">
-                                                            <el-form-item label="教育程度" prop="ii">
-                                                                <el-select v-model="teamDto.userList[index].ii" placeholder="请选择" style="width: 100%;"></el-select>
+                                                            <el-form-item label="级别" prop="level">
+                                                                <el-input v-model="programForm.team.users[index].level" clearable placeholder="请输入"></el-input>
                                                             </el-form-item>
                                                         </el-col>
                                                     </el-row>
                                                     <el-row style="width: 100%;">
-                                                        <el-col :span="8">
-                                                            <el-form-item label="级别" prop="jj">
-                                                                <el-select v-model="teamDto.userList[index].jj" placeholder="请选择" style="width: 100%;"></el-select>
-                                                            </el-form-item>
-                                                        </el-col>
                                                         <el-col :span="8">
                                                             <el-form-item label="" prop="">
                                                                 <div class="fs_add del" @click="handleDeleteItem(item,index)">x 删除</div>
@@ -199,24 +215,24 @@
             <div class="btns">
                 <el-button type="primary" @click="handleNext" v-if="step===1" style="margin-left: 20px;">下一步</el-button>
                 <el-button type="primary" @click="handlePrevious" v-if="step===2" style="margin-left: 20px;">上一步</el-button>
-                <el-button type="primary" @click="handleConfirm" v-if="step===2" style="margin-left: 20px;">确认</el-button>
+                <el-button type="primary" @click="handleConfirm" v-if="step===2" style="margin-left: 20px;" v-hasPermi="['core:project:save']">确认</el-button>
                 <el-button type="default" @click="handleCancel" style="margin-left: 20px;">取消</el-button>
             </div>
         
             <el-dialog width="790px" :visible.sync="coachShow" title="选择教练" @close="coachShow=false">
                 <div class="ed_coach adf">
                     <div class="ec_l">
-                        <el-input placeholder="请输入教练名搜索" suffix-icon="el-icon-search" v-model="coachName" style="width: 100%;"></el-input>
+                        <el-input placeholder="请输入教练名搜索" suffix-icon="el-icon-search" v-model="coachName" style="width: 100%;" @keyup.enter.native="handleQueryCoach"></el-input>
                         <el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" @change="handleCheckAllChange" style="margin-top: 65px;">全选</el-checkbox>
                         <div class="ecl_cbs">
-                            <el-checkbox v-model="coach.checked" v-for="(coach,index) in coachList" :key="coach.id" @change="handleChangeCoach" style="margin-top: 24px;display: block;">{{ coach.name }}</el-checkbox>
+                            <el-checkbox v-model="coach.checked" v-for="(coach,index) in coachList" :key="coach.id" @change="handleChangeCoach" style="margin-top: 24px;display: block;">{{ coach.realName }}</el-checkbox>
                         </div>
                     </div>
                     <div class="ec_r">
                         <div class="ecr_text">已选择({{ coachSelecteds.length }}/<span>{{ coachList.length }}</span>)</div>
                         <div class="ecr_names">
                             <div class="en_pre adfacjc" v-for="(item,index) in coachSelecteds" :key="index">
-                                <span>{{ item.name }}</span>
+                                <span>{{ item.realName }}</span>
                                 <img src="@/assets/images/agent/delete_mini.png" @click="handleDeleteCoach(item,index)">
                             </div>
                         </div>
@@ -232,8 +248,22 @@
 </template>
 
 <script setup name="">
+    import Cookies from "js-cookie";
     import { ref, getCurrentInstance } from 'vue'
+    import { getCoachList,addCoachProgram } from "@/api/agent/index";
+    import { useRegion } from "@/mixins/region-module";
     const { proxy } = getCurrentInstance();
+    const { companyIndustry, staffSize} = proxy.useDict("companyIndustry", "staffSize");
+    const {
+        provinceOptions,
+        cityOptions,
+        areaOptions,
+        provincAreaDetailInfoList,
+        regionChange
+    } = useRegion();
+    provincAreaDetailInfoList();
+    const uploadUrl = `${window.SITE_CONFIG["apiURL"]}/sys/oss/uploadFile`
+    const uploadHeaders = {token:Cookies.get("token")};
     
     const topname = ref('创建项目')
     const step = ref(1)
@@ -241,65 +271,63 @@
     const coachName = ref('')
     const coachShow = ref(false)
     const coachSelecteds = ref([])
-    const coachList = ref([
-        {id:1,name:'张三',checked:false},
-        {id:2,name:'李四',checked:false},
-        {id:3,name:'王五',checked:false},
-        {id:4,name:'赵六',checked:false},
-        {id:5,name:'田七',checked:false}
-    ])
+    const coachList = ref([])
     const isIndeterminate = ref(false)
     const checkAll = ref(false)
+    const cocahNames = ref('')
 
     const programForm = ref({
-        aaa: '',
-        bbb: '',
-        ccc: '',
-        ddd: '',
-        eee: ''
+        enterpriseName: '',
+        creditCode: '',
+        areaCode: '',
+        industryCode: '',
+        staffSizeCode: '',
+        province:'',
+        city:'',
+        area:'',
+        areaCode:'',
+        coachList:[],
+        team:{
+            id:'',
+            teamName:'',
+            workTasks:'',
+            introduce:'',
+            projectSituation:'',
+            file:'',
+            users:[]
+        }
     });
     const programRules = ref({
-        aaa: [
+        enterpriseName: [
             { required: true, message: '请输入企业名称', trigger: 'blur' }
         ],
-        bbb: [
+        creditCode: [
             { required: true, message: '请输入统一社会信用代码', trigger: 'blur' }
         ],
-        ccc: [
-            { required: true, message: '请选择所在地区', trigger: 'change' }
-        ],
-        ddd: [
+        industryCode: [
             { required: true, message: '请选择所在行业', trigger: 'change' }
         ],
-        eee: [
+        staffSizeCode: [
             { required: true, message: '请选择人员规模', trigger: 'change' }
+        ],
+        area: [
+            { required: true, message: '请选择所在地区', trigger: 'change' }
         ]
     });
-    const teamDto = ref({
-        aaa: '',
-        bbb: '',
-        ccc: '',
-        ddd: '',
-        eee: '',
-        userList:[]
-    })
     const addType = ref(1)
     const programRef = ref(null)
     const teamDtoRef = ref(null)
     const rules = ref({
-        aaa: [
-            { required: true, message: '请选择所属项目', trigger: 'change' }
-        ],
-        bbb: [
+        teamName: [
             { required: true, message: '请输入团队名称', trigger: 'blur' }
         ],
-        ccc: [
+        workTasks: [
             { required: true, message: '请输入工作任务', trigger: 'blur' }
         ],
-        ddd: [
+        introduce: [
             { required: true, message: '请输入团队介绍', trigger: 'blur' }
         ],
-        eee: [
+        projectSituation: [
             { required: true, message: '请输入团队项目情况', trigger: 'blur' }
         ]
     })
@@ -307,29 +335,45 @@
     const handleBack = () => {
         proxy.$router.back()
     }
+    
+    const uploadFileSuccess = e =>{
+        programForm.value.team.file = e.data;
+    }
+    
+    const beforeAvatarUpload = (e) => {
+        let type = e.name.split('.')[e.name.split('.').length-1];
+        let isExcel = e.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
+        if(type.toLowerCase() !== 'xlsx' && type.toLowerCase() !== 'xls' && !isExcel){
+            proxy?.$modal.msgError('请上传xlsx或xls格式的Excel文件!');
+            return false;
+        }
+    }
 
     const handleAddItem = () => {
-        teamDto.value.userList.push({
-            aa: '',
-            bb: '',
-            cc: '',
-            dd: '',
-            ee: '',
-            ff: '',
-            gg: '',
-            hh: '',
-            ii: '',
-            jj: ''
+        programForm.value.team.users.push({
+            id:'',
+            realName:'',
+            gender:'',
+            birthdate:'',
+            mobile:'',
+            dept:'',
+            post:'',
+            divisionOfLabour:'',
+            education:'',
+            level:'',
         })
     }
 
     const handleDeleteItem = (item,index) => {
-        teamDto.value.userList.splice(index,1)
+        programForm.value.team.users.splice(index,1)
     }
 
     const handleNext = () => {
         proxy.$refs.programRef.validate((valid) => {
             if (valid) {
+                programForm.value.areaCode = `${programForm.value.province}-${programForm.value.city}-${programForm.value.area}`;
+                if(programForm.value.coachList.length===0) return proxy.$message.warning('请至少选择一位教练');
+                console.log(programForm.value,'programForm')
                 step.value = 2;
                 topname.value = '添加团队及其成员';
             } else {
@@ -344,8 +388,11 @@
     const handleConfirm = () => {
         proxy.$refs.teamDtoRef.validate((valid) => {
             if (valid) {
-                console.log(programForm.value);
-                console.log(teamDto.value);
+                addCoachProgram(programForm.value).then(res => {
+                    if(res.code!==0) return proxy.$message.error(res.msg);
+                    proxy.$message.success('创建成功,即将返回');
+                    settimeout(()=>{proxy.$router.back();},1500)
+                })
             } else {
                 return false;
             }
@@ -356,10 +403,30 @@
     }
 
     const hangleSelectCoach = () => {
-        coachShow.value = true;
+        getCoachList({page:1,limit:-1,realName:coachName.value}).then(res => {
+            if(res.code!==0) return proxy.$message.error(res.msg);
+            coachList.value = res.data.list;
+            coachList.value.forEach(item => {
+                item.checked = false;
+            })
+            coachShow.value = true;
+        })
+    }
+    const handleQueryCoach = () => {
+        checkAll.value = false;
+        isIndeterminate.value = false;
+        coachSelecteds.value = [];
+        hangleSelectCoach();
     }
 
     const submitForm = () => {
+        if(coachSelecteds.value.length===0) return proxy.$message.warning('请至少选择一位教练')
+        programForm.value.coachList = JSON.parse(JSON.stringify(coachSelecteds.value)).map(c=>{return {coachId:c.id,coachName:c.realName}});
+        cocahNames.value = programForm.value.coachList.map(c=>c.coachName).join(';');
+        checkAll.value = false;
+        isIndeterminate.value = false;
+        coachSelecteds.value = [];
+        coachList.value = [];
         coachShow.value = false;
     }
     const cancel = () => {
@@ -391,6 +458,10 @@
         if(trues===coachList.value.length) checkAll.value = true;
         else checkAll.value = false;
     }
+
+    const handleDownloadExcel = () => {
+        window.location.href = `${window.SITE_CONFIG["apiURL"]}/sys/user/download?token=${Cookies.get("token")}`;
+    }
 </script>
 
 <style scoped lang="scss">
@@ -537,7 +608,7 @@
                         font-family: PingFangSC, PingFang SC;
                         font-weight: 400;
                         font-size: 12px;
-                        color: #833478;
+                        color: #761E6A;
                         line-height: 32px;
                         text-align: center;
                         cursor: pointer;
@@ -545,8 +616,8 @@
                     &.sc{
                         border-left: 1px solid #EDEEF0;
                         .fpbp_btn{
-                            background: #833478;
-                            border: 1px solid #833478;
+                            background: #761E6A;
+                            border: 1px solid #761E6A;
                             color: #FFFFFF;
                         }
                     }
@@ -578,7 +649,7 @@
             .fs_add{
                 width: 80px;
                 height: 32px;
-                background: #833478;
+                background: #761E6A;
                 border-radius: 6px;
                 font-family: PingFangSC, PingFang SC;
                 font-weight: 400;
@@ -614,6 +685,9 @@
                     color: #606266;
                 }
             }
+            p{
+
+            }
         }
 
         .ed_coach{

+ 1 - 1
src/views/modules/agent/questionnaire.vue

@@ -232,7 +232,7 @@
                     margin-top: 20px;
                     .lj{
                         height: 100%;
-                        background: linear-gradient( 270deg, #9D5F94 0%, #904A87 100%);
+                        background: linear-gradient( 270deg, #9D5F94 0%, #761E6A 100%);
                         border-radius: 4px;
                         position: absolute;
                         left: 0;

+ 2 - 2
src/views/modules/agent/questionnaire/schedule.vue

@@ -73,7 +73,7 @@
         if(!multipleSelection.value.length) return proxy.$message({ type: 'warning', message: '请选择需要提醒的人员' })
         proxy.$confirm('是否确认发送通知提醒??', '警告', {
             confirmButtonText: '确定',
-            confirmButtonColor:'#833478',
+            confirmButtonColor:'#761E6A',
             cancelButtonText: '取消',
             type: 'warning'
         }).then(() => {
@@ -87,7 +87,7 @@
     const handleRemind = (row) => {
         proxy.$confirm('是否确认发送通知提醒??', '警告', {
             confirmButtonText: '确定',
-            confirmButtonColor:'#833478',
+            confirmButtonColor:'#761E6A',
             cancelButtonText: '取消',
             type: 'warning'
         }).then(() => {

+ 1 - 1
src/views/modules/agent/report.vue

@@ -143,7 +143,7 @@
                         content: '';
                         width: 116px;
                         height: 2px;
-                        background: #833478;
+                        background: #761E6A;
                         position: absolute;
                         left: 0;
                         bottom: 0;

+ 162 - 93
src/views/modules/agent/user.vue

@@ -1,38 +1,35 @@
 <template>
     <div class="agent_page">
-        <div class="title">用户管理</div>
+        <div class="title">教练管理</div>
         <div class="query adfacjb">
             <div class="left adfac">
-                <el-input placeholder="请输入姓名搜索" prefix-icon="el-icon-search" v-model="queryParams.name" style="width: 300px;"></el-input>
-                <el-select v-model="queryParams.company" placeholder="所属公司" style="width: 200px;margin-left: 23px;"></el-select>
-                <el-select v-model="queryParams.sortType" placeholder="排序方式" style="width: 200px;margin-left: 23px;"></el-select>
+                <el-input placeholder="请输入姓名搜索" prefix-icon="el-icon-search" v-model="queryParams.realName" style="width: 300px;" @keyup.enter.native="handleQuery"></el-input>
+                <el-input type="number" placeholder="请输入手机号码搜索" prefix-icon="el-icon-search" v-model="queryParams.mobile" style="width: 300px;margin-left: 30px;" @keyup.enter.native="handleQuery"></el-input>
             </div>
             <div class="right">
-                <el-button type="primary" icon="el-icon-plus" @click="userShow=true">添加用户</el-button>
+                <el-button type="primary" icon="el-icon-plus" @click="handleAddCoach">添加教练</el-button>
             </div>
         </div>
-        <el-table :data="userList" border cell-class-name="vertical-top-cell" v-loading="loading" empty-text="暂无用户" max-height="578px" style="margin-top: 24px;">
+        <el-table :data="userList" border cell-class-name="vertical-top-cell" v-loading="loading" empty-text="暂无教练" max-height="578px" style="margin-top: 24px;">
             <el-table-column label="序号" width="50">
                 <template #default="scope">
                     {{ scope.$index + 1 }}
                 </template>
             </el-table-column>
-            <el-table-column label="姓名" prop="aaa"></el-table-column>
-            <el-table-column label="性别" prop="bbb">
-                <template #default="{ row }"></template>
+            <el-table-column label="姓名" prop="realName"></el-table-column>
+            <el-table-column label="性别" prop="gender">
+                <template #default="{ row }">{{ gender[row.gender]||'未知' }}</template>
             </el-table-column>
-            <el-table-column label="出生日期" prop="aaa"></el-table-column>
-            <el-table-column label="手机号码" prop="aaa"></el-table-column>
-            <el-table-column label="用户类型" prop="aaa"></el-table-column>
-            <el-table-column label="教练资格类型" prop="aaa"></el-table-column>
-            <el-table-column label="教练时长" prop="aaa"></el-table-column>
-            <el-table-column label="教练特长" prop="aaa"></el-table-column>
-            <el-table-column label="创建时间" prop="aaa"></el-table-column>
+            <el-table-column label="出生日期" prop="birthdate"></el-table-column>
+            <el-table-column label="手机号码" prop="mobile"></el-table-column>
+            <el-table-column label="教练资格类型" prop="qualificationType"></el-table-column>
+            <el-table-column label="教练时长" prop="coachDuration"></el-table-column>
+            <el-table-column label="教练特长" prop="talent"></el-table-column>
+            <el-table-column label="创建时间" prop="createDate"></el-table-column>
             <el-table-column label="操作" width="200">
                 <template #default="scope">
-                    <el-button link type="text" size="mini" @click="handleEdit(scope.row)">编辑</el-button>
-                    <el-button link type="text" size="mini" @click="handleStudent(scope.row)">教练学员</el-button>
-                    <el-button link type="text" size="mini" @click="handleDelete(scope.row)">删除</el-button>
+                    <el-button link type="text" size="mini" @click="handleEdit(scope.row)" v-hasPermi="['sys:user:update']">编辑</el-button>
+                    <el-button link type="text" size="mini" @click="handleDelete(scope.row)" v-hasPermi="['sys:user:delete']">删除</el-button>
                 </template>
             </el-table-column>
         </el-table>
@@ -48,59 +45,79 @@
                 v-show="total > 0">
             </el-pagination>
         </el-row>
-        <el-drawer :title="userTitle" :visible.sync="userShow" append-to-body size="60%" @close="userShow=false">
+        <el-drawer :title="userTitle" :visible.sync="userShow" append-to-body size="60%" @close="cancel">
             <el-form ref="userRef" :model="userForm" :rules="userRules" label-width="120px" style="width: 95%;margin: 0 auto;">
                 <el-row>
                   <el-col :span="12">
-                    <el-form-item label="姓名" prop="aaa">
-                      <el-input v-model="userForm.aaa" placeholder="请输入姓名" />
+                    <el-form-item label="姓名" prop="realName">
+                      <el-input v-model="userForm.realName" placeholder="请输入姓名" />
                     </el-form-item>
                   </el-col>
                   <el-col :span="12">
-                    <el-form-item label="性别" prop="bbb">
-                        <el-select v-model="userForm.bbb" placeholder="请选择性别" style="width: 100%;"></el-select>
+                    <el-form-item label="性别" prop="gender">
+                        <el-select v-model="userForm.gender" placeholder="请选择性别" style="width: 100%;">
+                            <el-option label="男" :value="0"></el-option>
+                            <el-option label="女" :value="1"></el-option>
+                            <el-option label="保密" :value="2"></el-option>
+                        </el-select>
                     </el-form-item>
                   </el-col>
                 </el-row>
                 <el-row>
                   <el-col :span="12">
-                    <el-form-item label="出生日期" prop="ccc">
-                        <el-select v-model="userForm.ccc" placeholder="请选择出生日期" style="width: 100%;"></el-select>
+                    <el-form-item label="出生日期" prop="birthdate">
+                        <el-date-picker style="width: 100%;" @change="handleChangeDate"
+                            v-model="userForm.birthdate"
+                            type="date"
+                            placeholder="请选择出生日期">
+                        </el-date-picker>
                     </el-form-item>
                   </el-col>
                   <el-col :span="12">
-                    <el-form-item label="手机号码" prop="ddd">
-                      <el-input type="phone" v-model="userForm.ddd" placeholder="请输入手机号码" />
+                    <el-form-item label="手机号码" prop="mobile">
+                      <el-input type="number" v-model="userForm.mobile" placeholder="请输入手机号码" />
                     </el-form-item>
                   </el-col>
                 </el-row>
                 <el-row>
                   <el-col :span="12">
-                    <el-form-item label="教练资格类型" prop="eee">
-                      <el-input type="phone" v-model="userForm.eee" placeholder="请输入教练资格类型" />
+                    <el-form-item label="教练资格类型" prop="qualificationType">
+                      <el-input v-model="userForm.qualificationType" placeholder="请输入教练资格类型" />
                     </el-form-item>
                   </el-col>
                   <el-col :span="12">
-                    <el-form-item label="用户类型" prop="fff">
-                        <el-select v-model="userForm.fff" placeholder="请选择用户类型" style="width: 100%;"></el-select>
+                    <el-form-item label="教练特长" prop="talent">
+                        <el-input v-model="userForm.talent" placeholder="请输入教练特长" />
                     </el-form-item>
                   </el-col>
                 </el-row>
                 <el-row>
                   <el-col :span="12">
-                    <el-form-item label="教练特长" prop="ggg">
-                        <el-input v-model="userForm.ggg" placeholder="请输入教练特长" />
+                    <el-form-item label="教练时长" prop="coachDuration">
+                        <el-input type="number" v-model="userForm.coachDuration" placeholder="请输入教练时长" />
                     </el-form-item>
                   </el-col>
                   <el-col :span="12">
-                    <el-form-item label="教练时长" prop="hhh">
-                        <el-input v-model="userForm.hhh" placeholder="请输入教练时长" />
+                    <el-form-item label="角色配置" prop="coachDuration">
+                        <el-select style="width: 100%;"
+                            v-model="userForm.roleIdList"
+                            multiple="true"
+                            placeholder="请选择角色配置"
+                            clearable
+                            >
+                            <el-option
+                                v-for="role in roleList"
+                                :key="role.id"
+                                :label="role.remark"
+                                :value="role.id"
+                            ></el-option>
+                        </el-select>
                     </el-form-item>
                   </el-col>
                 </el-row>
             </el-form>
             <div class="demo-drawer__footer" style="display: flex;justify-content: end;">
-                <el-button :loading="buttonLoading" type="primary" @click="submitForm">保 存</el-button>
+                <el-button :loading="buttonLoading" type="primary" @click="submitForm" v-hasPermi="['sys:user:save']">保 存</el-button>
                 <el-button @click="cancel" style="margin-right: 5%;">取 消</el-button>
             </div>
         </el-drawer>
@@ -108,67 +125,120 @@
 </template>
 
 <script setup name="">
-    import { ref, getCurrentInstance } from 'vue'
+    import { ref, getCurrentInstance, onMounted } from 'vue'
+    import { getCoachList,addCoach,updateCoach,getCoachInfo,deleteCoach } from '@/api/agent/index.js';
     const { proxy } = getCurrentInstance();
+    const gender = {
+        0:'男',
+        1:'女',
+        2:'保密'
+    }
     
+    const roleList = ref([])
     const queryParams = ref({
         page:1,
         limit:10,
-        name:'',
-        company:'',
-        sortType:''
+        realName:'',
+        mobile:''
     })
     const userList = ref([1])
     const loading = ref(false)
     const total = ref(0)
     const userShow = ref(false)
-    const userTitle = ref('添加用户')
+    const userTitle = ref('添加教练')
     const userForm = ref({
-        aaa:'',
-        bbb:'',
-        ccc:'',
-        ddd:'',
-        eee:'',
-        fff:'',
-        ggg:'',
-        hhh:''
+        id:'',
+        realName:'',
+        gender:'',
+        birthdate:'',
+        mobile:'',
+        qualificationType:'',
+        coachDuration:'',
+        talent:'',
+        roleIdList:[],
+        userType:1
     })
     const userRules = ref({
-        aaa: [
+        realName: [
             { required: true, message: '请输入姓名', trigger: 'blur' },
         ],
-        bbb: [
+        gender: [
             { required: true, message: '请选择性别', trigger: 'change' }
         ],
-        ccc: [
-            { required: true, message: '请选择出生日期', trigger: 'change' }
-        ],
-        ddd: [
+        // birthdate: [
+        //     { required: true, message: '请选择出生日期', trigger: 'change' }
+        // ],
+        mobile: [
             { required: true, message: '请输入手机号码', trigger: 'blur' },
             { pattern: /^1[3456789]\d{9}$/, message: '手机号格式不正确', trigger: 'blur' }
         ],
-        eee: [
+        qualificationType: [
             { required: true, message: '请输入教练资格类型', trigger: 'blur' }
         ],
-        fff: [
-            { required: true, message: '请选择用户类型', trigger: 'change' }
+        coachDuration: [
+            { required: true, message: '请输入教练时长', trigger: 'blur' }
         ],
-        ggg: [
+        talent: [
             { required: true, message: '请输入教练特长', trigger: 'blur' }
         ],
-        hhh: [
-            { required: true, message: '请输入教练时长', trigger: 'blur' }
+        roleIdList: [
+            { required: true, message: '请选择角色配置', trigger: 'change' }
         ]
     })
     const buttonLoading = ref(false)
+    const userRef = ref(null)
+
+    const handleQuery = () => {
+        queryParams.value.page = 1;
+        getList();
+    }
+
+    const handleAddCoach = () => {
+        reset();
+        userTitle.value = "添加教练";
+        userShow.value = true;
+    }
+
+    const reset = () => {
+        userForm.value = {
+            id:'',
+            realName:'',
+            gender:'',
+            birthdate:'',
+            mobile:'',
+            qualificationType:'',
+            coachDuration:'',
+            talent:'',
+            roleIdList:[],
+            userType:1
+        };
+        proxy.resetForm("userRef");
+    }
+
+    const handleChangeDate = (e) => {
+        userForm.value.birthdate = proxy.parseTime(new Date(e), '{yy}-{mm}-{dd}');
+    }
+
     const submitForm = () => {
         proxy.$refs.userRef.validate((valid) => {
             if (valid) {
                 buttonLoading.value = true;
-                // addOrUpdateUser(userForm.value).then(()=>{
-                //     buttonLoading.value = false;
-                //     userShow.value = false;
-                // })
+                userForm.value.username = userForm.value.mobile;
+                if(userForm.value.id){
+                    updateCoach(userForm.value).then((res)=>{
+                        if(res.code!==0) return proxy.$message.error(res.msg);
+                        buttonLoading.value = false;
+                        userShow.value = false;
+                        getList();
+                    })
+                }else{
+                    addCoach(userForm.value).then((res)=>{
+                        if(res.code!==0) return proxy.$message.error(res.msg);
+                        buttonLoading.value = false;
+                        userShow.value = false;
+                        getList();
+                    })
+                }
             } else {
                 return false;
             }
@@ -176,16 +246,15 @@
     }
     const cancel = () => {
         userShow.value = false;
-        proxy.$refs.userRef.resetFields();
+        reset();
     }
 
-
     const getList = async () => {
         let query = {...queryParams.value};
         loading.value = true;
-        // const res = await listOrder(query);
-        // userList.value = res.data.list;
-        // total.value = res.data.total;
+        const res = await getCoachList(query);
+        userList.value = res.data.list;
+        total.value = res.data.total;
         loading.value = false;
     }
     const handleSizeChange = (e)=>{
@@ -198,32 +267,32 @@
     }
 
     const handleEdit = (row) => {
-        userTitle.value = '编辑用户';
-        Object.keys(row).forEach((key)=>{
-            if (key === 'createTime') {
-                userForm.value[key] = proxy.$moment(row[key]).format('YYYY-MM-DD HH:mm');
-            } else {
-                userForm.value[key] = row[key];
-            }
-        })
-        userShow.value = true;
+        reset();
+        getCoachInfo(row.id).then(response => {
+            userForm.value = response.data;
+            userTitle.value = "编辑教练";
+            userShow.value = true;
+        });
     }
-    const handleDelete = (row) => {
-        proxy.$confirm('是否确认删除该条数据?', '警告', {
-            confirmButtonText: '确定',
-            cancelButtonText: '取消',
-            type: 'warning'
-        }).then(() => {
-            // deleteUser(row.id).then(()=>{
-            //     getList();
-            // })
-        })
+    async function handleDelete(row) {
+        await proxy?.$modal.confirm('确认删除教练【' + row.realName + '】吗?').finally(() => loading.value = false);
+        let res = await deleteCoach([row.id]);
+        if (res.code === 0) proxy?.$modal.msgSuccess("删除成功");
+        else return proxy?.$modal.msgError(res.msg);
+        await getList();
     }
-    const handleStudent = (row) => {
-        
+    
+    const getRoleList = () => {
+      return proxy.$http.get("/sys/role/list").then(({ data: res }) => {
+        if (res.code !== 0) return proxy.$message.error(res.msg);
+        roleList.value = res.data;
+      });
     }
+    onMounted(()=>{
+        getList();
+        getRoleList();
+    })
 
-    getList();
 </script>
 
 <style scoped lang="scss">

+ 3 - 3
src/views/modules/home.vue

@@ -335,7 +335,7 @@
             background: linear-gradient( 270deg, #3C82F6 0%, #3C82F6 100%);
           }
           &.tj2{
-            background: linear-gradient( 270deg, #9D5F94 0%, #904A87 100%);
+            background: linear-gradient( 270deg, #9D5F94 0%, #761E6A 100%);
           }
           &.tj3{
             background: linear-gradient( 90deg, #189B9B 0%, #7DC6C6 100%);
@@ -388,7 +388,7 @@
             cursor: pointer;
             margin-left: 16px;
             &.active{
-              background: #904A87;
+              background: #761E6A;
               color: #FFFFFF;
             }
           }
@@ -414,7 +414,7 @@
           font-family: PingFangSC, PingFang SC;
           font-weight: 400;
           font-size: 14px;
-          color: #833478;
+          color: #761E6A;
           line-height: 20px;
           text-align: right;
           cursor: pointer;