定制开发小程序基于Java+SpringBoot+vue+elementui药品商城采购系统详细设计实现

博主介绍全网粉丝20W+,csdn特邀作者、博客专家、CSDN定制开发小程序新星计划导师、java定制开发小程序领域优质创作者,博客之星TOP100、掘金/华为云/阿里云/InfoQ定制开发小程序等平台优质作者、专注于Java定制开发小程序技术领域和毕业设计项目实战

🍅定制开发小程序文末获取联系🍅

定制开发小程序精彩专栏推荐👇🏻👇🏻👇🏻👇🏻

目录


一、前言介绍:

         定制开发小程序随着社会的发展,定制开发小程序社会的各行各业都在利定制开发小程序用信息化时代的优势。定制开发小程序计算机的优势和普及使定制开发小程序得各种信息系统的开发成为必需。定制开发小程序医院药品管理系统,定制开发小程序主要的模块包括首页、个人中心、用户管理、员工管理、定制开发小程序供应商管理、定制开发小程序药品种类管理、定制开发小程序药品信息管理、定制开发小程序药品入库管理、定制开发小程序药品出库管理、药品采购管理、系统管理、订单管理等功能。系统中管理员主要是为了安全有效地存储和管理各类信息,还可以对系统进行管理与更新维护等操作,并且对后台有相应的操作权限。

要想实现医院药品管理系统的各项功能,需要后台数据库的大力支持。管理员验证注册信息,收集的信息,并由此分析得出的关联信息等大量的数据都由数据库管理。本文中数据库服务器端采用了Mysql作为后台数据库,使Web与数据库紧密联系起来。在设计过程中,充分保证了系统代码的良好可读性、实用性、易扩展性、通用性、便于后期维护、操作方便以及列表页面简洁等特点。

本系统的开发使获取医院药品管理系统信息能够更加方便快捷,同时也使药品管理变的更加系统化、有序化。系统界面较友好,易于操作。

二、系统设计:

2.1 系统设计原则:

本医院药品管理系统采用Java技术,Mysql数据库开发,充分保证了系统稳定性、完整性。

医院药品管理系统设计与实现的设计思路如下:

1.操作简单方便,页面布局简单清晰、界面安全良好:,便于查询医院药品的相关信息。

2.即时可视性:医院药品管理系统的信息处理将在相应的位置即时可用,以实现“即时发布、即时生效”的系统功能。

功能完善:可管理主页、个人中心、用户管理、员工管理、供应商管理、药品类别管理、药品信息管理、药品仓储管理、药品出库管理、药品采购管理、系统管理、订单管理等模块的修改和维护。

2.2 系统结构设计:

系统架构图属于系统设计阶段,系统架构图只是这个阶段一个产物,系统的总体架构决定了整个系统的模式,是系统的基础。医院药品管理系统的整体结构设计如图所示

三、数据设计:

3.1 数据实体ER设计:

药品信息实体属性图,如图所示:

 订单实体属性图,如图所示

 供应商实体属性图如图所示

3.2 数据逻辑结构设计:

 逻辑结构设计是把概念结构设计阶段画好的数据库ER图转换为关系模型。该系统的关系模型的逻辑结构是由主要一下关系模式组成,具体的字段设计如下:

