在线相册 ,图片上传, 基于 Spring boot vuejs element ui mysql 的项目

最近想学关于vuejs 和 element ui ,趁着工作之余开发了一个在线相册的项目,功能有 注册,登录,预览,各种中心,图片上传,我的资源,图片编辑等,,在此做一个分享吧。

Git 地址 :https://github.com/ryz-13997318136/photoalbum.git

https://github.com/ryz-13997318136/photoalbum.git
https://github.com/ryz-13997318136/photoalbum.git
https://github.com/ryz-13997318136/photoalbum.git

1 界面预览

1.1 注册页面

在线相册 ,图片上传, 基于 Spring boot vuejs element ui mysql 的项目

1.2 主页

在线相册 ,图片上传, 基于 Spring boot vuejs element ui mysql 的项目

1.3 个人中心

在线相册 ,图片上传, 基于 Spring boot vuejs element ui mysql 的项目

1.4 图片上传界面

在线相册 ,图片上传, 基于 Spring boot vuejs element ui mysql 的项目

1.5 我的资源

在线相册 ,图片上传, 基于 Spring boot vuejs element ui mysql 的项目

1.6 资源编辑

在线相册 ,图片上传, 基于 Spring boot vuejs element ui mysql 的项目

2 好了界面大概就这样的,很简单,其中大量的使用了 element ui,我觉得它是一个非常不错的css库,界面简洁,风格一致。很多控件他给我们做好了,我们只管使用,这种库文件很适合做某某网站的后台管理系统。好了下面开始贴代码

2.1 启动类

@ComponentScan(basePackages="com.ryz.photoalbum")
@EntityScan(basePackages="com.ryz.photoalbum.pojo")
@EnableJpaRepositories(basePackages="com.ryz.photoalbum.repository")
@SpringBootApplication
public class PhotoalbumApplication {

   public static void main(String[] args) {
      SpringApplication.run(PhotoalbumApplication.class, args);
   }
}

2.2 项目配置文件

spring.application.name=photo
server.servlet.context-path=/photo
server.port=8081

# 数据源配置
spring.datasource.url=jdbc:log4jdbc:mysql://118.25.65.113:3306/study
spring.datasource.username=root
spring.datasource.password=157123123
spring.datasource.driverClassName = net.sf.log4jdbc.DriverSpy
spring.jpa.database = MYSQL
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql = true
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect

# 定位模板的目录
spring.mvc.view.prefix=classpath:/templates/
# 给返回的页面添加后缀名
spring.mvc.view.suffix=.html
spring.thymeleaf.cache=false

basePath=D:\\image\\

2.3 系统控制层 ,用来处理首页的请求

@Controller
@RequestMapping("/index")
public class SysController {

    @Autowired
    UserService userService;

    @RequestMapping(value="/",method = RequestMethod.GET)
    public String index(Model model){
        return "index";
    }

    @RequestMapping(value="/main",method = RequestMethod.GET)
    public ModelAndView mian(String id){
        ModelAndView view = new ModelAndView();
        view.setViewName("main");
        view.addObject("cUser",userService.findPUserById(id));
        return view;
    }

}

2.4 文件控制层,用来处理文件的上传,下载,编辑,删除的请求

@Controller
@RequestMapping("/file")
@Configuration
public class FileController {

    @Resource
    private ResourceLoader resourceLoader;
    @Autowired
    private ImageService imageService;
    @Value("${basePath}")
    private  String basePath;

