工程课 SpringBoot-5.2. 上课笔记

master
barney 2 years ago
parent 5223e513d6
commit 42074fb132
  1. 4
      backend/src/main/java/com/kob/backend/controller/pojo/Bot.java
  2. 96
      web/package-lock.json
  3. 2
      web/package.json
  4. 343
      web/src/views/user/bot/UserBotIndexView.vue

@ -25,8 +25,8 @@ public class Bot {
private String description;
private String content;
private Integer rating;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "Asia/Shanghai")
private Date createTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "Asia/Shanghai")
private Date modifyTime;
}

@ -8,11 +8,13 @@
"name": "web",
"version": "0.1.0",
"dependencies": {
"@popperjs/core": "^2.11.5",
"bootstrap": "^5.1.3",
"core-js": "^3.8.3",
"jquery": "^3.6.0",
"vue": "^3.2.13",
"vue-router": "^4.0.3",
"vue3-ace-editor": "^2.2.2",
"vuex": "^4.0.0"
},
"devDependencies": {
@ -1931,8 +1933,7 @@
"node_modules/@popperjs/core": {
"version": "2.11.5",
"resolved": "https://registry.npmmirror.com/@popperjs/core/-/core-2.11.5.tgz",
"integrity": "sha512-9X2obfABZuDVLCgPK9aX0a/x4jaOEweTTWE2+9sr0Qqqevj2Uv5XorvusThmc9XGYpS9yI+fhh8RTafBtGposw==",
"peer": true
"integrity": "sha512-9X2obfABZuDVLCgPK9aX0a/x4jaOEweTTWE2+9sr0Qqqevj2Uv5XorvusThmc9XGYpS9yI+fhh8RTafBtGposw=="
},
"node_modules/@sideway/address": {
"version": "4.1.4",
@ -3118,6 +3119,11 @@
"node": ">= 0.6"
}
},
"node_modules/ace-builds": {
"version": "1.8.1",
"resolved": "https://registry.npmmirror.com/ace-builds/-/ace-builds-1.8.1.tgz",
"integrity": "sha512-wjEQ4khMQYg9FfdEDoOtqdoHwcwFL48H0VB3te5b5A3eqHwxsTw8IX6+xzfisgborIb8dYU+1y9tcmtGFrCPIg=="
},
"node_modules/acorn": {
"version": "8.7.1",
"resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.7.1.tgz",
@ -8839,6 +8845,11 @@
"integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
"dev": true
},
"node_modules/resize-observer-polyfill": {
"version": "1.5.1",
"resolved": "https://registry.npmmirror.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
"integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg=="
},
"node_modules/resolve": {
"version": "1.22.1",
"resolved": "https://registry.npmmirror.com/resolve/-/resolve-1.22.1.tgz",
@ -10176,6 +10187,16 @@
"integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==",
"dev": true
},
"node_modules/vue3-ace-editor": {
"version": "2.2.2",
"resolved": "https://registry.npmmirror.com/vue3-ace-editor/-/vue3-ace-editor-2.2.2.tgz",
"integrity": "sha512-fZ6OWosbU+odLrtrcGC/536QjCigujYJB0Hf6/tBp+ef/ohTadwQAqyBlVzOmvrmzZyubphpV9zkaZcx5Fuivw==",
"dependencies": {
"ace-builds": "^1.4.13",
"resize-observer-polyfill": "^1.5.1",
"vue": "^3.2.26"
}
},
"node_modules/vuex": {
"version": "4.0.2",
"resolved": "https://registry.npmmirror.com/vuex/-/vuex-4.0.2.tgz",
@ -12228,8 +12249,7 @@
"@popperjs/core": {
"version": "2.11.5",
"resolved": "https://registry.npmmirror.com/@popperjs/core/-/core-2.11.5.tgz",
"integrity": "sha512-9X2obfABZuDVLCgPK9aX0a/x4jaOEweTTWE2+9sr0Qqqevj2Uv5XorvusThmc9XGYpS9yI+fhh8RTafBtGposw==",
"peer": true
"integrity": "sha512-9X2obfABZuDVLCgPK9aX0a/x4jaOEweTTWE2+9sr0Qqqevj2Uv5XorvusThmc9XGYpS9yI+fhh8RTafBtGposw=="
},
"@sideway/address": {
"version": "4.1.4",
@ -12751,8 +12771,7 @@
"version": "5.0.8",
"resolved": "https://registry.npmmirror.com/@vue/cli-plugin-vuex/-/cli-plugin-vuex-5.0.8.tgz",
"integrity": "sha512-HSYWPqrunRE5ZZs8kVwiY6oWcn95qf/OQabwLfprhdpFWAGtLStShjsGED2aDpSSeGAskQETrtR/5h7VqgIlBA==",
"dev": true,
"requires": {}
"dev": true
},
"@vue/cli-service": {
"version": "5.0.8",
@ -13253,6 +13272,11 @@
"negotiator": "0.6.3"
}
},
"ace-builds": {
"version": "1.8.1",
"resolved": "https://registry.npmmirror.com/ace-builds/-/ace-builds-1.8.1.tgz",
"integrity": "sha512-wjEQ4khMQYg9FfdEDoOtqdoHwcwFL48H0VB3te5b5A3eqHwxsTw8IX6+xzfisgborIb8dYU+1y9tcmtGFrCPIg=="
},
"acorn": {
"version": "8.7.1",
"resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.7.1.tgz",
@ -13263,15 +13287,13 @@
"version": "1.8.0",
"resolved": "https://registry.npmmirror.com/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz",
"integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==",
"dev": true,
"requires": {}
"dev": true
},
"acorn-jsx": {
"version": "5.3.2",
"resolved": "https://registry.npmmirror.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
"integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
"dev": true,
"requires": {}
"dev": true
},
"acorn-walk": {
"version": "8.2.0",
@ -13330,8 +13352,7 @@
"version": "3.5.2",
"resolved": "https://registry.npmmirror.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
"integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
"dev": true,
"requires": {}
"dev": true
},
"ansi-colors": {
"version": "4.1.3",
@ -13619,8 +13640,7 @@
"bootstrap": {
"version": "5.1.3",
"resolved": "https://registry.npmmirror.com/bootstrap/-/bootstrap-5.1.3.tgz",
"integrity": "sha512-fcQztozJ8jToQWXxVuEyXWW+dSo8AiXWKwiSSrKWsRB/Qt+Ewwza+JWoLKiTuQLaEPhdNAJ7+Dosc9DOIqNy7Q==",
"requires": {}
"integrity": "sha512-fcQztozJ8jToQWXxVuEyXWW+dSo8AiXWKwiSSrKWsRB/Qt+Ewwza+JWoLKiTuQLaEPhdNAJ7+Dosc9DOIqNy7Q=="
},
"brace-expansion": {
"version": "1.1.11",
@ -14148,8 +14168,7 @@
"version": "6.3.0",
"resolved": "https://registry.npmmirror.com/css-declaration-sorter/-/css-declaration-sorter-6.3.0.tgz",
"integrity": "sha512-OGT677UGHJTAVMRhPO+HJ4oKln3wkBTwtDFH0ojbqm+MJm6xuDMHp2nkhh/ThaBqq20IbraBQSWKfSLNHQO9Og==",
"dev": true,
"requires": {}
"dev": true
},
"css-loader": {
"version": "6.7.1",
@ -14320,8 +14339,7 @@
"version": "3.1.0",
"resolved": "https://registry.npmmirror.com/cssnano-utils/-/cssnano-utils-3.1.0.tgz",
"integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==",
"dev": true,
"requires": {}
"dev": true
},
"csso": {
"version": "4.2.0",
@ -15777,8 +15795,7 @@
"version": "5.1.0",
"resolved": "https://registry.npmmirror.com/icss-utils/-/icss-utils-5.1.0.tgz",
"integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==",
"dev": true,
"requires": {}
"dev": true
},
"ieee754": {
"version": "1.2.1",
@ -17150,29 +17167,25 @@
"version": "5.1.2",
"resolved": "https://registry.npmmirror.com/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz",
"integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==",
"dev": true,
"requires": {}
"dev": true
},
"postcss-discard-duplicates": {
"version": "5.1.0",
"resolved": "https://registry.npmmirror.com/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz",
"integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==",
"dev": true,
"requires": {}
"dev": true
},
"postcss-discard-empty": {
"version": "5.1.1",
"resolved": "https://registry.npmmirror.com/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz",
"integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==",
"dev": true,
"requires": {}
"dev": true
},
"postcss-discard-overridden": {
"version": "5.1.0",
"resolved": "https://registry.npmmirror.com/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz",
"integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==",
"dev": true,
"requires": {}
"dev": true
},
"postcss-loader": {
"version": "6.2.1",
@ -17262,8 +17275,7 @@
"version": "3.0.0",
"resolved": "https://registry.npmmirror.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz",
"integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==",
"dev": true,
"requires": {}
"dev": true
},
"postcss-modules-local-by-default": {
"version": "4.0.0",
@ -17298,8 +17310,7 @@
"version": "5.1.0",
"resolved": "https://registry.npmmirror.com/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz",
"integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==",
"dev": true,
"requires": {}
"dev": true
},
"postcss-normalize-display-values": {
"version": "5.1.0",
@ -17736,6 +17747,11 @@
"integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
"dev": true
},
"resize-observer-polyfill": {
"version": "1.5.1",
"resolved": "https://registry.npmmirror.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
"integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg=="
},
"resolve": {
"version": "1.22.1",
"resolved": "https://registry.npmmirror.com/resolve/-/resolve-1.22.1.tgz",
@ -18825,6 +18841,16 @@
"integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==",
"dev": true
},
"vue3-ace-editor": {
"version": "2.2.2",
"resolved": "https://registry.npmmirror.com/vue3-ace-editor/-/vue3-ace-editor-2.2.2.tgz",
"integrity": "sha512-fZ6OWosbU+odLrtrcGC/536QjCigujYJB0Hf6/tBp+ef/ohTadwQAqyBlVzOmvrmzZyubphpV9zkaZcx5Fuivw==",
"requires": {
"ace-builds": "^1.4.13",
"resize-observer-polyfill": "^1.5.1",
"vue": "^3.2.26"
}
},
"vuex": {
"version": "4.0.2",
"resolved": "https://registry.npmmirror.com/vuex/-/vuex-4.0.2.tgz",
@ -19136,8 +19162,7 @@
"version": "8.8.0",
"resolved": "https://registry.npmmirror.com/ws/-/ws-8.8.0.tgz",
"integrity": "sha512-JDAgSYQ1ksuwqfChJusw1LSJ8BizJ2e/vVu5Lxjq3YvNJNlROv1ui4i+c/kUUrPheBvQl4c5UbERhTwKa6QBJQ==",
"dev": true,
"requires": {}
"dev": true
}
}
},
@ -19264,8 +19289,7 @@
"version": "7.5.8",
"resolved": "https://registry.npmmirror.com/ws/-/ws-7.5.8.tgz",
"integrity": "sha512-ri1Id1WinAX5Jqn9HejiGb8crfRio0Qgu8+MtL36rlTA6RLsMdWt1Az/19A2Qij6uSHUMphEFaTKa4WG+UNHNw==",
"dev": true,
"requires": {}
"dev": true
},
"y18n": {
"version": "5.0.8",

@ -8,11 +8,13 @@
"lint": "vue-cli-service lint"
},
"dependencies": {
"@popperjs/core": "^2.11.5",
"bootstrap": "^5.1.3",
"core-js": "^3.8.3",
"jquery": "^3.6.0",
"vue": "^3.2.13",
"vue-router": "^4.0.3",
"vue3-ace-editor": "^2.2.2",
"vuex": "^4.0.0"
},
"devDependencies": {

@ -1,97 +1,278 @@
<template>
<ContentField>
我的Bot
</ContentField>
<div class="container">
<div class="row">
<div class="col-3">
<div class="card" style="margin-top: 30px">
<div class="card-body">
<img :src="$store.state.user.photo" alt="">
</div>
</div>
</div>
<div class="col-9">
<div class="card" style="margin-top: 30px">
<div class="card-header" >
<span style="font-size: 20px; font-weight: bold ">我的bots</span>
<button type="button" class="btn btn-primary float-end" btn-sm data-bs-toggle="modal" data-bs-target="#add_bot_btn">创建bot</button>
<!-- Modal -->
<div class="modal fade" id="add_bot_btn" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">创建新的bot</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form>
<div class="mb-3">
<label for="add_bot_title" class="form-label">bot名称</label>
<input type="text" v-model="new_bot.title" class="form-control" id="add_bot_title" placeholder="请输入新bot的名称">
</div>
<div class="mb-3">
<label for="add_bot_description" class="form-label">bot简介</label>
<textarea class="form-control" v-model="new_bot.description" id="add_bot_description" rows= "3" placeholder="请输入新bot的简介"></textarea>
</div>
<div class="mb-3">
<label for="add_bot_code" class="form-label">bot的代码</label>
<VAceEditor
v-model:value="new_bot.content"
@init="editorInit"
lang="c_cpp"
theme="textmate"
:options="{fontSize: 16}"
style="height: 300px" />
</div>
</form>
</div>
<div class="modal-footer">
<div class="error_msg">{{ new_bot.error_msg }}</div>
<button type="button" class="btn btn-success" @click="add_bot" btn-sm>创建</button>
<button type="button" class="btn btn-danger" btn-sm @click="cancel_add">取消</button>
</div>
</div>
</div>
</div>
</div>
<div class="card-body">
<table class="table table-striped table-hover">
<!--表头-->
<thead>
<tr>
<th>名称</th>
<th>创建时间</th>
<th>操作</th>
</tr>
</thead>
<!--内容-->
<tbody>
<tr v-for="bot in bots" :key="bot.id">
<td>{{bot.title}}</td>
<td>{{bot.createTime}}</td>
<td>
<button type="button" class="btn btn-success" btn-sm style="margin-right: 10px" data-bs-toggle="modal" :data-bs-target="'#update-bot-btn-'+bot.id" >修改</button>
<button type="button" class="btn btn-danger" btn-sm @click="remove_bot(bot)">删除</button>
<div class="modal fade" :id="'update-bot-btn-'+bot.id" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">修改bot信息</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form>
<div class="mb-3">
<label for="add_bot_title" class="form-label">bot名称</label>
<input type="text" v-model="bot.title" class="form-control" id="add_bot_title" >
</div>
<div class="mb-3">
<label for="add_bot_description" class="form-label">bot简介</label>
<textarea class="form-control" v-model="bot.description" id="add_bot_description" rows= "3" ></textarea>
</div>
<div class="mb-3">
<label for="add_bot_code" class="form-label">bot的代码</label>
<VAceEditor
v-model:value="bot.content"
@init="editorInit"
lang="c_cpp"
theme="textmate"
:options="{fontSize: 16}"
style="height: 300px" />
</div>
</form>
</div>
<div class="modal-footer">
<div class="error_msg">{{ bot.error_msg }}</div>
<button type="button" class="btn btn-success" @click="update_bot(bot)" btn-sm>保存修改</button>
<button type="button" class="btn btn-danger" btn-sm @click="cancel_update(bot)">取消</button>
</div>
</div>
</div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import ContentField from '../../../components/ContentField.vue'
import $ from "jquery";
import { useStore } from "vuex";
import { ref,reactive } from "vue"
import $ from 'jquery'
import { useStore } from "vuex"
import {Modal} from "bootstrap/dist/js/bootstrap"
import { VAceEditor } from 'vue3-ace-editor';
import ace from 'ace-builds';
export default {
components: {
ContentField
components:{
VAceEditor,
},
setup() {
ace.config.set(
"basePath",
"https://cdn.jsdelivr.net/npm/ace-builds@" + require('ace-builds').version + "/src-noconflict/");
const store = useStore();
// bot
// $.ajax({
// url: "http://localhost:3000/user/bot/add/",
// type: "POST",
// data: {
// title: "bot",
// description: "bot",
// content: "bot",
// },
// headers:{
// Authorization: "Bearer " + store.state.user.token,
// },
// success(resp) {
// console.log(resp);
// },
// error(resp) {
// console.log(resp);
// }
// })
// bot
// $.ajax({
// url: "http://localhost:3000/user/bot/remove/",
// type: "POST",
// data: {
// bot_id: 10,
// },
// headers:{
// Authorization: "Bearer " + store.state.user.token,
// },
// success(resp) {
// console.log(resp);
// },
// error(resp) {
// console.log(resp);
// }
// })
// bot
// $.ajax({
// url: "http://localhost:3000/user/bot/update/",
// type: "POST",
// data: {
// bot_id: 2,
// title: "bot()",
// description: "bot()",
// content: "bot()",
// },
// headers:{
// Authorization: "Bearer " + store.state.user.token,
// },
// success(resp) {
// console.log(resp);
// },
// error(resp) {
// console.log(resp);
// }
// })
// bot
$.ajax({
url: "http://localhost:3000/user/bot/getlist/",
type: "GET",
headers:{
Authorization: "Bearer " + store.state.user.token,
},
success(resp) {
console.log(resp);
},
error(resp) {
console.log(resp);
}
let bots = ref([]) // bot
const new_bot = reactive({
title: "",
description: "",
content: "",
error_msg: "",
})
const cancel_update = (bot)=> {
Modal.getInstance("#update-bot-btn-"+bot.id).hide();
refresh_bots();
}
const cancel_add = ()=> {
Modal.getInstance("#add_bot_btn").hide();
refresh_bots();
}
const refresh_bots = () => {
$.ajax({
url: "http://localhost:3000/user/bot/getlist/",
type: "GET",
headers:{
"Authorization": "Bearer " + store.state.user.token, //
},
success(resp){
// bot
bots.value = resp;
}
})
}
refresh_bots();
// bot
const add_bot = () => {
new_bot.error_msg = "";
$.ajax({
url: "http://localhost:3000/user/bot/add/",
type: "POST",
data: {
title: new_bot.title,
description: new_bot.description,
content: new_bot.content,
},
headers:{
"Authorization": "Bearer " + store.state.user.token,
},
success(resp) {
if (resp.error_msg === "success") { // bot
new_bot.title = "",
new_bot.description="",
new_bot.content="",
Modal.getInstance("#add_bot_btn").hide();
refresh_bots();
}
else {
new_bot.error_msg = resp.error_msg; //
}
}
})
}
// bot
const update_bot = (bot) => {
$.ajax({
url: "http://localhost:3000/user/bot/update/",
type: "POST",
data: {
bot_id: bot.id,
title: bot.title,
description: bot.description,
content: bot.content,
},
headers:{
"Authorization": "Bearer " + store.state.user.token,
},
success(resp) {
if (resp.error_msg === "success") { // bot
Modal.getInstance("#update-bot-btn-"+bot.id).hide();
refresh_bots();
}
else {
new_bot.error_msg = resp.error_msg; //
}
}
})
}
// bot
const remove_bot = (bot) => {
$.ajax({
url: "http://localhost:3000/user/bot/remove/",
type: "POST",
data: {
bot_id: bot.id
},
headers:{
"Authorization": "Bearer " + store.state.user.token,
},
success(resp) {
console.log(resp)
if (resp.error_msg === "success") { // bot
refresh_bots();
}
}
})
}
return {
bots,
new_bot,
add_bot,
remove_bot,
update_bot,
cancel_update,
cancel_add,
}
}
}
</script>
<style scoped>
img{
width: 100%
}
.error_msg{
font-size: 20px;
font-weight: bold;
color: red;
}
</style>
Loading…
Cancel
Save