(1 药品资讯 ) 主键,创建时间,标题,简介,图片信息,内容
(2 员工信息 ) 主键,创建时间,员工工号,用户密码,员工用户姓名,性别,头像信息,手机号码,身份证,余额
(3 供应商信息 ) 主键,创建时间,供应商编号,供应商名称,联系人,联系方式,供应商地址,备注
(4 用户信息 ) 主键,创建时间,用户名,用户密码,用户姓名,头像信息,性别,联系方式,余额
(5 评论信息 ) 主键,创建时间,关联表id,用户id,用户名,评论内容,回复内容
(6 药品信息 ) 主键,创建时间,药品名称,药品种类,图片信息,规格信息,厂家信息,有效日期,数量,药品详情,最近点击时间,点击次数,药品价格
(7 配置信息 ) 主键,配置参数名称,配置参数值
(8 药品入库信息 ) 主键,创建时间,入库单号,药品名称,药品种类,规格信息,厂家信息,数量,备注,入库时间,员工工号,员工用户姓名
(9 药品种类信息 ) 主键,创建时间,药品种类
(10 提问信息 ) 主键,创建时间,用户id,管理员id,提问,回复,是否回复
(11 药品出库信息 ) 主键,创建时间,药品名称,药品种类,规格信息,厂家信息,数量,备注,出库日期,员工工号,员工用户姓名
(12 药品购物车信息 )   主键,创建时间,商品表名,用户id,商品id,药品名称,图片信息,购买数量,单价,会员价
(13 药品采购信息 )  主键,创建时间,供应商编号,供应商名称,采购单号,药品名称,药品种类,厂家信息,规格信息,数量,采购的单价,采购金额,备注,采购日期,员工工号,员工用户姓名,是否审核,审核回复
(14 收货信息 )   主键,创建时间,用户id,地址,收货人,电话,是否默认地址[是/否]
(15 用户信息 )  主键,用户名,用户密码,角色,新增时间
(16 token信息 )   主键,用户id,用户名,表名,角色,用户密码,新增时间,过期时间
(17 收藏信息 )  主键,创建时间,用户id,收藏id,表名,收藏名称,收藏图片信息,类型(1:收藏,21:赞,22:踩),推荐类型
(18 订单信息 )  主键,创建时间,订单编号,商品表名,用户id,商品id,药品名称,商品图片信息,购买数量,药品价格,折扣药品价格,总药品价格,折扣总药品价格,支付方式,状态,地址,电话,收货人,物流

四、功能截图: 

4.1 用户登录注册:

4.2 用户前端首页:

首页模块:

药品信息模块:

药品资讯模块:

 

个人中心模块:

 

购物车模块:

在线客服模块: 

4.3 用户后端管理:

个人中心管理:

4.4 供应商后端管理:

供应商管理:

药品信息管理:

4.5 管理员后端管理:

用户模块管理:

供应商管理:

药品类型管理:

药品信息管理:

药品出入库管理:

药品采购管理:

药品资讯管理:

系统设置管理:

药品订单管理:

五、代码实现:

