一、创建两个后台项目:

1.1_ 修改项目名为renren-fast-vue-manager,其中数据源配置

  1. spring:
  2. datasource:
  3. type: com.alibaba.druid.pool.DruidDataSource
  4. druid:
  5. driver-class-name: com.mysql.cj.jdbc.Driver
  6. url: jdbc:mysql://192.168.56.10:3306/renren_fast_manager?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
  7. username: root
  8. password: 123

1.2_ 用于原来一样前台的生成方式修改相关配置文件

renren-fast-vue-manager工程:

config/index.js相关配置:

  1. // 代理列表, 是否开启代理通过[./dev.env.js]配置
  2. proxyTable: devEnv.OPEN_PROXY === false ? {} : {
  3. '/proxyApi': {
  4. target: 'http://zeyigou.com/m',
  5. changeOrigin: true,
  6. pathRewrite: {
  7. '^/proxyApi': '/'
  8. }
  9. }
  10. },
  11. hot:true, //加上这句才会进行热启动
  12. // Various Dev Server settings
  13. host: 'localhost', // can be overwritten by process.env.HOST
  14. port: 8001,

static/config/index.js相关配置:

  1. window.SITE_CONFIG['baseUrl'] = 'http://zeyigou.com/m';

renren-fast-vue-shop工程:

config/index.js相关配置:

  1. // 代理列表, 是否开启代理通过[./dev.env.js]配置
  2. proxyTable: devEnv.OPEN_PROXY === false ? {} : {
  3. '/proxyApi': {
  4. target: 'http://zeyigou.com/s',
  5. changeOrigin: true,
  6. pathRewrite: {
  7. '^/proxyApi': '/'
  8. }
  9. }
  10. },
  11. hot:true, //加上这句才会进行热启动
  12. // Various Dev Server settings
  13. host: 'localhost', // can be overwritten by process.env.HOST
  14. port: 8002,

static/config/index.js相关配置:

  1. window.SITE_CONFIG['baseUrl'] = 'http://zeyigou.com/m';

1.3_ 修改项目名为renren-fast-vue-shop,其中数据源配置

  1. spring:
  2. datasource:
  3. type: com.alibaba.druid.pool.DruidDataSource
  4. druid:
  5. driver-class-name: com.mysql.cj.jdbc.Driver
  6. url: jdbc:mysql://192.168.56.10:3306/renren_fast_shop?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
  7. username: root
  8. password: 123

1.4_ 用于原来一样前台的生成方式修改相关配置文件

renren-fast-vue-manager工程:

config/index.js相关配置:

  1. // 代理列表, 是否开启代理通过[./dev.env.js]配置
  2. proxyTable: devEnv.OPEN_PROXY === false ? {} : {
  3. '/proxyApi': {
  4. target: 'http://zeyigou.com/s',
  5. changeOrigin: true,
  6. pathRewrite: {
  7. '^/proxyApi': '/'
  8. }
  9. }
  10. },
  11. hot:true, //加上这句才会进行热启动
  12. // Various Dev Server settings
  13. host: 'localhost', // can be overwritten by process.env.HOST
  14. port: 8002,

static/config/index.js相关配置:

  1. window.SITE_CONFIG['baseUrl'] = 'http://zeyigou.com/s';

1.5_ 需要完成的菜单如下效果

image.png

1.6 最后,修改nginx配置文件:

在mydata/nginx/conf下配置上游服务器地址:

  1. upstream manager{
  2. server 192.168.56.1:9001;
  3. }

修改mydata/nginx/conf/conf.d/zeyigou.onf文件:【不建议采用】

  1. server {
  2. listen 80;
  3. server_name zeyigou.com;
  4. location /m/manager {
  5. proxy_pass http://manager/;
  6. proxy_set_header Host $host;
  7. }
  8. location /s/manager {
  9. proxy_pass http://manager/;
  10. proxy_set_header Host $host;
  11. }
  12. #运营商管理后台
  13. location /m {
  14. proxy_pass http://192.168.56.1:8080/renren-fast/;
  15. proxy_set_header Host $host;
  16. }
  17. #商家管理后台
  18. location /s {
  19. proxy_pass http://192.168.56.1:8081/renren-fast/;
  20. proxy_set_header Host $host;
  21. }
  22. }
  1. #采用映射虚拟主机的方式:【建议采纳】,如下:/mydata/nginx/conf/conf.d/zeyigou.conf文件:
  2. #运营商管理后台
  3. server {
  4. listen 80;
  5. server_name manager.zeyigou.com;
  6. location / {
  7. proxy_pass http://192.168.56.1:8080/renren-fast/;
  8. proxy_set_header Host $host;
  9. }
  10. location /manager {
  11. proxy_pass http://192.168.56.1:9001/manager/;
  12. proxy_set_header Host $host;
  13. }
  14. }
  15. #商家管理后台
  16. server {
  17. listen 80;
  18. server_name shop.zeyigou.com;
  19. location / {
  20. proxy_pass http://192.168.56.1:8081/renren-fast/;
  21. proxy_set_header Host $host;
  22. }
  23. location /shop {
  24. proxy_pass http://192.168.56.1:9002/shop/;
  25. proxy_set_header Host $host;
  26. }
  27. }

1.7、将生成的后台相关的service及controller放到zyg-manager-web及zyg-sellerGoods-interface和zyg-sellergoods-service下

image.png image.png image.png

1.8 运行效果如下:

【运营商管理】后台:
image.png
【商家管理】后台:
image.png
附加说明:

1、此时有两个数据库: image.png 2、有两个后台对应: image.png 3、两个前台如上面的截图:

二、前端规格列表

  1. <template>
  2. <div class="mod-config">
  3. <el-form :inline="true" :model="dataForm" @keyup.enter.native="getDataList()">
  4. <el-form-item>
  5. <el-input v-model="dataForm.key" placeholder="参数名" clearable></el-input>
  6. </el-form-item>
  7. <el-form-item>
  8. <el-button @click="getDataList()">查询</el-button>
  9. <el-button v-if="isAuth('manager:specification:save')" type="primary" @click="addOrUpdateHandle()">新增</el-button>
  10. <el-button v-if="isAuth('manager:specification:delete')" type="danger" @click="deleteHandle()" :disabled="dataListSelections.length <= 0">批量删除</el-button>
  11. </el-form-item>
  12. </el-form>
  13. <el-table
  14. :data="dataList"
  15. border
  16. v-loading="dataListLoading"
  17. @selection-change="selectionChangeHandle"
  18. style="width: 100%;">
  19. <el-table-column
  20. type="selection"
  21. header-align="center"
  22. align="center"
  23. width="50">
  24. </el-table-column>
  25. <el-table-column
  26. prop="id"
  27. header-align="center"
  28. align="center"
  29. label="规格id">
  30. </el-table-column>
  31. <el-table-column
  32. prop="specName"
  33. header-align="center"
  34. align="center"
  35. label="名称">
  36. </el-table-column>
  37. <el-table-column
  38. fixed="right"
  39. header-align="center"
  40. align="center"
  41. width="150"
  42. label="操作">
  43. <template slot-scope="scope">
  44. <el-button type="text" size="small" @click="addOrUpdateHandle(scope.row.id)">修改</el-button>
  45. <el-button type="text" size="small" @click="deleteHandle(scope.row.id)">删除</el-button>
  46. </template>
  47. </el-table-column>
  48. </el-table>
  49. <el-pagination
  50. @size-change="sizeChangeHandle"
  51. @current-change="currentChangeHandle"
  52. :current-page="pageIndex"
  53. :page-sizes="[10, 20, 50, 100]"
  54. :page-size="pageSize"
  55. :total="totalPage"
  56. layout="total, sizes, prev, pager, next, jumper">
  57. </el-pagination>
  58. <!-- 弹窗, 新增 / 修改 -->
  59. <add-or-update v-if="addOrUpdateVisible" ref="addOrUpdate" @refreshDataList="getDataList"></add-or-update>
  60. </div>
  61. </template>
  62. <script>
  63. import AddOrUpdate from './specification-add-or-update'
  64. export default {
  65. data () {
  66. return {
  67. dataForm: {
  68. key: ''
  69. },
  70. dataList: [],
  71. pageIndex: 1,
  72. pageSize: 10,
  73. totalPage: 0,
  74. dataListLoading: false,
  75. dataListSelections: [],
  76. addOrUpdateVisible: false
  77. }
  78. },
  79. components: {
  80. AddOrUpdate
  81. },
  82. activated () {
  83. this.getDataList()
  84. },
  85. methods: {
  86. // 获取数据列表
  87. getDataList () {
  88. this.dataListLoading = true
  89. this.$http({
  90. url: this.$http.adornUrl('/manager/specification/list'),
  91. method: 'get',
  92. params: this.$http.adornParams({
  93. 'page': this.pageIndex,
  94. 'limit': this.pageSize,
  95. 'key': this.dataForm.key
  96. })
  97. }).then(({data}) => {
  98. if (data && data.code === 0) {
  99. this.dataList = data.page.list
  100. this.totalPage = data.page.totalCount
  101. } else {
  102. this.dataList = []
  103. this.totalPage = 0
  104. }
  105. this.dataListLoading = false
  106. })
  107. },
  108. // 每页数
  109. sizeChangeHandle (val) {
  110. this.pageSize = val
  111. this.pageIndex = 1
  112. this.getDataList()
  113. },
  114. // 当前页
  115. currentChangeHandle (val) {
  116. this.pageIndex = val
  117. this.getDataList()
  118. },
  119. // 多选
  120. selectionChangeHandle (val) {
  121. this.dataListSelections = val
  122. },
  123. // 新增 / 修改
  124. addOrUpdateHandle (id) {
  125. this.addOrUpdateVisible = true
  126. this.$nextTick(() => {
  127. this.$refs.addOrUpdate.init(id)
  128. })
  129. },
  130. // 删除
  131. deleteHandle (id) {
  132. console.log("---------->",this.dataListSelections);
  133. var ids = id ? [id] : this.dataListSelections.map(item => {
  134. return item.id
  135. })
  136. this.$confirm(`确定对[id=${ids.join(',')}]进行[${id ? '删除' : '批量删除'}]操作?`, '提示', {
  137. confirmButtonText: '确定',
  138. cancelButtonText: '取消',
  139. type: 'warning'
  140. }).then(() => {
  141. this.$http({
  142. url: this.$http.adornUrl('/manager/specification/delete'),
  143. method: 'post',
  144. data: this.$http.adornData(ids, false)
  145. }).then(({data}) => {
  146. if (data && data.code === 0) {
  147. this.$message({
  148. message: '操作成功',
  149. type: 'success',
  150. duration: 1500,
  151. onClose: () => {
  152. this.getDataList()
  153. }
  154. })
  155. } else {
  156. this.$message.error(data.msg)
  157. }
  158. })
  159. })
  160. }
  161. }
  162. }
  163. </script>

