huiqi 2 minggu lalu
induk
melakukan
ed9be37480

+ 1 - 1
.env.development

@@ -1,5 +1,5 @@
 # 页面标题
-VUE_APP_TITLE = 小智权限管理系统
+VUE_APP_TITLE = 建科•小智权限管理系统
 
 # 开发环境配置
 ENV = 'development'

+ 1 - 1
.env.production

@@ -1,5 +1,5 @@
 # 页面标题
-VUE_APP_TITLE = 小智权限管理系统
+VUE_APP_TITLE = 建科•小智权限管理系统
 
 # 生产环境配置
 ENV = 'production'

+ 1 - 1
.env.staging

@@ -1,5 +1,5 @@
 # 页面标题
-VUE_APP_TITLE = 小智权限管理系统
+VUE_APP_TITLE = 建科•小智权限管理系统
 
 NODE_ENV = production
 

+ 2 - 0
.gitignore

@@ -23,3 +23,5 @@ selenium-debug.log
 
 package-lock.json
 yarn.lock
+
+.history

+ 2 - 2
README.md

@@ -2,7 +2,7 @@
 
 ```bash
 # 进入项目目录
-cd chat-ui
+cd chat-auth-web
 
 # 安装依赖
 npm install
@@ -22,6 +22,6 @@ npm run dev
 # 构建测试环境
 npm run build:stage
 
-# 构建生产环境
+# 构建生产环境np
 npm run build:prod
 ```

+ 2 - 2
package.json