5.1 用户登录模块:

  1. <template>
  2. <div>
  3. <div class="container loginIn" style="backgroundImage: url(http://localhost:8080/springboot581jv/upload/login_bgyp.jpg)">
  4. <div :class="2 == 1 ? 'left' : 2 == 2 ? 'left center' : 'left right'" style="backgroundColor: rgba(237, 237, 237, 0.17)">
  5. <el-form class="login-form" label-position="left" :label-width="1 == 3 ? '56px' : '0px'">
  6. <div class="title-container"><h3 class="title" style="color: rgba(25, 169, 123, 1)">药品管理系统登录</h3></div>
  7. <el-form-item :label="1 == 3 ? '用户名' : ''" :class="'style'+1">
  8. <span v-if="1 != 3" class="svg-container" style="color:rgba(136, 154, 164, 1);line-height:44px"><svg-icon icon-class="user" /></span>
  9. <el-input placeholder="请输入用户名" name="username" type="text" v-model="rulesForm.username" />
  10. </el-form-item>
  11. <el-form-item :label="1 == 3 ? '密码' : ''" :class="'style'+1">
  12. <span v-if="1 != 3" class="svg-container" style="color:rgba(136, 154, 164, 1);line-height:44px"><svg-icon icon-class="password" /></span>
  13. <el-input placeholder="请输入密码" name="password" type="password" v-model="rulesForm.password" />
  14. </el-form-item>
  15. <el-form-item v-if="0 == '1'" class="code" :label="1 == 3 ? '验证码' : ''" :class="'style'+1">
  16. <span v-if="1 != 3" class="svg-container" style="color:rgba(136, 154, 164, 1);line-height:44px"><svg-icon icon-class="code" /></span>
  17. <el-input placeholder="请输入验证码" name="code" type="text" v-model="rulesForm.code" />
  18. <div class="getCodeBt" @click="getRandCode(4)" style="height:44px;line-height:44px">
  19. <span v-for="(item, index) in codes" :key="index" :style="{color:item.color,transform:item.rotate,fontSize:item.size}">{{ item.num }}</span>
  20. </div>
  21. </el-form-item>
  22. <el-form-item label="角色" prop="loginInRole" class="role">
  23. <el-radio
  24. v-for="item in menus"
  25. v-if="item.hasBackLogin=='是'"
  26. v-bind:key="item.roleName"
  27. v-model="rulesForm.role"
  28. :label="item.roleName"
  29. >{{item.roleName}}</el-radio>
  30. </el-form-item>
  31. <el-button type="primary" @click="login()" class="loginInBt" style="padding:0;font-size:16px;border-radius:4px;height:44px;line-height:44px;width:100%;backgroundColor:rgba(25, 169, 123, 1); borderColor:rgba(25, 169, 123, 1); color:rgba(255, 255, 255, 1)">{{'1' == '1' ? '登录' : 'login'}}</el-button>
  32. <el-form-item class="setting">
  33. <!-- <div style="color:rgba(25, 169, 123, 1)" class="reset">修改密码</div> -->
  34. </el-form-item>
  35. </el-form>
  36. </div>
  37. </div>
  38. </div>
  39. </template>
  40. <script>
  41. import menu from "@/utils/menu";
  42. export default {
  43. data() {
  44. return {
  45. rulesForm: {
  46. username: "",
  47. password: "",
  48. role: "",
  49. code: '',
  50. },
  51. menus: [],
  52. tableName: "",
  53. codes: [{
  54. num: 1,
  55. color: '#000',
  56. rotate: '10deg',
  57. size: '16px'
  58. },{
  59. num: 2,
  60. color: '#000',
  61. rotate: '10deg',
  62. size: '16px'
  63. },{
  64. num: 3,
  65. color: '#000',
  66. rotate: '10deg',
  67. size: '16px'
  68. },{
  69. num: 4,
  70. color: '#000',
  71. rotate: '10deg',
  72. size: '16px'
  73. }],
  74. };
  75. },
  76. mounted() {
  77. let menus = menu.list();
  78. this.menus = menus;
  79. },
  80. created() {
  81. this.setInputColor()
  82. this.getRandCode()
  83. },
  84. methods: {
  85. setInputColor(){
  86. this.$nextTick(()=>{
  87. document.querySelectorAll('.loginIn .el-input__inner').forEach(el=>{
  88. el.style.backgroundColor = "rgba(255, 255, 255, 1)"
  89. el.style.color = "rgba(25, 169, 123, 1)"
  90. el.style.height = "44px"
  91. el.style.lineHeight = "44px"
  92. el.style.borderRadius = "4px"
  93. })
  94. document.querySelectorAll('.loginIn .style3 .el-form-item__label').forEach(el=>{
  95. el.style.height = "44px"
  96. el.style.lineHeight = "44px"
  97. })
  98. document.querySelectorAll('.loginIn .el-form-item__label').forEach(el=>{
  99. el.style.color = "rgba(136, 154, 164, 1)"
  100. })
  101. setTimeout(()=>{
  102. document.querySelectorAll('.loginIn .role .el-radio__label').forEach(el=>{
  103. el.style.color = "#fff"
  104. })
  105. },350)
  106. })
  107. },
  108. register(tableName){
  109. this.$storage.set("loginTable", tableName);
  110. this.$router.push({path:'/register'})
  111. },
  112. // 登陆
  113. login() {
  114. let code = ''
  115. for(let i in this.codes) {
  116. code += this.codes[i].num
  117. }
  118. if ('0' == '1' && !this.rulesForm.code) {
  119. this.$message.error("请输入验证码");
  120. return;
  121. }
  122. if ('0' == '1' && this.rulesForm.code.toLowerCase() != code.toLowerCase()) {
  123. this.$message.error("验证码输入有误");
  124. this.getRandCode()
  125. return;
  126. }
  127. if (!this.rulesForm.username) {
  128. this.$message.error("请输入用户名");
  129. return;
  130. }
  131. if (!this.rulesForm.password) {
  132. this.$message.error("请输入密码");
  133. return;
  134. }
  135. if (!this.rulesForm.role) {
  136. this.$message.error("请选择角色");
  137. return;
  138. }
  139. let menus = this.menus;
  140. for (let i = 0; i < menus.length; i++) {
  141. if (menus[i].roleName == this.rulesForm.role) {
  142. this.tableName = menus[i].tableName;
  143. }
  144. }
  145. this.$http({
  146. url: `${this.tableName}/login?username=${this.rulesForm.username}&password=${this.rulesForm.password}`,
  147. method: "post"
  148. }).then(({ data }) => {
  149. if (data && data.code === 0) {
  150. this.$storage.set("Token", data.token);
  151. this.$storage.set("role", this.rulesForm.role);
  152. this.$storage.set("sessionTable", this.tableName);
  153. this.$storage.set("adminName", this.rulesForm.username);
  154. this.$router.replace({ path: "/index/" });
  155. } else {
  156. this.$message.error(data.msg);
  157. }
  158. });
  159. },
  160. getRandCode(len = 4){
  161. this.randomString(len)
  162. },
  163. randomString(len = 4) {
  164. let chars = [
  165. "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k",
  166. "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v",
  167. "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G",
  168. "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R",
  169. "S", "T", "U", "V", "W", "X", "Y", "Z", "0", "1", "2",
  170. "3", "4", "5", "6", "7", "8", "9"
  171. ]
  172. let colors = ["0", "1", "2","3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"]
  173. let sizes = ['14', '15', '16', '17', '18']
  174. let output = [];
  175. for (let i = 0; i < len; i++) {
  176. // 随机验证码
  177. let key = Math.floor(Math.random()*chars.length)
  178. this.codes[i].num = chars[key]
  179. // 随机验证码颜色
  180. let code = '#'
  181. for (let j = 0; j < 6; j++) {
  182. let key = Math.floor(Math.random()*colors.length)
  183. code += colors[key]
  184. }
  185. this.codes[i].color = code
  186. // 随机验证码方向
  187. let rotate = Math.floor(Math.random()*60)
  188. let plus = Math.floor(Math.random()*2)
  189. if(plus == 1) rotate = '-'+rotate
  190. this.codes[i].rotate = 'rotate('+rotate+'deg)'
  191. // 随机验证码字体大小
  192. let size = Math.floor(Math.random()*sizes.length)
  193. this.codes[i].size = sizes[size]+'px'
  194. }
  195. },
  196. }
  197. };
  198. </script>