    @RequestMapping("/upload")
    @ResponseBody
    public String handleFileUpload(@RequestParam("file")MultipartFile file, String userId){

        if(file.isEmpty()){
            return "FAIL";
        }

        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        String location =df.format(new Date()) + System.getProperty("file.separator");
        // 判断文件夹是否存在,不存在则
        basePath = "all_image"+System.getProperty("file.separator");
        File targetFile = new File(basePath + location);
        if(!targetFile.exists()){
            targetFile.mkdirs();
        }
        String fileName = file.getOriginalFilename();
        fileName = fileName.length()>10?fileName.substring(fileName.length()-10):fileName;
        String url ="";
        try{
            Files.copy(file.getInputStream(), Paths.get(basePath + location, fileName), StandardCopyOption.REPLACE_EXISTING);
            url = location + fileName;
        }catch (Exception e){
            e.printStackTrace();
        }
        PImage image = new PImage();
        image.setId(String.valueOf(System.currentTimeMillis()));
        image.setUserId(userId);

        image.setImageName(fileName);
        image.setImageUrl(url);
        imageService.save(image);

        return url;

    }
    @RequestMapping(value="/{filePath}/{filename}",method = RequestMethod.GET)
    @ResponseBody
    public ResponseEntity<?> getFile(@PathVariable String filePath,@PathVariable String filename)  {
        System.out.println("filePath----------------"+filePath);
        System.out.println("filename--------------"+filename);
        basePath = "all_image"+System.getProperty("file.separator");
        System.out.println("basePath-------------"+ basePath);
        ResponseEntity.ok().contentType(MediaType.IMAGE_PNG);
        String os = System.getProperty("os.name");
        if(os.toLowerCase().startsWith("win")){
            return ResponseEntity.ok(resourceLoader.getResource("file:" + Paths.get(basePath +filePath+"\\"+ filename).toString()));
        }else{
            File file = new File("/usr/photoalbum/all_image/2018-06-04/22.png");
            return ResponseEntity.ok(resourceLoader.getResource("file:" + Paths.get("/usr/photoalbum/all_image/" +filePath+"/"+ filename).toString()));
        }
    }

    @RequestMapping(value="/getImageByUserId",method = RequestMethod.GET)
    @ResponseBody
    public List<PImage> getImageByUserId(@RequestParam String userId){
        return imageService.getImageByUserId(userId);
    }

    @RequestMapping(value="/getRandomImages",method = RequestMethod.GET)
    @ResponseBody
    public List<PImage> getRandomImages(@RequestParam String userId,@RequestParam String model){
        return imageService.getRandomImages(userId,model);
    }

    @RequestMapping(value="/editDesc",method = RequestMethod.GET)
    @ResponseBody
    public void editDesc(@RequestParam String id,@RequestParam String desc,@RequestParam String name){
        imageService.editDesc(id,desc,name);
    }

    @RequestMapping(value="/deleteImageById",method = RequestMethod.GET)
    @ResponseBody
    public void deleteImageById(@RequestParam String id){
        imageService.deleteImageById(id);
    }

}

2.5 用户控制层,用来处理用户的注册,登录,登出,用户修改请求

@Controller
@RequestMapping("/file")
@Configuration
public class FileController {

    @Resource
    private ResourceLoader resourceLoader;
    @Autowired
    private ImageService imageService;
    @Value("${basePath}")
    private  String basePath;

    @RequestMapping("/upload")
    @ResponseBody
    public String handleFileUpload(@RequestParam("file")MultipartFile file, String userId){

        if(file.isEmpty()){
            return "FAIL";
        }

        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        String location =df.format(new Date()) + System.getProperty("file.separator");
        // 判断文件夹是否存在,不存在则
        basePath = "all_image"+System.getProperty("file.separator");
        File targetFile = new File(basePath + location);
        if(!targetFile.exists()){
            targetFile.mkdirs();
        }
        String fileName = file.getOriginalFilename();
        fileName = fileName.length()>10?fileName.substring(fileName.length()-10):fileName;
        String url ="";
        try{
            Files.copy(file.getInputStream(), Paths.get(basePath + location, fileName), StandardCopyOption.REPLACE_EXISTING);
            url = location + fileName;
        }catch (Exception e){
            e.printStackTrace();
        }
        PImage image = new PImage();
        image.setId(String.valueOf(System.currentTimeMillis()));
        image.setUserId(userId);

        image.setImageName(fileName);
        image.setImageUrl(url);
        imageService.save(image);

        return url;

    }
    @RequestMapping(value="/{filePath}/{filename}",method = RequestMethod.GET)
    @ResponseBody
    public ResponseEntity<?> getFile(@PathVariable String filePath,@PathVariable String filename)  {
        System.out.println("filePath----------------"+filePath);
        System.out.println("filename--------------"+filename);
        basePath = "all_image"+System.getProperty("file.separator");
        System.out.println("basePath-------------"+ basePath);
        ResponseEntity.ok().contentType(MediaType.IMAGE_PNG);
        String os = System.getProperty("os.name");
        if(os.toLowerCase().startsWith("win")){
            return ResponseEntity.ok(resourceLoader.getResource("file:" + Paths.get(basePath +filePath+"\\"+ filename).toString()));
        }else{
            File file = new File("/usr/photoalbum/all_image/2018-06-04/22.png");
            return ResponseEntity.ok(resourceLoader.getResource("file:" + Paths.get("/usr/photoalbum/all_image/" +filePath+"/"+ filename).toString()));
        }
    }