@@ -5,8 +5,8 @@
   "author": "建科",
   "license": "MIT",
   "scripts": {
-    "dev": "vue-cli-service serve",
-    "build:prod": "vue-cli-service build",
+    "dev": "export NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve",
+    "build:prod": "export NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service build",
     "build:stage": "vue-cli-service build --mode staging",
     "preview": "node build/index.js --preview",
     "lint": "eslint --ext .js,.vue src"

+ 25 - 11
src/layout/components/Navbar.vue

@@ -7,19 +7,20 @@
 
     <div class="right-menu">
       <template v-if="device!=='mobile'">
-        <search id="header-search" class="right-menu-item" />
 
-        <screenfull id="screenfull" class="right-menu-item hover-effect" />
 
-        <el-tooltip content="布局大小" effect="dark" placement="bottom">
+        <!-- <screenfull id="screenfull" class="right-menu-item hover-effect" /> -->
+
+        <!-- <el-tooltip content="布局大小" effect="dark" placement="bottom">
           <size-select id="size-select" class="right-menu-item hover-effect" />
-        </el-tooltip>
+        </el-tooltip> -->
 
       </template>
 
       <el-dropdown class="avatar-container right-menu-item hover-effect" trigger="click">
         <div class="avatar-wrapper">
-          <img :src="avatar" class="user-avatar">
+          <span class="user-name">{{ name }}</span>
+          <el-avatar class="user-avatar" icon="el-icon-user"></el-avatar>
           <i class="el-icon-caret-bottom" />
         </div>
         <el-dropdown-menu slot="dropdown">
@@ -44,23 +45,22 @@ import Breadcrumb from '@/components/Breadcrumb'
 import TopNav from '@/components/TopNav'
 import Hamburger from '@/components/Hamburger'
 import Screenfull from '@/components/Screenfull'
-import SizeSelect from '@/components/SizeSelect'
-import Search from '@/components/HeaderSearch'
+
+
 
 export default {
   components: {
     Breadcrumb,
     TopNav,
     Hamburger,
-    Screenfull,
-    SizeSelect,
-    Search
+    Screenfull
   },
   computed: {
     ...mapGetters([
       'sidebar',
       'avatar',
-      'device'
+      'device',
+      'name'
     ]),
     setting: {
       get() {
@@ -166,6 +166,8 @@ export default {
       .avatar-wrapper {
         margin-top: 5px;
         position: relative;
+        display: inline-flex;
+        align-items: center;
 
         .user-avatar {
           cursor: pointer;
@@ -174,6 +176,18 @@ export default {
           border-radius: 10px;
         }
 
+        .user-name {
+          margin-right: 10px;
+          font-size: 14px;
+          color: #606266;
+          line-height: 1;
+          max-width: 120px;
+          display: inline-block;
+          white-space: nowrap;
+          overflow: hidden;
+          text-overflow: ellipsis;
+        }
+
         .el-icon-caret-bottom {
           cursor: pointer;
           position: absolute;

+ 1 - 1
src/views/index.vue

@@ -1,5 +1,5 @@
 <template>
-  <div style="margin: 20px;">小智权限管理系统</div>
+  <div style="margin: 20px;">建科•小智权限管理系统</div>
   <!-- <div class="dashboard-editor-container">
 
     <panel-group @handleSetLineChartData="handleSetLineChartData" />

+ 1 - 1
src/views/login.vue

@@ -1,7 +1,7 @@
 <template>
   <div class="login">
     <el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form">
-      <h2 class="title" >小智权限管理系统</h2>
+      <h2 class="title" >建科•小智权限管理系统</h2>
       <el-form-item prop="userName">
         <el-input
           v-model="loginForm.userName"

+ 1 - 1
src/views/register.vue

@@ -1,7 +1,7 @@
 <template>
   <div class="register">
     <el-form ref="registerForm" :model="registerForm" :rules="registerRules" class="register-form">
-      <h3 class="title">小智权限管理系统</h3>
+      <h3 class="title">建科•小智权限管理系统</h3>
       <el-form-item prop="username">
         <el-input v-model="registerForm.username" type="text" auto-complete="off" placeholder="账号">
           <svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon" />

+ 145 - 7
src/views/system/project/index.vue

@@ -1,12 +1,23 @@
 <template>
   <div class="app-container">
     <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="项目来源" prop="sourceFrom">
+        <el-select v-model="queryParams.sourceFrom" placeholder="请选择项目来源" clearable filterable @change="handleQuery">
+          <el-option
+            v-for="item in projectSourceList"
+            :key="item.dictCode || item.dictValue || item.value"
+            :label="item.dictLabel || item.label"
+            :value="item.dictValue || item.value"
+          />
+        </el-select>
+      </el-form-item>
       <el-form-item label="项目编号" prop="projectPid">
         <el-input v-model="queryParams.projectPid" placeholder="请输入项目编号" clearable @keyup.enter.native="handleQuery" />
       </el-form-item>
       <el-form-item label="项目名称" prop="projectName">
         <el-input v-model="queryParams.projectName" placeholder="请输入项目名称" clearable @keyup.enter.native="handleQuery" />
       </el-form-item>
+
       <!-- <el-form-item label="应用名称" prop="appId">
         <el-select v-model="queryParams.appId">
           <el-option
@@ -52,17 +63,40 @@
 
     <el-table v-loading="loading" :data="projectList" @selection-change="handleSelectionChange">
       <el-table-column type="selection" width="55" align="center" />
-      <el-table-column label="来源" align="center" prop="sourceFromName" />
-      <el-table-column label="项目编号" align="center" prop="projectPid" />
-      <el-table-column label="项目名称" align="center" prop="projectName" />
+      <el-table-column label="项目来源" width="90" align="center" prop="sourceFromName" />
+      <el-table-column label="项目编号" align="center" prop="projectPid" min-width="90">
+        <template slot-scope="scope">
+          <el-tooltip placement="top" popper-class="pid-tooltip">
+            <div slot="content" class="pid-tooltip-content">{{ scope.row.projectPid }}</div>
+            <span class="pid-ellipsis">{{ scope.row.projectPid }}</span>
+          </el-tooltip>
+        </template>
+      </el-table-column>
+      <el-table-column label="项目名称" align="center" prop="projectName" min-width="320">
+        <template slot-scope="scope">
+          <el-tooltip placement="top" popper-class="pid-tooltip">
+            <div slot="content" class="pid-tooltip-content">{{ scope.row.projectName }}</div>
+            <span class="name-ellipsis">{{ scope.row.projectName }}</span>
+          </el-tooltip>
+        </template>
+      </el-table-column>
       <!-- <el-table-column label="应用名称" align="center" prop="name" /> -->
-      <el-table-column label="应用名称" align="center">
+      <el-table-column label="应用名称" align="center" min-width="360">
         <template slot-scope="scope">
-          <div v-for="item in scope.row.name" :key="item">{{ item }}</div>
+          <div class="app-tags">
+            <el-tag
+              v-for="item in (scope.row.name || [])"
+              :key="item"
+              size="mini"
+              effect="plain"
+              :class="['app-tag', getTagColorClass(item)]"
+              disable-transitions
+            >{{ item }}</el-tag>
+          </div>
         </template>
       </el-table-column>
-      <el-table-column label="创建时间" align="center" prop="createTime" />
-      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+      <el-table-column label="项目创建时间" width="160" align="center" prop="createTime" />
+      <el-table-column label="操作" width="180" align="center" class-name="small-padding fixed-width">
         <template slot-scope="scope">
           <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
             v-hasPermi="['system:project:edit']">修改</el-button>
@@ -138,9 +172,11 @@ export default {
         projectPid: null,
         projectName: null,
         appId: null,
+        sourceFrom: null,
       },
       appList: [],
       projectTypeList: [],
+      projectSourceList: [],
       // 表单参数
       form: {},
       // 表单校验
@@ -158,6 +194,7 @@ export default {
     this.getList();
     this.getAppList();
     this.getProjectTypeList();
+    this.getProjectSourceList();
   },
   methods: {
     /** 查询项目列表 */
@@ -175,6 +212,14 @@ export default {
         this.projectTypeList = response.data;
       });
     },
+    getProjectSourceList() {
+      // 假设后端提供字典类型 project_source
+      getDicts('project_source').then(response => {
+        this.projectSourceList = response.data || [];
+      }).catch(() => {
+        this.projectSourceList = [];
+      });
+    },
     // 取消按钮
     cancel() {
       this.open = false;
@@ -276,6 +321,99 @@ export default {
         reject(error)
       })
     },
+    // 根据名称生成稳定的颜色 class
+    getTagColorClass(name) {
+      if (!name) return 'tag-color-0'
+      let hash = 0
+      for (let i = 0; i < name.length; i++) {
+        hash = ((hash << 5) - hash) + name.charCodeAt(i)
+        hash |= 0
+      }
+      const idx = Math.abs(hash) % 6
+      return `tag-color-${idx}`
+    },
   }
 };
 </script>
+
+<style>
+.pid-ellipsis {
+  display: inline-block;
+  max-width: 100%;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  vertical-align: middle;
+}
+/* Project name ellipsis behavior consistent with pid */
+.name-ellipsis {
+  display: inline-block;
+  max-width: 100%;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  vertical-align: middle;
+}
+/* App names single-line ellipsis inside flexible column */
+.app-ellipsis {
+  display: inline;
+  max-width: 100%;
+  white-space: normal;
+  word-break: break-all;
+  overflow: visible;
+  text-overflow: clip;
+  vertical-align: middle;
+}
+/* App name tags container: wrap to next line automatically */
+.app-tags {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 4px 6px;
+  justify-content: center;
+}
+.app-tag {
+  margin: 0; /* use gap instead */
+}
+/* Tag color variants */
+.app-tag.tag-color-0 {
+  color: #409EFF;
+  background-color: rgba(64, 158, 255, 0.08);
+  border-color: rgba(64, 158, 255, 0.35);
+}
+.app-tag.tag-color-1 {
+  color: #67C23A;
+  background-color: rgba(103, 194, 58, 0.08);
+  border-color: rgba(103, 194, 58, 0.35);
+}
+.app-tag.tag-color-2 {
+  color: #E6A23C;
+  background-color: rgba(230, 162, 60, 0.08);
+  border-color: rgba(230, 162, 60, 0.35);
+}
+.app-tag.tag-color-3 {
+  color: #F56C6C;
+  background-color: rgba(245, 108, 108, 0.08);
+  border-color: rgba(245, 108, 108, 0.35);
+}
+.app-tag.tag-color-4 {
+  color: #8A5CF6;
+  background-color: rgba(138, 92, 246, 0.08);
+  border-color: rgba(138, 92, 246, 0.35);
+}
+.app-tag.tag-color-5 {
+  color: #13C2C2;
+  background-color: rgba(19, 194, 194, 0.08);
+  border-color: rgba(19, 194, 194, 0.35);
+}
+/* Tooltip content selectable and readable */
+.pid-tooltip {
+  max-width: 640px;
+  user-select: text;
+  word-break: break-all;
+}
+.pid-tooltip .pid-tooltip-content {
+  font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;
+  font-size: 12px;
+  line-height: 1.5;
+}
+</style>

+ 53 - 3
src/views/system/staff/index.vue

@@ -20,7 +20,7 @@
           <el-option v-for="itemR in roleList" :key="itemR.roleId" :label="itemR.roleName" :value="itemR.roleId" />
         </el-select>
       </el-form-item> -->
-      <el-form-item label="进入项目日期" prop="mBdate">
+      <!-- <el-form-item label="进入项目日期" prop="mBdate">
         <el-date-picker clearable v-model="queryParams.mBdate" type="date" value-format="yyyy-MM-dd"
           placeholder="请选择进入项目日期">
         </el-date-picker>
@@ -29,7 +29,7 @@
         <el-date-picker clearable v-model="queryParams.mEdate" type="date" value-format="yyyy-MM-dd"
           placeholder="请选择撤出项目日期">
         </el-date-picker>
-      </el-form-item>
+      </el-form-item> -->
       <el-form-item>
         <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
         <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
@@ -73,6 +73,25 @@
       <el-table-column label="成员类型" align="center" prop="userTypeName" />
       <el-table-column label="系统角色" align="center" prop="roleName" />
       <el-table-column label="创建日期" align="center" prop="createTime" />
+      <el-table-column label="进入项目日期" align="center" prop="mBdate" width="180" />
+      <el-table-column label="项目编号" align="center" prop="projectPid" min-width="90" >
+        <template slot-scope="scope">
+          <el-tooltip placement="top" popper-class="pid-tooltip">
+            <div slot="content" class="pid-tooltip-content">{{ scope.row.projectPid }}</div>
+            <span class="pid-ellipsis">{{ scope.row.projectPid }}</span>
+          </el-tooltip>
+        </template>
+      </el-table-column>
+      <el-table-column label="项目名称" align="center" prop="projectName" min-width="320">
+        <template slot-scope="scope">
+          <el-tooltip placement="top" popper-class="pid-tooltip">
+            <div slot="content" class="pid-tooltip-content">{{ scope.row.projectName }}</div>
+            <span class="name-ellipsis">{{ scope.row.projectName }}</span>
+          </el-tooltip>
+        </template>
+      </el-table-column>
+      <el-table-column label="用户名称" align="center" prop="userName" />
+      <!-- <el-table-column label="角色" align="center" prop="roleName" /> -->
       <el-table-column label="进入项目日期" align="center" prop="mBdate" width="180">
         <template slot-scope="scope">
           <span>{{ parseTime(scope.row.mBdate, '{y}-{m}-{d}') }}</span>
@@ -115,6 +134,8 @@
               :value="itemU.userId.toString()" />
           </el-select>
         </el-form-item>
+
+        <!-- <el-form-item label="进入项目日期" prop="mBdate">-->
 <!--        <el-form-item label="角色" prop="roleId">-->
 <!--          <el-select v-model="form.roleId"-->
 <!--                     filterable-->
@@ -125,7 +146,7 @@
         <el-form-item label="进入项目日期" prop="mBdate">
           <el-date-picker clearable v-model="form.mBdate" type="date" value-format="yyyy-MM-dd" placeholder="请选择进入项目日期">
           </el-date-picker>
-        </el-form-item>
+        </el-form-item> -->
         <el-form-item label="撤出项目日期" prop="mEdate">
           <el-date-picker clearable v-model="form.mEdate" type="date" value-format="yyyy-MM-dd" placeholder="请选择撤出项目日期">
           </el-date-picker>
@@ -406,3 +427,32 @@ export default {
   }
 };
 </script>
+
+<style>
+.pid-ellipsis {
+  display: inline-block;
+  max-width: 100%;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  vertical-align: middle;
+}
+.name-ellipsis {
+  display: inline-block;
+  max-width: 100%;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  vertical-align: middle;
+}
+.pid-tooltip {
+  max-width: 640px;
+  user-select: text;
+  word-break: break-all;
+}
+.pid-tooltip .pid-tooltip-content {
+  font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;
+  font-size: 12px;
+  line-height: 1.5;
+}
+</style>

+ 6 - 52
src/views/system/user/profile/userAvatar.vue

@@ -1,55 +1,9 @@
 <template>
   <div>
-    <div class="user-info-head" @click="editCropper()"><img v-bind:src="options.img" title="点击上传头像" class="img-circle img-lg" /></div>
-    <el-dialog :title="title" :visible.sync="open" width="800px" append-to-body @opened="modalOpened"  @close="closeDialog">
-      <el-row>
-        <el-col :xs="24" :md="12" :style="{height: '350px'}">
-          <vue-cropper
-            ref="cropper"
-            :img="options.img"
-            :info="true"
-            :autoCrop="options.autoCrop"
-            :autoCropWidth="options.autoCropWidth"
-            :autoCropHeight="options.autoCropHeight"
-            :fixedBox="options.fixedBox"
-            :outputType="options.outputType"
-            @realTime="realTime"
-            v-if="visible"
-          />
-        </el-col>
-        <el-col :xs="24" :md="12" :style="{height: '350px'}">
-          <div class="avatar-upload-preview">
-            <img :src="previews.url" :style="previews.img" />
-          </div>
-        </el-col>
-      </el-row>
-      <br />
-      <el-row>
-        <el-col :lg="2" :sm="3" :xs="3">
-          <el-upload action="#" :http-request="requestUpload" :show-file-list="false" :before-upload="beforeUpload">
-            <el-button size="small">
-              选择
-              <i class="el-icon-upload el-icon--right"></i>
-            </el-button>
-          </el-upload>
-        </el-col>
-        <el-col :lg="{span: 1, offset: 2}" :sm="2" :xs="2">
-          <el-button icon="el-icon-plus" size="small" @click="changeScale(1)"></el-button>
-        </el-col>
-        <el-col :lg="{span: 1, offset: 1}" :sm="2" :xs="2">
-          <el-button icon="el-icon-minus" size="small" @click="changeScale(-1)"></el-button>
-        </el-col>
-        <el-col :lg="{span: 1, offset: 1}" :sm="2" :xs="2">
-          <el-button icon="el-icon-refresh-left" size="small" @click="rotateLeft()"></el-button>
-        </el-col>
-        <el-col :lg="{span: 1, offset: 1}" :sm="2" :xs="2">
-          <el-button icon="el-icon-refresh-right" size="small" @click="rotateRight()"></el-button>
-        </el-col>
-        <el-col :lg="{span: 2, offset: 6}" :sm="2" :xs="2">
-          <el-button type="primary" size="small" @click="uploadImg()">提 交</el-button>
-        </el-col>
-      </el-row>
-    </el-dialog>
+    <div class="user-info-head"><el-avatar icon="el-icon-user" class="img-circle img-lg"></el-avatar></div>
+    <!-- <el-dialog :title="title" :visible.sync="open" width="800px" append-to-body @opened="modalOpened"  @close="closeDialog"> -->
+      <!-- Upload/Crop dialog disabled -->
+    <!-- </el-dialog> -->
   </div>
 </template>
 
@@ -167,7 +121,7 @@ export default {
   height: 120px;
 }
 
-.user-info-head:hover:after {
+/* .user-info-head:hover:after {
   content: '+';
   position: absolute;
   left: 0;
@@ -183,5 +137,5 @@ export default {
   cursor: pointer;
   line-height: 110px;
   border-radius: 50%;
-}
+} */
 </style>

+ 1 - 1
vue.config.js

@@ -39,7 +39,7 @@ module.exports = {
     proxy: {
       // detail: https://cli.vuejs.org/config/#devserver-proxy
       [process.env.VUE_APP_BASE_API]: {
-        target: `http://localhost:8090`,
+        target: `http://192.168.3.3:8091`,
         changeOrigin: true,
         pathRewrite: {
           ['^' + process.env.VUE_APP_BASE_API]: ''