三、前端规格修改及添加

  1. <template>
  2. <el-dialog
  3. :title="!dataForm.spec.id ? '新增' : '修改'"
  4. :close-on-click-modal="false"
  5. :visible.sync="visible">
  6. <el-form :model="dataForm" :rules="dataRule" ref="dataForm" @keyup.enter.native="dataFormSubmit()" label-width="80px">
  7. {{dataForm}}
  8. <el-form-item label="名称" prop="spec.specName">
  9. <el-input v-model="dataForm.spec.specName" placeholder="名称" ></el-input>
  10. </el-form-item>
  11. <el-button @click="dataForm.options.push({})" type="success">新增规格选项</el-button>
  12. </el-form>
  13. <el-table
  14. :data="dataForm.options"
  15. style="width: 100%;margin-top: 20px;">
  16. <el-table-column
  17. header-align="center"
  18. align="center"
  19. prop="optionName"
  20. label="规格名称">
  21. <template slot-scope="scope">
  22. <el-input type="text" v-model="scope.row.optionName" size="small" />
  23. </template>
  24. </el-table-column>
  25. <el-table-column
  26. header-align="center"
  27. align="center"
  28. prop="orders"
  29. label="顺序">
  30. <template slot-scope="scope">
  31. <el-input type="text" size="small" v-model="scope.row.orders" />
  32. </template>
  33. </el-table-column>
  34. <el-table-column
  35. fixed="right"
  36. header-align="center"
  37. align="center"
  38. width="150"
  39. label="操作">
  40. <template slot-scope="scope">
  41. <el-button type="text" size="small" @click="dataForm.options.splice(scope.$index,1)">删除</el-button>
  42. </template>
  43. </el-table-column>
  44. </el-table>
  45. <span slot="footer" class="dialog-footer">
  46. <el-button @click="visible = false">取消</el-button>
  47. <el-button type="primary" @click="dataFormSubmit()">确定</el-button>
  48. </span>
  49. </el-dialog>
  50. </template>
  51. <script>
  52. export default {
  53. data () {
  54. return {
  55. visible: false,
  56. dataForm: {
  57. spec:{
  58. id:undefined,
  59. specName: ''
  60. },
  61. options:[],
  62. },
  63. dataRule: {
  64. spec:{
  65. specName: [
  66. { required: true, message: '名称不能为空', trigger: 'blur' }
  67. ]
  68. }
  69. }
  70. }
  71. },
  72. methods: {
  73. init (id) {
  74. this.dataForm.spec.id = id || 0
  75. this.visible = true
  76. this.$nextTick(() => {
  77. this.$refs['dataForm'].resetFields()
  78. if (this.dataForm.spec.id) {
  79. this.$http({
  80. url: this.$http.adornUrl(`/manager/specification/info/${this.dataForm.spec.id}`),
  81. method: 'get',
  82. params: this.$http.adornParams()
  83. }).then(({data}) => {
  84. if (data && data.code === 0) {
  85. this.dataForm = data.specification;
  86. }
  87. })
  88. }
  89. else{
  90. this.dataForm.spec={};
  91. this.dataForm.options=[];
  92. }
  93. })
  94. },
  95. // 表单提交
  96. dataFormSubmit () {
  97. this.$refs['dataForm'].validate((valid) => {
  98. if (valid) {
  99. this.$http({
  100. url: this.$http.adornUrl(`/manager/specification/${!this.dataForm.spec.id ? 'save' : 'update'}`),
  101. method: 'post',
  102. data:this.dataForm
  103. // data: this.$http.adornData({
  104. // 'id': this.dataForm.spec.id || undefined,
  105. // 'specName': this.dataForm.spec.specName
  106. // })
  107. }).then(({data}) => {
  108. if (data && data.code === 0) {
  109. this.$message({
  110. message: '操作成功',
  111. type: 'success',
  112. duration: 1500,
  113. onClose: () => {
  114. this.visible = false
  115. this.$emit('refreshDataList')
  116. }
  117. })
  118. } else {
  119. this.$message.error(data.msg)
  120. }
  121. })
  122. }
  123. })
  124. }
  125. }
  126. }
  127. </script>

四、后端规格服务层修改及添加、删除

  1. /**
  2. * 功能: 添加规格及期规格选项
  3. * 参数:
  4. * 返回值: void
  5. * 时间: 2021/7/26 15:52
  6. */
  7. @Override
  8. public void add(Specification specification) {
  9. //1. 添加规格对象
  10. SpecificationEntity spec = specification.getSpec();
  11. baseMapper.insert(spec);
  12. System.out.println("spec = " + spec);
  13. //2. 添加规格选项
  14. List<SpecificationOptionEntity> options = specification.getOptions();
  15. for (SpecificationOptionEntity option : options) {
  16. //2.1 为规格选项指定外键
  17. option.setSpecId(spec.getId());
  18. //2.2 添加规格选项
  19. optionService.save(option);
  20. }
  21. }
  22. /**
  23. * 功能: 根据id查询规格及其规格选项
  24. * 参数:
  25. * 返回值: com.zelin.entity.group.Specification
  26. * 时间: 2021/7/26 16:17
  27. */
  28. @Override
  29. public Specification findById(Long id) {
  30. //1. 根据规格id查询规格
  31. SpecificationEntity specificationEntity = baseMapper.selectById(id);
  32. //2. 根据规格id在规格选项表中查询出此规格对应的规格选项列表
  33. //2.1 定义查询条件
  34. QueryWrapper<SpecificationOptionEntity> queryWrapper = new QueryWrapper<>();
  35. queryWrapper.eq("spec_id",id);
  36. //2.2 根据条件查询出规格选项列表
  37. List<SpecificationOptionEntity> list = optionService.list(queryWrapper);
  38. //3. 定义规格的组合对象
  39. Specification specification = new Specification();
  40. specification.setSpec(specificationEntity);
  41. specification.setOptions(list);
  42. return specification;
  43. }
  44. /**
  45. * 功能: 修改规格及其规格选项
  46. * 参数:
  47. * 返回值: void
  48. * 时间: 2021/7/26 16:27
  49. * 注意:
  50. * 一对多及多对多修改:
  51. * ① 根据外键删除多的一方表中的所有数据
  52. * ② 再添加到多的一方
  53. * ③ 一方直接修改
  54. */
  55. @Override
  56. public void update2(Specification specification) {
  57. //1. 修改规格表(根据id修改规格表)
  58. this.updateById(specification.getSpec());
  59. //2. 根据规格id在多的表中删除数据(根据外键删除多的一方)
  60. QueryWrapper<SpecificationOptionEntity> deleteWrapper = new QueryWrapper<>();
  61. deleteWrapper.eq("spec_id",specification.getSpec().getId());
  62. optionService.remove(deleteWrapper);
  63. //3. 再添加新的数据到多的表中
  64. //3.1 得到规格选项的值
  65. List<SpecificationOptionEntity> options = specification.getOptions();
  66. for (SpecificationOptionEntity option : options) {
  67. //3.2 设置关联的外键
  68. option.setSpecId(specification.getSpec().getId());
  69. //3.2 添加规格选项到规格选项表中
  70. optionService.save(option);
  71. }
  72. }
  73. /**
  74. * 功能: 根据传入的多个规格id,删除规格及规格选项
  75. * 参数:
  76. * 返回值: void
  77. * 时间: 2021/7/26 16:48
  78. */
  79. @Override
  80. public void batchDelete(List<Long> ids) {
  81. for (Long id : ids) {
  82. //1. 删除主表规格表
  83. this.removeById(id);
  84. //2. 规格选项表
  85. QueryWrapper<SpecificationOptionEntity> deleteWrapper = new QueryWrapper<>();
  86. deleteWrapper.eq("spec_id",id);
  87. optionService.remove(deleteWrapper);
  88. }
  89. }