    @RequestMapping(value="/getImageByUserId",method = RequestMethod.GET)
    @ResponseBody
    public List<PImage> getImageByUserId(@RequestParam String userId){
        return imageService.getImageByUserId(userId);
    }

    @RequestMapping(value="/getRandomImages",method = RequestMethod.GET)
    @ResponseBody
    public List<PImage> getRandomImages(@RequestParam String userId,@RequestParam String model){
        return imageService.getRandomImages(userId,model);
    }

    @RequestMapping(value="/editDesc",method = RequestMethod.GET)
    @ResponseBody
    public void editDesc(@RequestParam String id,@RequestParam String desc,@RequestParam String name){
        imageService.editDesc(id,desc,name);
    }

    @RequestMapping(value="/deleteImageById",method = RequestMethod.GET)
    @ResponseBody
    public void deleteImageById(@RequestParam String id){
        imageService.deleteImageById(id);
    }

}

2.6 pojo User set get 方法略,为了节省空间,不然 

@Entity
@Table(name = "p_user")
public class PUser implements Serializable {
    private String id;
    private String password;
    private String name;
    private String sex;
    private String mobile;
    private Date registerDate;
    private String headUrl;
}

2.6 pojo PImage set get 方法略,为了节省空间,不然太多了

@Entity
@Table(name = "p_image")
public class PImage {
    private String id;
    private String userId;
    private String imageUrl;
    private String imageDesc;
    private String imageName;

     }

2.7 UserRepository

@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    public void register(PUser user){
        user.setId(String.valueOf(System.currentTimeMillis()));
        user.setRegisterDate(new Date());
        userRepository.save(user);
    }

    public PUser login(String name,String password) throws Exception {
        PUser user = userRepository.findPUserByNameAndPassword(name,password);
        if(user == null){
            throw new Exception("找不到用户");
        }
        return user;
    }

    public PUser findPUserById(String id){
        return userRepository.findPUserById(id);
    }
    public void saveEdit(PUser user){
        userRepository.save(user);
    }

}

2.8 ImageService

@Service
public class ImageService {
    @Autowired
    private ImageRepository imageRepository;

    public void save(PImage image){
        imageRepository.save(image);
    }

    public List<PImage> getImageByUserId(String userId){
        return imageRepository.findPImagesByUserId(userId);
    }

    public List<PImage> getRandomImages(String userId,String model){
        if(model.equals("SJZS")){
            userId = "%";
        }
        List<String> list = imageRepository.getALLId(userId);
        int size = list.size();
        if(size == 0){
            return null;
        }
        List<String> id = new ArrayList<>();

        for(int i=0;i< 10;i++){
            int x=(int)(Math.random()*size);
            id.add(list.get(x));
        }
        return imageRepository.getRandomImages(id);
    }
    public void editDesc(String id,String desc,String name){
        Optional<PImage>  optional = imageRepository.findById(id);
        PImage pImage = optional.get();
        pImage.setImageDesc(desc);
        pImage.setImageName(name);
        imageRepository.save(pImage);
    }
    public void deleteImageById(String id){
        imageRepository.deleteById(id);
    }

}