5.2 文件上传模块:

  1. /**
  2. * 上传文件
  3. */
  4. @Async
  5. @RequestMapping("/upload")
  6. public R upload(@RequestParam("file") MultipartFile file,String type) throws Exception {
  7. if (file.isEmpty()) {
  8. throw new EIException("上传文件不能为空");
  9. }
  10. String fileExt = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")+1);
  11. File upload = new File("D:/work/");
  12. if(!upload.exists()) {
  13. upload.mkdirs();
  14. }
  15. String fileName = new Date().getTime()+"."+fileExt;
  16. File dest = new File(upload+"/"+fileName);
  17. file.transferTo(dest);
  18. if(StringUtils.isNotBlank(type) && type.equals("1")) {
  19. ConfigEntity configEntity = configService.selectOne(new EntityWrapper<ConfigEntity>().eq("name", "faceFile"));
  20. if(configEntity==null) {
  21. configEntity = new ConfigEntity();
  22. configEntity.setName("faceFile");
  23. configEntity.setValue(fileName);
  24. } else {
  25. configEntity.setValue(fileName);
  26. }
  27. configService.insertOrUpdate(configEntity);
  28. }
  29. return R.ok().put("file", fileName);
  30. }

5.3 药品采购模块:

  1. /**
  2. * 药品采购
  3. * 后端接口
  4. * @author
  5. * @email
  6. * @date 2022-03-28 20:09:08
  7. */
  8. @RestController
  9. @RequestMapping("/yaopincaigou")
  10. public class YaopincaigouController {
  11. @Autowired
  12. private YaopincaigouService yaopincaigouService;
  13. /**
  14. * 后端列表
  15. */
  16. @RequestMapping("/page")
  17. public R page(@RequestParam Map<String, Object> params,YaopincaigouEntity yaopincaigou,
  18. HttpServletRequest request){
  19. String tableName = request.getSession().getAttribute("tableName").toString();
  20. if(tableName.equals("yuangong")) {
  21. yaopincaigou.setYuangonggonghao((String)request.getSession().getAttribute("username"));
  22. }
  23. EntityWrapper<YaopincaigouEntity> ew = new EntityWrapper<YaopincaigouEntity>();
  24. PageUtils page = yaopincaigouService.queryPage(params, MPUtil.sort(MPUtil.between(MPUtil.likeOrEq(ew, yaopincaigou), params), params));
  25. return R.ok().put("data", page);
  26. }
  27. /**
  28. * 前端列表
  29. */
  30. @RequestMapping("/list")
  31. public R list(@RequestParam Map<String, Object> params,YaopincaigouEntity yaopincaigou, HttpServletRequest request){
  32. EntityWrapper<YaopincaigouEntity> ew = new EntityWrapper<YaopincaigouEntity>();
  33. PageUtils page = yaopincaigouService.queryPage(params, MPUtil.sort(MPUtil.between(MPUtil.likeOrEq(ew, yaopincaigou), params), params));
  34. return R.ok().put("data", page);
  35. }
  36. /**
  37. * 查询
  38. */
  39. @RequestMapping("/query")
  40. public R query(YaopincaigouEntity yaopincaigou){
  41. EntityWrapper< YaopincaigouEntity> ew = new EntityWrapper< YaopincaigouEntity>();
  42. ew.allEq(MPUtil.allEQMapPre( yaopincaigou, "yaopincaigou"));
  43. YaopincaigouView yaopincaigouView = yaopincaigouService.selectView(ew);
  44. return R.ok("查询药品采购成功").put("data", yaopincaigouView);
  45. }
  46. /**
  47. * 后端详情
  48. */
  49. @RequestMapping("/info/{id}")
  50. public R info(@PathVariable("id") Long id){
  51. YaopincaigouEntity yaopincaigou = yaopincaigouService.selectById(id);
  52. return R.ok().put("data", yaopincaigou);
  53. }
  54. /**
  55. * 前端详情
  56. */
  57. @RequestMapping("/detail/{id}")
  58. public R detail(@PathVariable("id") Long id){
  59. YaopincaigouEntity yaopincaigou = yaopincaigouService.selectById(id);
  60. return R.ok().put("data", yaopincaigou);
  61. }
  62. /**
  63. * 前端保存
  64. */
  65. @RequestMapping("/add")
  66. public R add(@RequestBody YaopincaigouEntity yaopincaigou, HttpServletRequest request){
  67. yaopincaigou.setId(new Date().getTime()+new Double(Math.floor(Math.random()*1000)).longValue());
  68. //ValidatorUtils.validateEntity(yaopincaigou);
  69. yaopincaigouService.insert(yaopincaigou);
  70. return R.ok();
  71. }
  72. /**
  73. * 修改
  74. */
  75. @RequestMapping("/update")
  76. public R update(@RequestBody YaopincaigouEntity yaopincaigou, HttpServletRequest request){
  77. //ValidatorUtils.validateEntity(yaopincaigou);
  78. yaopincaigouService.updateById(yaopincaigou);//全部更新
  79. return R.ok();
  80. }
  81. /**
  82. * 删除
  83. */
  84. @RequestMapping("/delete")
  85. public R delete(@RequestBody Long[] ids){
  86. yaopincaigouService.deleteBatchIds(Arrays.asList(ids));
  87. return R.ok();
  88. }
  89. /**
  90. * 提醒接口
  91. */
  92. @RequestMapping("/remind/{columnName}/{type}")
  93. public R remindCount(@PathVariable("columnName") String columnName, HttpServletRequest request,
  94. @PathVariable("type") String type,@RequestParam Map<String, Object> map) {
  95. map.put("column", columnName);
  96. map.put("type", type);
  97. if(type.equals("2")) {
  98. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
  99. Calendar c = Calendar.getInstance();
  100. Date remindStartDate = null;
  101. Date remindEndDate = null;
  102. if(map.get("remindstart")!=null) {
  103. Integer remindStart = Integer.parseInt(map.get("remindstart").toString());
  104. c.setTime(new Date());
  105. c.add(Calendar.DAY_OF_MONTH,remindStart);
  106. remindStartDate = c.getTime();
  107. map.put("remindstart", sdf.format(remindStartDate));
  108. }
  109. if(map.get("remindend")!=null) {
  110. Integer remindEnd = Integer.parseInt(map.get("remindend").toString());
  111. c.setTime(new Date());
  112. c.add(Calendar.DAY_OF_MONTH,remindEnd);
  113. remindEndDate = c.getTime();
  114. map.put("remindend", sdf.format(remindEndDate));
  115. }
  116. }
  117. Wrapper<YaopincaigouEntity> wrapper = new EntityWrapper<YaopincaigouEntity>();
  118. if(map.get("remindstart")!=null) {
  119. wrapper.ge(columnName, map.get("remindstart"));
  120. }
  121. if(map.get("remindend")!=null) {
  122. wrapper.le(columnName, map.get("remindend"));
  123. }
  124. String tableName = request.getSession().getAttribute("tableName").toString();
  125. if(tableName.equals("yuangong")) {
  126. wrapper.eq("yuangonggonghao", (String)request.getSession().getAttribute("username"));
  127. }
  128. int count = yaopincaigouService.selectCount(wrapper);
  129. return R.ok().put("count", count);
  130. }
  131. }

