Browse Source

fix:小程序用户管理

lsw 10 months ago
parent
commit
040bdb98d6

+ 68 - 37
admin-ui/src/views/work/user/index.vue

@@ -1,11 +1,11 @@
 <template>
   <div class="app-container">
     <el-form :model="queryParams" ref="queryForm" :inline="true" @submit.native.prevent>
-      <el-form-item label="微信id" prop="openId">
-        <el-input v-model="queryParams.openId" placeholder="请输入微信id"  @keyup.enter.native="handleQuery" clearable class="inp"/>
-      </el-form-item>
-      <el-form-item label="状态" prop="state">
-        <el-input v-model="queryParams.state" placeholder="请输入状态"  @keyup.enter.native="handleQuery" clearable class="inp"/>
+      <el-form-item label="账号状态" prop="state">
+        <el-select v-model="queryParams.state" placeholder="账号状态" class="se" clearable>
+          <el-option value="0" label="正常"></el-option>
+          <el-option value="1" label="禁用"></el-option>
+        </el-select>
       </el-form-item>
       <el-form-item>
         <el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
@@ -13,43 +13,57 @@
       </el-form-item>
     </el-form>
     <el-row :gutter="10" class="mb8">
-        <el-button type="primary" icon="el-icon-plus" :disabled="ids.length > 0" @click="op('add')" v-hasPermi="['work:user:add']">新增</el-button>
-        <el-button type="success" icon="el-icon-edit" :disabled="ids.length != 1" @click="op('edit',ids)" v-hasPermi="['work:user:edit']">修改</el-button>
-        <el-button type="danger" icon="el-icon-delete" :disabled="ids.length == 0" @click="del" v-hasPermi="['work:user:remove']">删除{{ids.length>0?'('+ids.length+')':''}}</el-button>
+      <el-button type="primary" icon="el-icon-plus" :disabled="ids.length > 0" @click="op('add')" v-hasPermi="['work:user:add']">新增</el-button>
+      <el-button type="success" icon="el-icon-edit" :disabled="ids.length != 1" @click="op('edit', ids)" v-hasPermi="['work:user:edit']">修改</el-button>
+      <el-button type="danger" icon="el-icon-delete" :disabled="ids.length == 0" @click="del" v-hasPermi="['work:user:remove']">删除{{ ids.length > 0 ? '(' + ids.length + ')' : '' }}</el-button>
     </el-row>
 
     <el-table :data="response.rows" border @selection-change="selects" height="calc(100vh - 270px)">
       <el-table-column type="selection" width="55" align="center" />
-      <el-table-column label="id" align="center" prop="id" />
-      <el-table-column label="微信id" align="center" prop="openId" />
-      <el-table-column label="状态" align="center" prop="state" />
-      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+      <el-table-column label="微信openId" align="left" prop="openId" />
+      <el-table-column label="绑定就诊人" align="center" width="160">
+        <template slot-scope="scope">
+          <el-tag type="success" v-if="scope.row.patientId">已绑定</el-tag>
+          <el-tag type="danger" v-else>未绑定</el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column label="当前绑定" prop="patientName" align="center" width="160" />
+      <el-table-column label="账号状态" align="center" prop="state" width="110">
+        <template slot-scope="scope">
+          <div class="switch">
+            <el-switch v-model="scope.row.state" :active-value="0" :width="50" :inactive-value="1" @change="op('change', scope.row)"></el-switch>
+            <span class="zc" v-if="scope.row.state == 0" style="left: 22px">正常</span>
+            <span class="ty" v-else style="left: 35px">禁用</span>
+          </div>
+        </template>
+      </el-table-column>
+      <el-table-column label="创建时间" align="center" prop="createTime" width="160" />
+      <el-table-column label="操作" align="center" width="160">
         <template slot-scope="scope">
-          <el-button size="mini" type="text" icon="el-icon-edit" @click="op('edit',scope.row)" v-hasPermi="['work:user:edit']">修改</el-button>
           <el-button size="mini" type="text" icon="el-icon-delete" @click="del(scope.row)" v-hasPermi="['work:user:remove']">删除</el-button>
         </template>
       </el-table-column>
       <template slot="empty">
-          <el-empty></el-empty>
+        <el-empty></el-empty>
       </template>
     </el-table>