2.9 UserRepository

@Repository
@Table(name="p_user")
public interface UserRepository extends CrudRepository<PUser,String> {

    PUser findPUserByNameAndPassword(String name,String password);

    PUser findPUserById(String id);

}

2.10 ImageRepository

@Repository
@Table(name="p_image")
public interface ImageRepository extends CrudRepository<PImage,String> {

    List<PImage> findPImagesByUserId(String userId);

    @Query("select image.id from PImage image where image.userId like ?1")
    List<String> getALLId(String userId);

    @Query("select image from PImage image where image.id in ?1")
    List<PImage> getRandomImages(List<String> list);
}

2.11 下面开始贴界面的html,js ,css 文件

index.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>Photo_index</title>
    <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
    <script src="https://unpkg.com/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/element-ui/lib/index.js"></script>
    <script src="//cdn.bootcss.com/vue-resource/1.0.3/vue-resource.min.js"></script>
</head>
<body style="background-color: azure;">
<div style="text-align: center;">在线相册</div>
<div id="vm1" style=" width: 100%;height: 137px;margin-top: 10px;">
    <div v-if="register" style="margin-top: 300px;text-align: center;">
        用户注册
        <el-row>
            <el-col :span="8" :offset="8">
                <el-form :model="registerUser" status-icon :rules="registerRule" ref="registerUser">
                    <el-form-item label="姓名" prop="name">
                        <el-input v-model="registerUser.name" auto-complete="off" clearable maxlength="10"></el-input>
                    </el-form-item>
                    <el-form-item label="手机号码" prop="mobile">
                        <el-input v-model="registerUser.mobile" auto-complete="off" clearable maxlength="13"></el-input>
                    </el-form-item>
                    <el-form-item label="密码" prop="password">
                        <el-input type="password" v-model="registerUser.password" auto-complete="off" clearable maxlength="10"></el-input>
                    </el-form-item>
                    <el-form-item label="确认密码" prop="password2">
                        <el-input type="password" v-model="registerUser.password2" auto-complete="off" clearable maxlength="10"></el-input>
                    </el-form-item>
                    <el-form-item>
                        <el-button type="success" @click="registerOk()">注册</el-button>
                        <el-button type="success" @click="register=false;index=true">返回</el-button>
                        <el-button type="success" @click="registerRest()">重置</el-button>
                    </el-form-item>
                </el-form>

            </el-col>
        </el-row>
    </div>

    <div v-if="login" style="margin-top: 300px;text-align: center;">
        用户登录
        <el-row>
            <el-col :span="8" :offset="8">

                <el-form :model="loginUser">
                    <el-form-item label="姓名" >
                        <el-input v-model="loginUser.loginName" clearable maxlength="10"> </el-input>
                    </el-form-item>
                    <el-form-item label="密码" >
                        <el-input type="password" v-model="loginUser.loginPassword"  clearable maxlength="10"></el-input>
                    </el-form-item>
                    <el-form-item>
                        <el-button type="success" @click="loginOk()">登录</el-button>
                        <el-button type="success" @click="login=false;index=true">返回</el-button>
                        <el-button type="success" @click="loginRest()">重置</el-button>
                    </el-form-item>
                </el-form>

            </el-col>
        </el-row>

    </div>
    <div v-if="index" style="margin-top: 300px;text-align: center;">
        <el-row>
            <el-col :span="8" :offset="8">
                <el-form>
                    <el-form-item>
                        <el-button type="success" @click="register = true;login = false;index=false">注册</el-button>
                        <el-button type="success" @click="login=true;register = false;index=false">登录</el-button>
                    </el-form-item>
                </el-form>
            </el-col>
        </el-row>
    </div>