五、后端规格控制层

  1. /**
  2. * @author WF
  3. * @email 2568783935@qq.com
  4. * @date 2021-07-23 21:10:35
  5. */
  6. @RestController
  7. @RequestMapping("/specification")
  8. public class SpecificationController {
  9. @Autowired
  10. private SpecificationService specificationService;
  11. /**
  12. * 列表
  13. */
  14. @RequestMapping("/list")
  15. //@RequiresPermissions("manager:specification:list")
  16. public R list(@RequestParam Map<String, Object> params){
  17. PageUtils page = specificationService.queryPage(params);
  18. return R.ok().put("page", page);
  19. }
  20. /**
  21. * 功能: 显示所有规格列表
  22. * 参数:
  23. * 返回值: com.zelin.utils.R
  24. * 时间: 2021/7/27 11:57
  25. */
  26. @RequestMapping("/findAll")
  27. public R findAll(){
  28. //1. 查询所有规格列表
  29. List<SpecificationEntity> list = specificationService.list();
  30. //2. 收集数据转换为SpecificationVoEntity对象
  31. List<SpecificationVoEntity> collect = list.stream()
  32. .map(m -> new SpecificationVoEntity(m.getId(), m.getSpecName()))
  33. .collect(Collectors.toList());
  34. //3. 返回分页对象
  35. return R.ok().put("list", collect);
  36. }
  37. /**
  38. * 信息(根据id查询规格)
  39. */
  40. @RequestMapping("/info/{id}")
  41. //@RequiresPermissions("manager:specification:info")
  42. public R info(@PathVariable("id") Long id){
  43. Specification specification = specificationService.findById(id);
  44. return R.ok().put("specification", specification);
  45. }
  46. /**
  47. * 保存(添加)
  48. */
  49. @RequestMapping("/save")
  50. //@RequiresPermissions("manager:specification:save")
  51. public R save(@RequestBody Specification specification){
  52. System.out.println("specification--->add = " + specification);
  53. specificationService.add(specification);
  54. return R.ok();
  55. }
  56. /**
  57. * 修改
  58. */
  59. @RequestMapping("/update")
  60. //@RequiresPermissions("manager:specification:update")
  61. public R update(@RequestBody Specification specification){
  62. specificationService.update2(specification);
  63. return R.ok();
  64. }
  65. /**
  66. * 删除
  67. */
  68. @RequestMapping("/delete")
  69. //@RequiresPermissions("manager:specification:delete")
  70. public R delete(@RequestBody Long[] ids){
  71. specificationService.batchDelete(Arrays.asList(ids));
  72. return R.ok();
  73. }
  74. }

六、后端品牌控制层:

  1. /**
  2. * @author WF
  3. * @email 2568783935@qq.com
  4. * @date 2021-07-23 21:10:35
  5. */
  6. @RestController
  7. @RequestMapping("/brand")
  8. public class BrandController {
  9. @Autowired
  10. private BrandService brandService;
  11. /**
  12. * 列表cd
  13. */
  14. @RequestMapping("/list")
  15. //@RequiresPermissions("manager:brand:list")
  16. public R list(@RequestParam Map<String, Object> params){
  17. PageUtils page = brandService.queryPage(params);
  18. System.out.println("page = " + page.getList());
  19. return R.ok().put("page", page);
  20. }
  21. /**
  22. * 显示所有品牌
  23. */
  24. @RequestMapping("/findAll")
  25. public R findAll(){
  26. //1. 查询所有品牌
  27. List<BrandEntity> list = brandService.list();
  28. //2. 将当前页集合中的对象更改为BrandVoEntity对象,因为这个对象是模板表中的brandIds[{id:1,text:'aa'}]中某一条记录
  29. List<BrandVoEntity> collect = list.stream()
  30. .map(m -> new BrandVoEntity(m.getId(), m.getName()))
  31. .collect(Collectors.toList());
  32. //2. 返回结果
  33. return R.ok().put("list", collect);
  34. }
  35. /**
  36. * 信息
  37. */
  38. @RequestMapping("/info/{id}")
  39. //@RequiresPermissions("manager:brand:info")
  40. public R info(@PathVariable("id") Long id){
  41. BrandEntity brand = brandService.getById(id);
  42. return R.ok().put("brand", brand);
  43. }
  44. /**
  45. * 保存
  46. */
  47. @RequestMapping("/save")
  48. //@RequiresPermissions("manager:brand:save")
  49. public R save(@RequestBody BrandEntity brand){
  50. System.out.println("brand = " + brand);
  51. brandService.save(brand);
  52. return R.ok();
  53. }
  54. /**
  55. * 修改
  56. */
  57. @RequestMapping("/update")
  58. //@RequiresPermissions("manager:brand:update")
  59. public R update(@RequestBody BrandEntity brand){
  60. brandService.updateById(brand);
  61. return R.ok();
  62. }
  63. /**
  64. * 删除
  65. */
  66. @RequestMapping("/delete")
  67. //@RequiresPermissions("manager:brand:delete")
  68. public R delete(@RequestBody Long[] ids){
  69. brandService.removeByIds(Arrays.asList(ids));
  70. return R.ok();
  71. }
  72. }

七、运行效果如下:

image.png
image.png
image.png