-    <pagination v-if="response.total>0" :total="response.total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList"/>
+    <pagination v-if="response.total > 0" :total="response.total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" />
   </div>
 </template>
 
 <script>
-import edit from './edit'
+import edit from './edit';
 export default {
-  name: "User",
+  name: 'User',
   data() {
     return {
       queryParams: {
         pageNum: 1,
         pageSize: 10,
-                      openId: null,
-                      state: null,
-                orderByColumn:'id', //排序字段
-                isAsc: 'desc' //排序方式
+        openId: null,
+        state: null,
+        orderByColumn: 'id', //排序字段
+        isAsc: 'desc' //排序方式
       }
     };
   },
@@ -58,8 +72,8 @@ export default {
   },
   methods: {
     getList() {
-      this.ajax({ url: '/work/user/list', data: this.queryParams }).then(response => {
-            this.response = response;
+      this.ajax({ url: '/work/user/list', data: this.queryParams }).then((response) => {
+        this.response = response;
       });
     },
     handleQuery() {
@@ -67,28 +81,45 @@ export default {
       this.getList();
     },
     resetQuery() {
-      this.resetForm("queryForm");
+      this.resetForm('queryForm');
       this.handleQuery();
     },
     selects(rows) {
-      this.ids = rows.map(item => item.id)
+      this.ids = rows.map((item) => item.id);
     },
     op(tag, row) {
-          if (tag == 'add') {
-            this.iframe({ obj: edit, param: {}, title:'新增',width: '45%', height: '55%'});
-          }
-          if (tag == 'edit') {
-              const id = row.id || this.ids[0];
-              this.iframe({ obj: edit, param: {id: id}, title:'编辑',width: '50%', height: '50%'});
-          }
+      if (tag == 'add') {
+        this.iframe({ obj: edit, param: {}, title: '新增', width: '45%', height: '55%' });
+      }
+      if (tag == 'edit') {
+        const id = row.id || this.ids[0];
+        this.iframe({ obj: edit, param: { id: id }, title: '编辑', width: '50%', height: '50%' });
+      }
+      //账号状态
+      if (tag == 'change') {
+        let text = row.state === 0 ? '启用' : '禁用';
+        this.$confirm('确认要' + text + '该用户吗?', '警告', { type: 'warning' })
+          .then(() => {
+            this.post({ url: '/work/user/edit', data: { id: row.id, state: row.state } })
+              .then((response) => {
+                this.$modal.msgSuccess(text + '成功');
+              })
+              .catch(() => {
+                row.state = row.state === 0 ? 1 : 0;
+              });
+          })
+          .catch(() => {
+            row.state = row.state === 0 ? 1 : 0;
+          });
+      }
     },
     del(row) {
-        this.$confirm('是否确认删除选中数据?', '警告', { type: 'warning' }).then(() => {
-        this.get({ url: '/work/user/remove/' + (row.id || this.ids) }).then(response => {
-                this.$modal.msgSuccess('删除成功');
-                this.getList();
-            });
+      this.$confirm('是否确认删除选中数据?', '警告', { type: 'warning' }).then(() => {
+        this.get({ url: '/work/user/remove/' + (row.id || this.ids) }).then((response) => {
+          this.$modal.msgSuccess('删除成功');
+          this.getList();
         });
+      });
     }
   }
 };

+ 1 - 1
app/App.vue

@@ -30,7 +30,7 @@ button::after {
 /**挂载iconfont字体图标*/
 @font-face {
 	font-family: 'iconfont';
-	src: url('https://at.alicdn.com/t/c/font_4620946_zhmq38l0vzq.ttf?t=1721980812832') format('truetype');
+	src: url('https://at.alicdn.com/t/c/font_4620946_yjys6ggyf8q.ttf?t=1722229086081') format('truetype');
 	/* src: url('~@/static/font/iconfont.ttf') format('truetype'); */
 }
 .icon {

+ 15 - 0
app/common/common.scss

@@ -325,3 +325,18 @@
 		}
 	}
 }
+.bz {
+	font-size: 12px;
+	color: $font-c;
+	margin-top: -5px;
+	.icon {
+		padding-right: 3px;
+	}
+	.contact {
+		background-color: #f1f1f1;
+		float: right;
+		font-size: 13px;
+		color: $main-color;
+		margin-top: -5px;
+	}
+}

+ 18 - 8
app/common/http.js

@@ -13,11 +13,10 @@ const request = (opt) => {
 	opt.header = opt.header || {
 		"Content-Type": opt.contentType,
 		"Authorization": getUser().token ? getUser().token : ''
-
 	};
 	opt.loading = opt.loading || 'true';
-	opt.success = opt.success || function() {};
-	opt.fail = opt.fail || function() {};
+	opt.success = opt.success || function () {};
+	opt.fail = opt.fail || function () {};
 	// console.log("**************************************参数调式***************************************************");
 	// console.log("请求地址:" + opt.url + " 请求参数:" + JSON.stringify(opt.data));
 	// console.log("************************************************************************************************");
@@ -38,11 +37,22 @@ const request = (opt) => {
 				uni.hideLoading();
 			}, 500)
 			/*******************未授权***************************/
-			if (res.data.code === 401) {
-				uni.removeStorageSync('user');
-				uni.navigateTo({
-					url: '/pages/user/login'
-				})
+			if (res.data.code === 401 || res.data.code === 403) {
+				uni.showModal({
+					title: '提示',
+					content: res.data.msg,
+					showCancel: false,
+					success: () => {
+						uni.removeStorageSync('user');
+						if (res.data.code === 401) {
+							uni.navigateTo({
+								url: '/pages/user/login'
+							})
+						}
+						opt.fail();
+						return;
+					}
+				});
 				return;
 			}
 			/*******************系统内部错误***************************/

+ 9 - 1
app/pages/user/bind/add.vue

@@ -4,6 +4,10 @@
 			<view class="lable re">手机号</view>
 			<input type="digit" v-model="item.phone" placeholder="请输入手机号" />
 		</view>
+		<view class="bz">
+			<text class="icon">&#xe627;</text>
+			<text>请输入在医院预留的手机号</text>
+		</view>
 		<button class="btn" @click="add()">确认</button>
 	</view>
 </template>
@@ -38,4 +42,8 @@ export default {
 };
 </script>
 
-<style lang="scss"></style>
+<style lang="scss">
+.btn {
+	margin-top: 35px;
+}
+</style>

+ 1 - 1
app/pages/user/bind/index.vue

@@ -8,7 +8,7 @@
 				</view>
 				<view class="icon del" @click.stop="del(item)">&#xe641;</view>
 			</view>
-			<u-empty v-if="list.length == 0" text="你还未绑定就诊人"></u-empty>
+			<u-empty v-if="list.length == 0" text="请先绑定就诊人"></u-empty>
 		</view>
 		<view class="mfooter">
 			<button class="btn" @click="go('/pages/user/bind/add')">

+ 63 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/work/controller/UserController.java

@@ -0,0 +1,63 @@
+package com.ruoyi.web.work.controller;
+
+import com.ruoyi.common.annotation.Log;
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.core.page.TableDataInfo;
+import com.ruoyi.common.enums.BusinessType;
+import com.ruoyi.web.work.domain.User;
+import com.ruoyi.web.work.service.IUserService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 小程序用户
+ *
+ * @author lsw
+ * @date 2024-07-29
+ */
+@RestController
+@RequestMapping("/work/user")
+public class UserController extends BaseController {
+    @Autowired
+    private IUserService userService;
+
+    @PreAuthorize("@ss.hasPermi('work:user:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(User user) {
+        startPage();
+        List<User> list = userService.selectList(user);
+        return getDataTable(list);
+    }
+
+    @PreAuthorize("@ss.hasPermi('work:user:query')")
+    @GetMapping(value = "/detail/{id}")
+    public AjaxResult detail(@PathVariable("id") Long id) {
+        return AjaxResult.success(userService.getById(id));
+    }
+
+    @PreAuthorize("@ss.hasPermi('work:user:add')")
+    @Log(title = "小程序用户", businessType = BusinessType.INSERT)
+    @PostMapping("/add")
+    public AjaxResult add(@RequestBody User user) {
+        return toAjax(userService.save(user));
+    }
+
+    @PreAuthorize("@ss.hasPermi('work:user:edit')")
+    @Log(title = "小程序用户", businessType = BusinessType.UPDATE)
+    @PostMapping("/enable")
+    public AjaxResult enable(@RequestBody User user) {
+        return userService.enable(user);
+    }
+
+
+    @PreAuthorize("@ss.hasPermi('work:user:remove')")
+    @Log(title = "小程序用户", businessType = BusinessType.DELETE)
+    @GetMapping("/remove/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids) {
+        return userService.remove(ids);
+    }
+}

+ 18 - 1
ruoyi-admin/src/main/java/com/ruoyi/web/work/service/IUserService.java

@@ -13,7 +13,7 @@ import java.util.List;
  * @author lsw
  * @date 2024-07-16LoginDto
  */
-public interface IUserService extends IService<User>{
+public interface IUserService extends IService<User> {
     List<User> selectList(User user);
 
     /**
@@ -42,7 +42,24 @@ public interface IUserService extends IService<User>{
 
     /**
      * 用户详情
+     *
      * @return
      */
     AjaxResult info();
+
+    /**
+     * 启用或停用账户
+     *
+     * @param user
+     * @return
+     */
+    AjaxResult enable(User user);
+
+    /**
+     * 批量删除账户
+     *
+     * @param ids
+     * @return
+     */
+    AjaxResult remove(Long[] ids);
 }

+ 1 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/work/service/impl/BindUserServiceImpl.java

@@ -62,6 +62,7 @@ public class BindUserServiceImpl extends ServiceImpl<BindUserMapper, BindUser> i
             if (!userService.updateById(user)) {
                 throw new ServerException("绑定就诊人失败");
             }
+            tokenService.setLoginUser(user);
         }
         if (!save(bindUser)) {
             throw new ServerException("绑定就诊人失败");

+ 40 - 1
ruoyi-admin/src/main/java/com/ruoyi/web/work/service/impl/UserServiceImpl.java

@@ -3,7 +3,9 @@ package com.ruoyi.web.work.service.impl;
 import com.alibaba.fastjson2.JSON;
 import com.alibaba.fastjson2.JSONObject;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.common.constant.CacheConstants;
 import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.core.redis.RedisCache;
 import com.ruoyi.common.exception.ServiceException;
 import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.common.utils.http.HttpUtils;
@@ -22,6 +24,8 @@ import org.springframework.core.env.Environment;
 import org.springframework.stereotype.Service;
 
 import java.rmi.ServerException;
+import java.util.Arrays;
+import java.util.Collection;
 import java.util.List;
 
 /**
@@ -40,6 +44,9 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IU
     IBindUserService bindUserService;
 
     @Autowired
+    private RedisCache redisCache;
+
+    @Autowired
     private Environment env;
 
     @Override
@@ -95,8 +102,40 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IU
 
     @Override
     public AjaxResult info() {
-        User user =getById(AppUtil.getUser().getId());
+        User user = getById(AppUtil.getUser().getId());
         user.setBindUserList(bindUserService.selectList(new BindUser().setUserId(user.getId())));
         return AjaxResult.success(user);
     }
+
+    @Override
+    public AjaxResult enable(User user) {
+        if (!updateById(user)) {
+            throw new ServiceException("启用或停用账户失败");
+        }
+        if (user.getState() == 1) {
+            deleteCache(user.getId());
+        }
+        return AjaxResult.success();
+    }
+
+    @Override
+    public AjaxResult remove(Long[] ids) {
+        if (!removeByIds(Arrays.asList(ids))) {
+            throw new ServiceException("删除账户失败");
+        }
+        for (Long id : ids) {
+            deleteCache(id);
+        }
+        return AjaxResult.success();
+    }
+
+    private void deleteCache(Long id) {
+        Collection<String> keys = redisCache.keys(CacheConstants.APP_LOGIN_TOKEN_KEY + "*");
+        for (String key : keys) {
+            User loginUser = redisCache.getCacheObject(key);
+            if (loginUser != null && loginUser.getId().equals(id)) {
+                tokenService.delLoginUser(loginUser.getToken());
+            }
+        }
+    }
 }

+ 0 - 2
ruoyi-admin/src/main/resources/mapper/work/UserMapper.xml

@@ -8,8 +8,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         select * from tb_user
         <where>  
             <if test="openId != null  and openId != ''"> and open_id = #{openId}</if>
-            <if test="name != null  and name != ''"> and name like concat('%', #{name}, '%')</if>
-            <if test="avatar != null  and avatar != ''"> and avatar = #{avatar}</if>
             <if test="state != null "> and state = #{state}</if>
         </where>
     </select>