</div>
<script th:src="@{/js/index.js}"></script>
</body>
</html>

index.js

//Vue.http.options.emulateHTTP = true;
var vm = new Vue({
        el: '#vm1',
        data: {
            // index
            index:true,
            // login
            login : false,
            loginUser:{'loginName':'','loginPassword':''},
            // register
            register:false,
            registerUser:{'name':'','password':'','password2':'','mobile':''},
            //validateName1:this.validateName,
            registerRule:{
                na: [{ validator: this.validateName1, trigger: 'blur' }],
                password: [{ validator: this.validatePassword, trigger: 'blur' }],
                password2: [{ validator: this.validatePassword2, trigger: 'blur' }],
                mobile: [{ validator: this.checkMobile, trigger: 'blur' }]
            }

        },
        methods:{
            registerOk:function(){
                this.$http.post("/photo/user/register",this.registerUser)
                    .then(function (response) {
                        this.$message({
                            type: 'success',
                            message: '注册成功,赶快去登录吧!'
                        });
                    })
                    .catch(function (response) { console.error(response); });
            },
            registerRest:function(){
                this.registerUser.name = '';
                this.registerUser.password='';
                this.registerUser.mobile=''
            },
            loginOk:function(){
                this.$http.get("/photo/user/login",{params: {name:this.loginUser.loginName,password:this.loginUser.loginPassword}})
                    .then(function (response) {
                        console.log(response);
                        var user = response.body;
                        if(user ==null){
                            this.$message({
                                type: 'success',
                                message: '用户名密码有误,登录失败!'
                            });
                        }else{
                            window.location.href="/photo/index/main?id="+user.id;
                        }
                    })
                    .catch(function (response) { console.error(response); });
            },
            loginRest:function(){
                this.loginName = '';
                this.loginPassword = '';
            },
            // 注册校验方法
            validateName:function(rule, value, callback){
                if (value === '') {
                    callback(new Error('请输入用户名'));
                } else {
                    callback();
                }
            },
            validatePassword:function(rule, value, callback){
                if (value === '') {
                    callback(new Error('请输入密码'));
                } else {
                    if (this.registerUser.password2 !== '') {
                        this.$refs.registerUser.validateField('password2');
                    }
                    callback();
                }
            },
            validatePassword2:function(rule, value, callback){
                if (value === '') {
                    callback(new Error('请再次输入密码'));
                } else {
                    if (this.registerUser.password !== value) {
                        callback(new Error('两次输入密码不一致!'));
                    }else{
                        callback();
                    }
                }
            },
            checkMobile:function(rule, value, callback){
                if (value === '') {
                    callback(new Error('请输入手机号'));
                } else {
                    if(value.length !=11){
                        callback(new Error('手机号不合法'));
                    }else {
                            callback();
                    }
                }
            },

        },
        mounted: function () {
            var registerRule ={
                name: [{ required: true, message: '请输入名称', trigger: 'blur' },{ validator: this.validateName, trigger: 'blur' }],
                password: [{ validator: this.validatePassword, trigger: 'blur' }],
                password2: [{ validator: this.validatePassword2, trigger: 'blur' }],
                mobile: [{ validator: this.checkMobile, trigger: 'blur' }]
            }
            this.registerRule = registerRule;
        },
        watch:{

        },
        updated:function(){
            //this.registerRule.name[0].validator=this.validateName
        },
    })

main.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>Photo_main</title>
    <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
    <script src="https://unpkg.com/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/element-ui/lib/index.js"></script>
    <script src="//cdn.bootcss.com/vue-resource/1.0.3/vue-resource.min.js"></script>
    <link  th:href="@{/css/main.css}" rel="stylesheet" />
</head>
<body>