八、模板前端开发-列表展示:

  1. <template>
  2. <div class="mod-config">
  3. <el-form :inline="true" :model="dataForm" @keyup.enter.native="getDataList()">
  4. <el-form-item>
  5. <el-input v-model="dataForm.key" placeholder="参数名" clearable></el-input>
  6. </el-form-item>
  7. <el-form-item>
  8. <el-button @click="getDataList()">查询</el-button>
  9. <el-button v-if="isAuth('manager:typetemplate:save')" type="primary" @click="addOrUpdateHandle()">新增</el-button>
  10. <el-button v-if="isAuth('manager:typetemplate:delete')" type="danger" @click="deleteHandle()" :disabled="dataListSelections.length <= 0">批量删除</el-button>
  11. </el-form-item>
  12. </el-form>
  13. <el-table
  14. :data="dataList"
  15. border
  16. v-loading="dataListLoading"
  17. @selection-change="selectionChangeHandle"
  18. style="width: 100%;">
  19. <el-table-column
  20. type="selection"
  21. header-align="center"
  22. align="center"
  23. width="50">
  24. </el-table-column>
  25. <el-table-column
  26. prop="id"
  27. header-align="center"
  28. align="center"
  29. label="">
  30. </el-table-column>
  31. <el-table-column
  32. prop="name"
  33. header-align="center"
  34. align="center"
  35. label="模板名称">
  36. </el-table-column>
  37. <el-table-column
  38. header-align="center"
  39. align="center"
  40. label="关联规格">
  41. <template slot-scope="scope">
  42. <span style="margin-left: 10px">{{handleDataList(scope.row.specIds,"text") }}</span>
  43. </template>
  44. </el-table-column>
  45. <el-table-column
  46. header-align="center"
  47. align="center"
  48. label="关联品牌">
  49. <template slot-scope="scope">
  50. <span style="margin-left: 10px">{{handleDataList(scope.row.brandIds,"text") }}</span>
  51. </template>
  52. </el-table-column>
  53. <el-table-column
  54. header-align="center"
  55. align="center"
  56. label="自定义属性">
  57. <template slot-scope="scope">
  58. <span style="margin-left: 10px">{{handleDataList(scope.row.customAttributeItems,"text") }}</span>
  59. </template>
  60. </el-table-column>
  61. <el-table-column
  62. fixed="right"
  63. header-align="center"
  64. align="center"
  65. width="150"
  66. label="操作">
  67. <template slot-scope="scope">
  68. <el-button type="text" size="small" @click="addOrUpdateHandle(scope.row.id)">修改</el-button>
  69. <el-button type="text" size="small" @click="deleteHandle(scope.row.id)">删除</el-button>
  70. </template>
  71. </el-table-column>
  72. </el-table>
  73. <el-pagination
  74. @size-change="sizeChangeHandle"
  75. @current-change="currentChangeHandle"
  76. :current-page="pageIndex"
  77. :page-sizes="[10, 20, 50, 100]"
  78. :page-size="pageSize"
  79. :total="totalPage"
  80. layout="total, sizes, prev, pager, next, jumper">
  81. </el-pagination>
  82. <!-- 弹窗, 新增 / 修改 -->
  83. <add-or-update v-if="addOrUpdateVisible" ref="addOrUpdate" @refreshDataList="getDataList"></add-or-update>
  84. </div>
  85. </template>
  86. <script>
  87. import AddOrUpdate from './typetemplate-add-or-update'
  88. export default {
  89. data () {
  90. return {
  91. dataForm: {
  92. key: ''
  93. },
  94. dataList: [],
  95. pageIndex: 1,
  96. pageSize: 10,
  97. totalPage: 0,
  98. dataListLoading: false,
  99. dataListSelections: [],
  100. addOrUpdateVisible: false
  101. }
  102. },
  103. components: {
  104. AddOrUpdate
  105. },
  106. activated () {
  107. this.getDataList()
  108. },
  109. methods: {
  110. // 获取数据列表
  111. getDataList () {
  112. this.dataListLoading = true
  113. this.$http({
  114. url: this.$http.adornUrl('/manager/typetemplate/list'),
  115. method: 'get',
  116. params: this.$http.adornParams({
  117. 'page': this.pageIndex,
  118. 'limit': this.pageSize,
  119. 'key': this.dataForm.key
  120. })
  121. }).then(({data}) => {
  122. if (data && data.code === 0) {
  123. this.dataList = data.page.list
  124. this.totalPage = data.page.totalCount
  125. //处理一下dataList
  126. // this.handleDataList(this.dataList.brandIds,"text");
  127. } else {
  128. this.dataList = []
  129. this.totalPage = 0
  130. }
  131. this.dataListLoading = false
  132. })
  133. },
  134. //将传入的集合只根据对应key得到数据并返回
  135. handleDataList(list,key){
  136. list = JSON.parse(list);
  137. //最终连接成的文本
  138. let info = "";
  139. list.forEach(item=>{
  140. info += item[key] + ","
  141. })
  142. return info;
  143. },
  144. // 每页数
  145. sizeChangeHandle (val) {
  146. this.pageSize = val
  147. this.pageIndex = 1
  148. this.getDataList()
  149. },
  150. // 当前页
  151. currentChangeHandle (val) {
  152. this.pageIndex = val
  153. this.getDataList()
  154. },
  155. // 多选
  156. selectionChangeHandle (val) {
  157. this.dataListSelections = val
  158. },
  159. // 新增 / 修改
  160. addOrUpdateHandle (id) {
  161. this.addOrUpdateVisible = true
  162. this.$nextTick(() => {
  163. this.$refs.addOrUpdate.init(id)
  164. })
  165. },
  166. // 删除
  167. deleteHandle (id) {
  168. var ids = id ? [id] : this.dataListSelections.map(item => {
  169. return item.id
  170. })
  171. this.$confirm(`确定对[id=${ids.join(',')}]进行[${id ? '删除' : '批量删除'}]操作?`, '提示', {
  172. confirmButtonText: '确定',
  173. cancelButtonText: '取消',
  174. type: 'warning'
  175. }).then(() => {
  176. this.$http({
  177. url: this.$http.adornUrl('/manager/typetemplate/delete'),
  178. method: 'post',
  179. data: this.$http.adornData(ids, false)
  180. }).then(({data}) => {
  181. if (data && data.code === 0) {
  182. this.$message({
  183. message: '操作成功',
  184. type: 'success',
  185. duration: 1500,
  186. onClose: () => {
  187. this.getDataList()
  188. }
  189. })
  190. } else {
  191. this.$message.error(data.msg)
  192. }
  193. })
  194. })
  195. }
  196. }
  197. }
  198. </script>