六、项目总结: 

      在设计医院药品管理系统的过程中还遇到了一些棘手的问题,那就是自己的英语水平还有待提高,很多关于网站技术开发的资料文献都是英文版的,关键词语以及技术性词汇不能很好的理解。只有在借助翻译软件的实时性翻译功能的辅助下才勉强看懂。显然英语水平的高低直接影响到系统的开发过程。还有一些错误信息、比如用户空指针异常、还有MYSQL5.7版本数据库版本5.5和5.7不一致的问题、会导致SQL语句无法正常运行、还要就是管理员用户名设置的时候,后台没有判断好、在输入错误用户密码的的时候还是可以登录。这样的错原则上是不能发生的,在返回代码检查的情况下发现是在管理员信息与数据库的DAO类代码里出现了错误,代码和数据库之间没有建立好连接。还有比如管理员添加用户的时候报java.lang.NullPointException、解决的方法:查看控制台打印信息、发现添加的时候未填写相关信息、报java.lang.NullPointException、通过断电调试发现、用户信息为空的数据项、在前端保存的时候、必须填写用户完整相关信息、或者数据库设置字段可以为空都可以解决。经过本次测试,我会更加的对代码和数据库的操作上更加细心,不再出现这种原则上的错误。

        通过这次医院药品管理系统的开发,我参考了很多相关系统的例子,取长补短,吸取了其他系统的长处,逐步对该系统进行了完善,但是该系统还是有很多的不足之处,有待以后进一步学习。实践证明,医院药品管理系统有着非常好的发展前景,经过测试运行,系统各项功能都十分完善,界面漂亮,使用方便,操作容易,在技术理论上已经成熟。

七、源码获取:

大家点赞、收藏、关注、评论啦 、查看👇🏻👇🏻👇🏻获取联系方式👇🏻👇🏻👇🏻

打卡 文章 更新 308/  365天

 精彩专栏推荐订阅:下方专栏👇🏻👇🏻👇🏻👇🏻

网站建设定制开发 软件系统开发定制 定制软件开发 软件开发定制 定制app开发 app开发定制 app开发定制公司 电商商城定制开发 定制小程序开发 定制开发小程序 客户管理系统开发定制 定制网站 定制开发 crm开发定制 开发公司 小程序开发定制 定制软件 收款定制开发 企业网站定制开发 定制化开发 android系统定制开发 定制小程序开发费用 定制设计 专注app软件定制开发 软件开发定制定制 知名网站建设定制 软件定制开发供应商 应用系统定制开发 软件系统定制开发 企业管理系统定制开发 系统定制开发