<div id="vm2">

    <el-row>
        <el-col :span="8">
            <p>当前用户:{{ user.name }}</p>
        </el-col>
        <el-col :span="8" :offset="8">
            <el-button type="primary" @click="logout">退出登录</el-button>
        </el-col>
    </el-row>

    <el-row>
        <el-tabs type="border-card"  @tab-click="tabClick">
            <el-tab-pane style="height: 500px;">
                <span slot="label"><i class="el-icon-date"></i>相册展示</span>
                <el-row :gutter="20">
                    <el-col :span="16">
                        <div  style="width: 600px;">
                            <el-carousel :interval="5000" arrow="always" height="400px" @change="carouselChange">
                                <el-carousel-item v-for="item in pictures">
                                    <img  height="390px" width="600px" :src="base+item.imageUrl"/>
                                </el-carousel-item>
                            </el-carousel>
                        </div>
                    </el-col>
                    <el-col :span="8"><div class="grid-content bg-purple">{{pictureDesc}}</div></el-col>
                </el-row>

                <br/>
                <el-form :inline="true" class="demo-form-inline">
                    <el-form-item>
                        <el-button type="primary" @click="getRandomImages('SJZS')">刷新图片</el-button>
                    </el-form-item>
                    <el-form-item label="查看模式">
                        <el-select v-model="showModel" placeholder="选择一种模式" @change="showModelSelect">
                            <el-option label="随机展示" value="SJZS"></el-option>
                            <el-option label="只看自己" value="ZKZJ"></el-option>
                        </el-select>
                    </el-form-item>
                </el-form>
            </el-tab-pane>

            <el-tab-pane label="个人中心" style="height: 400px;">
                <el-form ref="user" :model="user" label-width="80px">
                    <el-form-item label="用户标识"> <el-input v-model="user.id" :disabled="true"></el-input> </el-form-item>
                    <el-form-item label="用户名称"> <el-input v-model="user.name" maxlength="10"></el-input> </el-form-item>
                    <el-form-item label="用户密码"> <el-input v-model="user.password" maxlength="10"></el-input> </el-form-item>
                    <el-form-item label="手机号码"> <el-input v-model="user.mobile" maxlength="13"></el-input> </el-form-item>
                    <el-form-item label="用户性别">
                        <el-radio-group v-model="user.sex">
                            <el-radio label=""></el-radio>
                            <el-radio label=""></el-radio>
                        </el-radio-group>
                    </el-form-item>
                    <el-form-item>
                        <el-button type="primary" @click="saveUser">立即保存</el-button>
                        <el-button type="primary" @click="editUserRest">重置</el-button>
                    </el-form-item>
                </el-form>
            </el-tab-pane>
            <el-tab-pane label="图片上传" style="height: 400px;" >
                <el-upload
                        :data={'userId':user.id}
                        action="../file/upload"
                        list-type="picture-card"
                        :on-preview="handlePictureCardPreview"
                        :on-remove="handleRemove">
                    <i class="el-icon-plus"></i>
                </el-upload>
                <el-dialog :visible.sync="dialogVisible">
                    <img width="100%" :src="dialogImageUrl" alt="">
                </el-dialog>
            </el-tab-pane>
            <el-tab-pane label="我的资源" style="height: 400px;">
                <div style="height: 390px;overflow-y: auto;">
                    <li v-for="item in myImages">
                        <div id="main">
                            <div style="margin-top: 10px; margin-bottom: 10px;">
                                <img :src="base + item.imageUrl" th:width="100" height="100" :id="item.id" @click="imageClick(item.id)" />
                                <p >{{item.imageName}}</p>
                            </div>
                            <div style="margin-top: 10px; margin-bottom: 10px;background: #00b8ff21;width: 762px;">描述:{{item.imageDesc}}</div>
                        </div>
                    </li>
                </div>
            </el-tab-pane>
        </el-tabs>
    </el-row>

    <el-dialog title="图片编辑" :visible="dialogFormVisible">
        <el-form :model="dialogForm">
            <el-form-item label="图片标识" :label-width="formLabelWidth">
                <el-input  v-model="dialogForm.id" :disabled="true"> </el-input>
            </el-form-item>
            <el-form-item label="图片名称" :label-width="formLabelWidth">
                <el-input  v-model="dialogForm.imageName" clearable maxlength="10"> </el-input>
            </el-form-item>
            <el-form-item label="描述文本" :label-width="formLabelWidth">
                <el-input  type="textarea" :rows="2" v-model="dialogForm.imageDesc" auto-complete="off" clearable maxlength="200"></el-input>
            </el-form-item>
        </el-form>
        <div slot="footer" class="dialog-footer">
            <el-button @click="deleteImage">删除这一张图片</el-button>
            <el-button @click="dialogFormVisible = false">取 消</el-button>
            <el-button type="primary" @click="dialogFormOk">保存修改</el-button>
        </div>
    </el-dialog>