九、模板前端开发-新增修改模板:

  1. <template>
  2. <el-dialog
  3. :title="!dataForm.id ? '新增' : '修改'"
  4. :close-on-click-modal="false"
  5. :visible.sync="visible">
  6. {{dataForm}}
  7. <el-form :model="dataForm" :rules="dataRule" ref="dataForm" @keyup.enter.native="dataFormSubmit()" label-width="120px">
  8. <el-form-item label="模板名称" prop="name">
  9. <el-input v-model="dataForm.name" placeholder="模板名称"></el-input>
  10. </el-form-item>
  11. <el-form-item label="关联规格">
  12. <el-select v-model="dataForm.specIds" value-key="id" multiple placeholder="请选择">
  13. <el-option
  14. v-for="item in specs"
  15. :key="item.id"
  16. :label="item.text"
  17. :value="item">
  18. </el-option>
  19. </el-select>
  20. </el-form-item>
  21. <el-form-item label="关联品牌" prop="brandIds">
  22. <el-select v-model="dataForm.brandIds" value-key="id" multiple placeholder="请选择">
  23. <el-option
  24. v-for="item in brands"
  25. :key="item.id"
  26. :label="item.text"
  27. :value="item">
  28. </el-option>
  29. </el-select>
  30. </el-form-item>
  31. <el-form-item label="自定义扩展属性" >
  32. <el-button @click="dataForm.customAttributeItems.push({})" type="primary" plain>新增扩展属性</el-button>
  33. <el-table
  34. :data="dataForm.customAttributeItems"
  35. style="width: 100%;margin-top: 20px;">
  36. <el-table-column
  37. header-align="center"
  38. align="center"
  39. label="属性名称">
  40. <template slot-scope="scope">
  41. <el-input type="text" v-model="scope.row.text" size="small" />
  42. </template>
  43. </el-table-column>
  44. <el-table-column
  45. fixed="right"
  46. header-align="center"
  47. align="center"
  48. width="150"
  49. label="操作">
  50. <template slot-scope="scope">
  51. <el-button type="text" size="small" @click="dataForm.options.splice(scope.$index,1)">删除</el-button>
  52. </template>
  53. </el-table-column>
  54. </el-table>
  55. </el-form-item>
  56. </el-form>
  57. <span slot="footer" class="dialog-footer">
  58. <el-button @click="visible = false">取消</el-button>
  59. <el-button type="primary" @click="dataFormSubmit()">确定</el-button>
  60. </span>
  61. </el-dialog>
  62. </template>
  63. <script>
  64. export default {
  65. data () {
  66. return {
  67. visible: false,
  68. specs:[],
  69. brands:[],
  70. dataForm: {
  71. name: '',
  72. specIds: [],
  73. brandIds: [],
  74. customAttributeItems: []
  75. },
  76. dataRule: {
  77. name: [
  78. { required: true, message: '模板名称不能为空', trigger: 'blur' }
  79. ],
  80. specIds: [
  81. { required: true, message: '关联规格不能为空', trigger: 'blur' }
  82. ],
  83. brandIds: [
  84. { required: true, message: '关联品牌不能为空', trigger: 'blur' }
  85. ],
  86. customAttributeItems: [
  87. { required: true, message: '自定义属性不能为空', trigger: 'blur' }
  88. ]
  89. }
  90. }
  91. },
  92. created() {
  93. this.getSpecs();
  94. this.getBrands();
  95. },
  96. methods: {
  97. getKey(row){
  98. return row.id;
  99. },
  100. //1. 获取规格列表
  101. getSpecs(){
  102. this.$http({
  103. url: this.$http.adornUrl(`/manager/specification/findAll`),
  104. method: 'get',
  105. params: this.$http.adornParams()
  106. }).then(({data}) => {
  107. if (data && data.code === 0) {
  108. console.log("xxx----",data);
  109. // this.specs = data.page.list.map(m=>{
  110. // return {"id":m.id,"text":m.specName}
  111. // })
  112. this.specs = data.list;
  113. }
  114. })
  115. },
  116. //2. 获取所有的品牌列表
  117. getBrands(){
  118. this.$http({
  119. url: this.$http.adornUrl(`/manager/brand/findAll`),
  120. method: 'get',
  121. params: this.$http.adornParams()
  122. }).then(({data}) => {
  123. if (data && data.code === 0) {
  124. console.log("xxx----",data);
  125. this.brands = data.list
  126. // this.brands = data.page.list;
  127. }
  128. })
  129. },
  130. converToStr(str,key){
  131. //1. 转换字符串为对象
  132. let obj = JSON.parse(str);
  133. //2. 再处理其中的id为字符串类型
  134. return obj.map(m=>{
  135. return {"id":m.id+"","text":m[key]};
  136. })
  137. },
  138. init (id) {
  139. this.dataForm.id = id || 0
  140. this.visible = true
  141. this.$nextTick(() => {
  142. this.$refs['dataForm'].resetFields()
  143. if (this.dataForm.id) {
  144. this.$http({
  145. url: this.$http.adornUrl(`/manager/typetemplate/info/${this.dataForm.id}`),
  146. method: 'get',
  147. params: this.$http.adornParams()
  148. }).then(({data}) => {
  149. if (data && data.code === 0) {
  150. this.dataForm.name = data.typeTemplate.name
  151. //this.dataForm.specIds = JSON.parse(data.typeTemplate.specIds)
  152. this.dataForm.specIds = this.converToStr(data.typeTemplate.specIds,"text");
  153. this.dataForm.brandIds = this.converToStr(data.typeTemplate.brandIds,"text")
  154. this.dataForm.customAttributeItems = JSON.parse(data.typeTemplate.customAttributeItems)
  155. // this.dataForm.specIds = this.dataForm.specIds.map(m=>{
  156. // return {"id":m.id,"text":m.specName};
  157. // })
  158. console.log("dataForm---->",this.dataForm);
  159. }
  160. })
  161. }else{
  162. this.dataForm.specIds = [];
  163. this.dataForm.brandIds = [];
  164. this.dataForm.customAttributeItems = [];
  165. }
  166. })
  167. },
  168. // 表单提交
  169. dataFormSubmit () {
  170. this.$refs['dataForm'].validate((valid) => {
  171. if (valid) {
  172. this.$http({
  173. url: this.$http.adornUrl(`/manager/typetemplate/${!this.dataForm.id ? 'save' : 'update'}`),
  174. method: 'post',
  175. data: this.$http.adornData({
  176. 'id': this.dataForm.id || undefined,
  177. 'name': this.dataForm.name,
  178. 'specIds': this.dataForm.specIds,
  179. 'brandIds': this.dataForm.brandIds,
  180. 'customAttributeItems': this.dataForm.customAttributeItems
  181. })
  182. }).then(({data}) => {
  183. if (data && data.code === 0) {
  184. this.$message({
  185. message: '操作成功',
  186. type: 'success',
  187. duration: 1500,
  188. onClose: () => {
  189. this.visible = false
  190. this.$emit('refreshDataList')
  191. }
  192. })
  193. } else {
  194. this.$message.error(data.msg)
  195. }
  196. })
  197. }
  198. })
  199. }
  200. }
  201. }
  202. </script>