</div>
<script th:src="@{/js/main.js}"></script>

<script th:inline="javascript">
    /*<![CDATA[*/
    var user = [[${cUser}]];
    console.log(user);
    vm._data.user = user;
    for(var key in user){
        vm._data.userBack[key] = user[key];
    }
    /*]]>*/
</script>
</body>

</html>

main.js

Vue.http.options.emulateHTTP = true;
var vm = new Vue({
    el: '#vm2',
    data: {
        // 图片展示
        pictures:[],
        user:{'id':'','name':'','password':'','mobile':'','sex':'','registerDate':'','headUrl':''},
        userBack:{},
        showModel:'',
        pictureDesc:'',
        // 图片上传参数
        dialogImageUrl: '',
        dialogVisible: false,
        // 我的资源
        myImages:[],
        base:'../file/',
        dialogFormVisible:false,
        dialogForm:{'id':'','imageDesc':'','imageName':''},
        formLabelWidth:'120px'
    },
    methods:{
        logout:function(){
            var _this = this;
            this.$confirm('确定要退出当前系统吗?', '提示', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning',
                callback: function(id){
                    if(id == 'confirm'){
                        window.location.href="/photo/user/logout";
                    }else{
                        _this.$message({
                            type: 'info',
                            message: '已取消'
                        });
                    }
                }
            });
        },

        carouselChange:function(index){
            this.pictureDesc = this.pictures[index].imageDesc;
        },
        deleteImage:function(){
            this.$http.get("/photo/file/deleteImageById",{params: {id:this.dialogForm.id}})
                .then(function (response) {
                    this.$message({
                        type: 'success',
                        message: '删除成功!'
                    });
                    this.dialogFormVisible = false;
                    this.getMyImage();
                })
                .catch(function (response) { console.error(response); });
        },
        dialogFormOk:function(){
            this.$http.get("/photo/file/editDesc",
                {params: {id:this.dialogForm.id,desc:this.dialogForm.imageDesc,name:this.dialogForm.imageName}})
                .then(function (response) {
                    this.$message({
                        type: 'success',
                        message: '修改成功!'
                    });
                    this.dialogFormVisible = false;
                    //this.getMyImage();
                })
                .catch(function (response) { console.error(response); });
        },
        imageClick:function(id){
            this.dialogFormVisible = true;
            for(index in this.myImages){
                if(this.myImages[index].id == id){
                    this.dialogForm = this.myImages[index];
                    break;
                }
            }
        },
        showModelSelect:function (model) {
            this.getRandomImages(model);
        },
        getRandomImages:function(model){
            this.$http.get("/photo/file/getRandomImages",{params: {userId:this.user.id,model:model}})
                .then(function (response) {
                    console.log(response);
                    this.pictures = response.body;
                })
                .catch(function (response) { console.error(response); });
        },
        tabClick:function(tab){
            if(tab.index==3){
                this.getMyImage();
            }
        },
        getMyImage:function(){
            this.$http.get("/photo/file/getImageByUserId",{params: {userId:this.user.id}})
                .then(function (response) {
                    console.log(response);
                    this.myImages = response.body;
                })
                .catch(function (response) { console.error(response); });
        },
        handleRemove:function(file, fileList) {
            console.log(file, fileList);
        },
        handlePictureCardPreview:function(file) {
            this.dialogImageUrl = file.url;
            this.dialogVisible = true;
        },
        saveUser:function(){
            this.$http.post("/photo/user/saveEdit",this.user)
                .then(function (response) {
                    this.$message({
                        type: 'success',
                        message: '保存成功!'
                    });
                })
                .catch(function (response) { console.error(response); });
        },
        editUserRest:function(){
            for(var key in this.userBack){
                this.user[key] = this.userBack[key];
            }
        }
    },
    mounted: function () {
        // 加载首页随机图片
        this.getRandomImages('SJZS');
    },
    watch:{

    }
})

main.css

.avatar-uploader .el-upload {
    border: 1px dashed #d9d9d9;
    border-radius: 6px;
    cursor: pointer;
    position: relative;
    overflow: hidden;
}
.avatar-uploader .el-upload:hover {
    border-color: #409EFF;
}
.avatar-uploader-icon {
    font-size: 28px;
    color: #8c939d;
    width: 178px;
    height: 178px;
    line-height: 178px;
    text-align: center;
}
.avatar {
    width: 178px;
    height: 178px;
    display: block;
}

.el-upload--picture-card {
    background-color: #fbfdff;
    border: 1px dashed #c0ccda;
    border-radius: 6px;
    box-sizing: border-box;
    width: 148px;
    height: 148px;
    cursor: pointer;
    line-height: 146px;
    vertical-align: top;
}
el-upload--picture-card i {
    font-size: 28px;
    color: #8c939d;
}

#main {
    width: auto;
    height: 150px;
    border: 1px solid #c3c3c3;
    display: -webkit-flex; /* Safari */
    -webkit-justify-content: space-around; /* Safari 6.1+ */
    display: flex;
    justify-content: space-around;
}

2.12 最后贴上 pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>

   <groupId>com.ryz</groupId>
   <artifactId>photoalbum</artifactId>
   <version>0.0.1-SNAPSHOT</version>
   <packaging>jar</packaging>

   <name>photoalbum</name>
   <description>Demo project for Spring Boot</description>

   <parent>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-parent</artifactId>
      <version>2.0.2.RELEASE</version>
      <relativePath/> <!-- lookup parent from repository -->
   </parent>

   <properties>
      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
      <java.version>1.8</java.version>
   </properties>

   <dependencies>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-data-jpa</artifactId>
      </dependency>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-thymeleaf</artifactId>
      </dependency>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-web</artifactId>
      </dependency>

      <dependency>
         <groupId>mysql</groupId>
         <artifactId>mysql-connector-java</artifactId>
         <version>5.1.44</version>
      </dependency>
      <dependency>
         <groupId>com.googlecode.log4jdbc</groupId>
         <artifactId>log4jdbc</artifactId>
         <version>1.2</version>
      </dependency>

      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-test</artifactId>
         <scope>test</scope>
      </dependency>
   </dependencies>

   <build>
      <plugins>
         <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <executions>
               <execution>
                  <goals>
                     <goal>repackage</goal>
                  </goals>
               </execution>
            </executions>
         </plugin>
      </plugins>
   </build>

</project>
3 终于贴完代码了,总结一下吧,主要使用element ui 的 el-carousel 跑马灯,你可以监听他的change事件做你想做的事情,el-upload 文件上传控件,他是一个非常不错的空间,界面好看并且有预览功能,进度条。登录注册时使用了el-form 中的校验规则,是一个非常好用的功能。js 中大量的使用了 vuejs 的特性,以及它的什么周期调用的各种钩子。之前项目是运行在我本地的,后面又放在腾讯云服务器上去,所以在文件上传的地方稍微判断了一下是什么Windows系统还是Linux系统,因为两种系统的获取文件不同。发现在腾讯云上获取上传的图片是如果采用相对路径不能获取(权限都是777),后来改成绝对路径了。这里的文件存储在本地一定不是可以的方案,后面有时间找个文件服务器吧。