十、模板页面运行效果:

image.png
image.png

十一、模板表中的id一定要带引号,否则,修改回显数据出错

  1. CREATE TABLE `tb_type_template` (
  2. `id` bigint(11) NOT NULL AUTO_INCREMENT,
  3. `name` varchar(80) DEFAULT NULL COMMENT '模板名称',
  4. `spec_ids` varchar(1000) DEFAULT NULL COMMENT '关联规格',
  5. `brand_ids` varchar(1000) DEFAULT NULL COMMENT '关联品牌',
  6. `custom_attribute_items` varchar(2000) DEFAULT NULL COMMENT '自定义属性',
  7. PRIMARY KEY (`id`)
  8. ) ENGINE=InnoDB AUTO_INCREMENT=1419912706006802434 DEFAULT CHARSET=utf8;
  9. /*Data for the table `tb_type_template` */
  10. insert into `tb_type_template`(`id`,`name`,`spec_ids`,`brand_ids`,`custom_attribute_items`) values
  11. (35,'手机','[{\"id\":\"27\",\"text\":\"网络\"},{\"id\":\"32\",\"text\":\"机身内存\"}]','[{\"id\":\"1\",\"text\":\"联想\"},{\"id\":\"3\",\"text\":\"三星\"},{\"id\":\"2\",\"text\":\"华为\"},{\"id\":\"5\",\"text\":\"OPPO\"},{\"id\":\"4\",\"text\":\"小米\"},{\"id\":\"9\",\"text\":\"苹果\"},{\"id\":\"8\",\"text\":\"魅族\"},{\"id\":\"6\",\"text\":\"360\"},{\"id\":\"10\",\"text\":\"VIVO\"},{\"id\":\"11\",\"text\":\"诺基亚\"},{\"id\":\"12\",\"text\":\"锤子\"}]','[{\"text\":\"内存大小\"},{\"text\":\"颜色\"}]'),
  12. (37,'电视','[{\"id\":\"33\",\"text\":\"电视屏幕尺寸\"}]','[{\"id\":\"16\",\"text\":\"TCL\"},{\"id\":\"13\",\"text\":\"长虹\"},{\"id\":\"14\",\"text\":\"海尔\"},{\"id\":\"19\",\"text\":\"创维\"},{\"id\":\"21\",\"text\":\"康佳\"},{\"id\":\"18\",\"text\":\"夏普\"},{\"id\":\"17\",\"text\":\"海信\"},{\"id\":\"20\",\"text\":\"东芝\"},{\"id\":\"15\",\"text\":\"飞利浦\"},{\"id\":\"22\",\"text\":\"LG\"}]','[{\"text\":\"机身内存\"},{\"text\":\"颜色\"}]'),
  13. (38,'移动电源','[{\"id\":\"26\",\"text\":\"尺码\"},{\"id\":\"28\",\"text\":\"手机屏幕尺寸\"}]','[{\"id\":\"1\",\"text\":\"联想\"},{\"id\":\"2\",\"text\":\"华为\"},{\"id\":\"5\",\"text\":\"OPPO\"}]','[{\"text\":\"aaa\"},{\"text\":\"ccc\"},{\"text\":\"ddd\"}]'),
  14. (1419912706006802433,'京东电视','[{\"id\":\"26\",\"text\":\"尺码\"},{\"id\":\"27\",\"text\":\"网络\"}]','[{\"id\":\"7\",\"text\":\"中兴\"},{\"id\":\"3\",\"text\":\"三星\"},{\"id\":\"11\",\"text\":\"诺基亚\"}]','[{\"text\":\"cc\"},{\"text\":\"eee\"}]');

十二:商家审核

业务需求:
商家申请入驻后,需要网站运营人员在运营商后台进行审核,审核后商家才可以登陆系统。
状态值: 0:未审核 1:已审核 2:审核未通过 3:关闭

12.1 前端实现

  1. <template>
  2. <div class="mod-config">
  3. <el-form :inline="true" :model="dataForm" @keyup.enter.native="getDataList()">
  4. <el-form-item>
  5. <el-input v-model="dataForm.key" placeholder="参数名" clearable></el-input>
  6. </el-form-item>
  7. <el-form-item>
  8. <el-button @click="getDataList()">查询</el-button>
  9. <el-button v-if="isAuth('manager:seller:save')" type="primary" @click="addOrUpdateHandle()">新增</el-button>
  10. <el-button v-if="isAuth('manager:seller:delete')" type="danger" @click="deleteHandle()" :disabled="dataListSelections.length <= 0">批量删除</el-button>
  11. </el-form-item>
  12. </el-form>
  13. <el-table
  14. :data="dataList"
  15. border
  16. v-loading="dataListLoading"
  17. @selection-change="selectionChangeHandle"
  18. style="width: 100%;">
  19. <el-table-column
  20. type="selection"
  21. header-align="center"
  22. align="center"
  23. width="50">
  24. </el-table-column>
  25. <el-table-column
  26. prop="sellerId"
  27. header-align="center"
  28. align="center"
  29. label="商家ID">
  30. </el-table-column>
  31. <el-table-column
  32. prop="name"
  33. header-align="center"
  34. align="center"
  35. label="公司名">
  36. </el-table-column>
  37. <el-table-column
  38. prop="nickName"
  39. header-align="center"
  40. align="center"
  41. label="店铺名称">
  42. </el-table-column>
  43. <el-table-column
  44. prop="telephone"
  45. header-align="center"
  46. align="center"
  47. label="公司电话">
  48. </el-table-column>
  49. <el-table-column
  50. fixed="right"
  51. header-align="center"
  52. align="center"
  53. width="300"
  54. label="操作">
  55. <template slot-scope="scope">
  56. <el-button type="text" size="small" @click="updateStatus(scope.row.sellerId,'1')">审核通过</el-button>
  57. <el-button type="text" size="small" @click="updateStatus(scope.row.sellerId,'2')">审核未通过</el-button>
  58. <el-button type="text" size="small" @click="addOrUpdateHandle(scope.row.sellerId)">修改</el-button>
  59. <el-button type="text" size="small" @click="deleteHandle(scope.row.sellerId)">删除</el-button>
  60. </template>
  61. </el-table-column>
  62. </el-table>
  63. <el-pagination
  64. @size-change="sizeChangeHandle"
  65. @current-change="currentChangeHandle"
  66. :current-page="pageIndex"
  67. :page-sizes="[10, 20, 50, 100]"
  68. :page-size="pageSize"
  69. :total="totalPage"
  70. layout="total, sizes, prev, pager, next, jumper">
  71. </el-pagination>
  72. <!-- 弹窗, 新增 / 修改 -->
  73. <add-or-update v-if="addOrUpdateVisible" ref="addOrUpdate" @refreshDataList="getDataList"></add-or-update>
  74. </div>
  75. </template>
  76. <script>
  77. import AddOrUpdate from './seller-add-or-update'
  78. export default {
  79. data () {
  80. return {
  81. dataForm: {
  82. key: ''
  83. },
  84. dataList: [],
  85. pageIndex: 1,
  86. pageSize: 10,
  87. totalPage: 0,
  88. dataListLoading: false,
  89. dataListSelections: [],
  90. addOrUpdateVisible: false
  91. }
  92. },
  93. components: {
  94. AddOrUpdate
  95. },
  96. activated () {
  97. this.getDataList()
  98. },
  99. methods: {
  100. //商家审核
  101. updateStatus(sellerId,status){
  102. this.$http({
  103. url: this.$http.adornUrl(`/manager/seller/updateStatus/${sellerId}/${status}`),
  104. method: 'get'
  105. }).then(({data}) => {
  106. if (data && data.code === 0) {
  107. this.getDataList();
  108. } else {
  109. this.dataList = []
  110. this.totalPage = 0
  111. }
  112. })
  113. },
  114. // 获取数据列表
  115. getDataList () {
  116. this.dataListLoading = true
  117. this.$http({
  118. url: this.$http.adornUrl('/manager/seller/list'),
  119. method: 'get',
  120. params: this.$http.adornParams({
  121. 'page': this.pageIndex,
  122. 'limit': this.pageSize,
  123. 'key': this.dataForm.key
  124. })
  125. }).then(({data}) => {
  126. if (data && data.code === 0) {
  127. this.dataList = data.page.list
  128. this.totalPage = data.page.totalCount
  129. } else {
  130. this.dataList = []
  131. this.totalPage = 0
  132. }
  133. this.dataListLoading = false
  134. })
  135. },
  136. // 每页数
  137. sizeChangeHandle (val) {
  138. this.pageSize = val
  139. this.pageIndex = 1
  140. this.getDataList()
  141. },
  142. // 当前页
  143. currentChangeHandle (val) {
  144. this.pageIndex = val
  145. this.getDataList()
  146. },
  147. // 多选
  148. selectionChangeHandle (val) {
  149. this.dataListSelections = val
  150. },
  151. // 新增 / 修改
  152. addOrUpdateHandle (id) {
  153. this.addOrUpdateVisible = true
  154. this.$nextTick(() => {
  155. this.$refs.addOrUpdate.init(id)
  156. })
  157. },
  158. // 删除
  159. deleteHandle (id) {
  160. var ids = id ? [id] : this.dataListSelections.map(item => {
  161. return item.sellerId
  162. })
  163. this.$confirm(`确定对[id=${ids.join(',')}]进行[${id ? '删除' : '批量删除'}]操作?`, '提示', {
  164. confirmButtonText: '确定',
  165. cancelButtonText: '取消',
  166. type: 'warning'
  167. }).then(() => {
  168. this.$http({
  169. url: this.$http.adornUrl('/manager/seller/delete'),
  170. method: 'post',
  171. data: this.$http.adornData(ids, false)
  172. }).then(({data}) => {
  173. if (data && data.code === 0) {
  174. this.$message({
  175. message: '操作成功',
  176. type: 'success',
  177. duration: 1500,
  178. onClose: () => {
  179. this.getDataList()
  180. }
  181. })
  182. } else {
  183. this.$message.error(data.msg)
  184. }
  185. })
  186. })
  187. }
  188. }
  189. }
  190. </script>

12.2 后端实现

12.2.1 服务层

  1. /**
  2. * 功能: 商家审核
  3. * 参数:
  4. * 返回值:
  5. * 时间: 2021/7/27 15:33
  6. */
  7. @Override
  8. public void updateStatus(String sellerId, String status) {
  9. SellerEntity entity = new SellerEntity();
  10. entity.setSellerId(sellerId);
  11. entity.setStatus(status);
  12. updateById(entity);
  13. }

12.2.2 控制层

  1. /**
  2. * 功能: 商家审核
  3. * 参数:
  4. * 返回值:
  5. * 时间: 2021/7/27 15:32
  6. */
  7. @RequestMapping("/updateStatus/{sellerId}/{status}")
  8. public R updateStatus(@PathVariable String sellerId,@PathVariable String status){
  9. sellerService.updateStatus(sellerId,status);
  10. return R.ok();
  11. }

12.3 最张效果

image.png