Commit 8b75acaa authored by Piyaphorn Arphornsri's avatar Piyaphorn Arphornsri

updete

parent 52b77fac
This diff is collapsed.
\chapter{การทดสอบระบบ}
การทดสอบการทำงานขอแอนดรอยด์งแอปพลิเคชันระบบกองทุนเงินให้กู้ยืมเพื่อการศึกษา คณะวิทยาศาสตร์ มหาวิทยาลัยอุบลราชธานีและทดสอบการทำงานในส่วนของเว็บไซต์ โดยทำการทดสอบในลักษณะ Black-box Testing \cite{blackbox} หรือ Data-Driven testing ซึ่งเป็นการเทสแบบที่ไม่สนใจโปรเซส (Process) การทำงานภายในของโปรแกรมว่าทำงานอย่างไร แต่จะเน้นไปที่ Input และ Result ที่ได้มากกว่าว่าการทำงานต่าง ๆ ถูกต้องตามความต้องการ (Requirement) หรือไม่ ซึ่งการทดสอบการใช้งานแอนดรอยด์แอปพลิเคชัน และ การใช้งานเว็บแอปพลิเคชัน ได้ผลดังนี้
การทดสอบการทำงานของเว็บไซต์ โดยทำการทดสอบในลักษณะ Black-box Testing \cite{blackbox} หรือ Data-Driven testing ซึ่งเป็นการเทสแบบที่ไม่สนใจโปรเซส (Process) การทำงานภายในของโปรแกรมว่าทำงานอย่างไร แต่จะเน้นไปที่ Input และ Result ที่ได้มากกว่าว่าการทำงานต่าง ๆ ถูกต้องตามความต้องการ (Requirement) หรือไม่ ซึ่งการทดสอบการใช้งานแอนดรอยด์แอปพลิเคชัน และ การใช้งานเว็บแอปพลิเคชัน ได้ผลดังนี้
\section{การทดสอบการใช้งานแอนดรอยด์แอปพลิเคชัน}
\begin{itemize}
......
......@@ -39,14 +39,13 @@
\section{ปัญหาและอุปสรรคในการพัฒนา}
\begin{enumerate}
\item เนื่องจากทางผู้พัฒนามีความประสงค์ให้ระบบนี้สามารถใช้งานได้จริง ดังนั้น การพัฒนาในตอนนี้ยังมีข้อจำกัดเรื่องขนาดของเอกสารที่จัดเก็บบนไฟร์เบสที่สามารถอัพโหลดเข้าสู่ระบบสูงสุดเพียง 5 GB ซึ่งหากระบบถูกใช้งานจริงจำนวนข้อมูลในระบบจะเกินจำนวนที่ไฟร์เบสให้ใช้งานฟรี \\
\item เนื่องจากทางผู้พัฒนามีความประสงค์ให้ระบบนี้สามารถใช้งานได้จริง ดังนั้น การพัฒนาในตอนนี้ยังมีข้อจำกัดเรื่องขนาดของข้อมูลที่จัดเก็บบนไฟร์เบสที่สามารถอัพโหลดเข้าสู่ระบบสูงสุดเพียง 5 GB ซึ่งหากระบบถูกใช้งานจริงจำนวนข้อมูลในระบบจะเกินจำนวนที่ไฟร์เบสให้ใช้งานฟรี \\
แนวทางการแก้ไข : ทำการบีบอัดข้อมูลให้มีขนาดเล็กลง ส่วนในอนาคตอาจจำเป็นต้องศึกษาแนวทางการสร้างเซิฟเวอร์ (Server) เป็นของระบบเอง
\end{enumerate}
\section{แนวทางการพัฒนาต่อ}
\begin{enumerate}
\item สร้าง Web server ของระบบซึ่งเป็นโปรแกรมที่มีหน้าที่ให้บริการด้านการจัดการเว็บไซต์และ Database server ซึ่งเป็นโปรแกรมที่ทำหน้าที่ให้บริการด้านการจัดการดูแลข้อมูลต่าง ๆ ภายในเว็บไซต์ โปรแกรมที่มีการใช้งานส่วนใหญ่เป็น mysql, postgresql, DB2
\item การพัฒนาช่องทางการติดต่อ
\item เจ้าของร้านสามารถยืนยันการจองคิวได้
\item การพัฒนาเป็นแอปพลิเคชัน
......
Document/Latex/Figures/3/usecase.png

156 KB | W: | H:

Document/Latex/Figures/3/usecase.png

360 KB | W: | H:

Document/Latex/Figures/3/usecase.png
Document/Latex/Figures/3/usecase.png
Document/Latex/Figures/3/usecase.png
Document/Latex/Figures/3/usecase.png
  • 2-up
  • Swipe
  • Onion skin
......@@ -62,6 +62,24 @@ exports.getListuser = async (req, res) => {
});
}
};
exports.getListshop = async (req, res) => {
try {
const listshop = req.params.shop;
let list = await List.findAll({
where: {
shop: listshop
}
});
console.log('list', list)
res.status(200).send(list);
} catch (err) {
// console.log(err);
// res.sendStatus(401);
res.send({
error: err.message
});
}
};
exports.updateList = async (req, res) => {
try {
......
......@@ -27,8 +27,8 @@ exports.deleteshop = async (req, res) => {
const shopId = req.params.shopId;
await Shop.destroy({
where: {
id: shopId
}
id: shopId,
},
});
res.status(200).send("success");
} catch (err) {
......@@ -42,8 +42,8 @@ exports.getShopId = async (req, res) => {
const shopId = req.params.id;
let shop = await Shop.findOne({
where: {
id: shopId
}
id: shopId,
},
});
res.status(200).send(shop);
} catch (err) {
......@@ -65,13 +65,13 @@ exports.updateShop = async (req, res) => {
};
exports.getUserId = async (req, res) => {
try {
const userId = req.params.id;
let shop = await Shop.findOne({
const userId = req.params.userId;
let response = await Shop.findOne({
where: {
userId: id
}
userId: userId,
},
});
res.status(200).send(shop);
res.status(200).send(response);
} catch (err) {
console.log(err);
res.sendStatus(401);
......
......@@ -19,7 +19,7 @@ module.exports = db.sequelize.define("shopimages", {
referencesKey: 'id'
},
image: {
type: Sequelize.BLOB
type: Sequelize.BLOB('long')
},
type: {
type: Sequelize.STRING
......
......@@ -8,6 +8,7 @@ router.post("/add", listController.addlist);
router.get('/all', listController.getList);
router.delete('/delete/:listId',listController.deletelist);
router.get('/getListuser/:userId',listController.getListuser);
router.get("/getListshop/:shop", listController.getListshop)
router.put('/updateList/id',listController.updateList);
......
......@@ -7,7 +7,7 @@ router.post("/add", shopController.addShop);
router.get("/all", shopController.getShop);
router.delete("/delete/:shopId", shopController.updateShop);
router.get("/getShopId/:id", shopController.getShopId);
router.put("/updateshop/id", shopController.updateShop);
router.put("/updateshop/:id", shopController.updateShop);
router.get("/getUserId/:userId", shopController.getUserId);
router.put("/updateuserId/:userId", shopController.updateuserId);
......
......@@ -4,25 +4,23 @@ const router = express.Router();
const storage = require('../../multer');
const ShopImage = require('../../models/shopimage');
router.post('/upload/shop/:userId', storage.single('images',5), async (req, res) => {
router.post('/upload/shop/:shopId', storage.array('images', 5), async (req, res) => {
console.warn(req.files)
const images = req.files;
for (let i = 0; i < images.length; i++) {
await ShopImage.create({
shop_id: req.params.shop_id,
user_id: req.params.userId,
image: images[i].buffer,
type: images[i].mimetype
});
}
res.send('success')
console.log(images)
// const images = req.files;
// for (let i = 0; i < images.length; i++) {
// await ShopImage.create({
// shop_id: req.params.productId,
// userId: req.params.productId,
// image: images[i].buffer,
// type: images[i].mimetype
// });
// }
// res.send('success')
})
// get file
router.get('/file/Shop/:imageId', async (req, res) => {
const existingImage = await ShopImage.findOne({
//get file
router.get('/file/product/:imageId', async (req, res) => {
const existingImage = await ProductImage.findOne({
where: {
image_id: req.params.imageId
}
......@@ -32,3 +30,4 @@ router.get('/file/Shop/:imageId', async (req, res) => {
})
module.exports = router;
......@@ -15,7 +15,7 @@ app.use("/api/shop", router.shop);
app.use("/api/promotion", router.promotion);
app.use("/api/review", router.review);
app.use("/api/booking", router.booking);
// app.use("/api/storage", router.storage);
app.use("/api/storage", router.storage);
app.listen(port, () => {
console.log("Express server listening on port " + port);
......
......@@ -2,27 +2,21 @@ import React, { Component } from "react";
import { withStyles } from "@material-ui/core/styles";
import { withRouter } from "react-router-dom";
import compose from "recompose/compose";
import Input from "@material-ui/core/Input";
import InputLabel from "@material-ui/core/InputLabel";
import InputAdornment from "@material-ui/core/InputAdornment";
import FormControl from "@material-ui/core/FormControl";
import TextField from "@material-ui/core/TextField";
import Grid from "@material-ui/core/Grid";
import {
InputAdornment,
TextField,
Button,
Fab
} from "@material-ui/core";
import AccountCircle from "@material-ui/icons/AccountCircle";
import AddPhotoAlternateIcon from "@material-ui/icons/AddPhotoAlternate";
import MailOutlineIcon from "@material-ui/icons/MailOutline";
import VpnKeyIcon from "@material-ui/icons/VpnKey";
import Button from "@material-ui/core/Button";
import TextareaAutosize from "@material-ui/core/TextareaAutosize";
import ContactPhoneIcon from "@material-ui/icons/ContactPhone";
import BusinessIcon from "@material-ui/icons/Business";
import Fab from "@material-ui/core/Fab";
import EditIcon from "@material-ui/icons/Edit";
import Paper from "@material-ui/core/Paper";
import CardMedia from "@material-ui/core/CardMedia";
import { connect } from "react-redux";
import PhotoCameraIcon from "@material-ui/icons/PhotoCamera";
import Avatar from "react-avatar";
import axios from "axios";
const styles = theme => ({
margin: {
margin: theme.spacing(1)
......@@ -30,9 +24,24 @@ const styles = theme => ({
});
class Profile extends Component {
render() {
const { classes } = this.props;
state = {
user: ""
};
componentDidMount = async () => {
const { location, userInfo } = this.props;
// const id = userInfo.id;
const response = await axios.get(
`http://localhost:9000/api/auth/getUserById/${userInfo.id}`
);
console.log(response.data);
this.setState({
user: response.data
});
};
render() {
const { classes, userInfo } = this.props;
const { user } = this.state;
return (
<div className="row center">
<div className="row mt-2 mb-2">
......@@ -62,8 +71,10 @@ class Profile extends Component {
<div ClassName="row">
<TextField
className={classes.margin}
id="outlined-uncontrolled"
label="ชื่อร้าน"
id="name"
name="name"
value={user.name}
label="ชื่อ-นามสกุล"
variant="outlined"
InputProps={{
startAdornment: (
......@@ -76,7 +87,9 @@ class Profile extends Component {
<TextField
className={classes.margin}
id="outlined-uncontrolled"
id="email"
name="email"
value={user.email}
label="E_mail"
variant="outlined"
InputProps={{
......@@ -92,41 +105,9 @@ class Profile extends Component {
<div>
<TextField
className={classes.margin}
id="outlined-password-input"
label="Password"
type="password"
autoComplete="current-password"
variant="outlined"
InputProps={{
startAdornment: (
<InputAdornment position="start">
<VpnKeyIcon />
</InputAdornment>
)
}}
/>
<TextField
className={classes.margin}
id="outlined-password-input"
label="Confirm-Password"
type="password"
autoComplete="current-password"
variant="outlined"
InputProps={{
startAdornment: (
<InputAdornment position="start">
<VpnKeyIcon />
</InputAdornment>
)
}}
/>
</div>
<br></br>
<div>
<TextField
className={classes.margin}
id="outlined-password-input"
id="address"
name="address"
value={user.address}
label="ที่อยู่"
autoComplete="address"
variant="outlined"
......@@ -138,9 +119,12 @@ class Profile extends Component {
)
}}
/>
<TextField
className={classes.margin}
id="outlined-password-input"
id="tel"
name="tel"
value={user.tel}
label="เบอร์โทร"
autoComplete="Phone number"
variant="outlined"
......@@ -176,4 +160,13 @@ class Profile extends Component {
);
}
}
export default compose(withStyles(styles), withRouter)(Profile);
const mapStateToProps = state => ({
userInfo: state.user
});
const mapDispatchToProps = dispatch => {};
export default connect(
mapStateToProps,
mapDispatchToProps
)(compose(withStyles(styles), withRouter)(Profile));
......@@ -133,7 +133,7 @@ class Datashop extends Component {
const { location, userInfo } = this.props;
// const id = location.state.id;
const response = await axios.get(
`http://localhost:9000/api/shop/getuserId/${userInfo.id}`
`http://localhost:9000/api/shop/getUserId/${userInfo.id}`
);
if (response.data) this.setState({ shop: response.data });
......@@ -210,11 +210,11 @@ class Datashop extends Component {
axios
.post(
`http://localhost:9000/api/storage/upload/shop/${userInfo.id}`,
`http://localhost:9000/api/storage/upload/shop/${shop.id}`,
formData,
// shop.id,
// userInfo.id
shop.id,
userInfo.id
)
.then(response => {
console.log("เพิ่มรูปภาพสำเร็จ", response);
......
......@@ -5,6 +5,7 @@ import {
Button,
DialogActions,
DialogContent,
Typography,
DialogContentText,
DialogTitle,
Paper,
......@@ -28,7 +29,9 @@ import DirectionsIcon from "@material-ui/icons/Directions";
import ListIcon from "@material-ui/icons/List";
import AssignmentIndIcon from "@material-ui/icons/AssignmentInd";
import Rating from "@material-ui/lab/Rating";
import MaterialTable from "material-table";
import moment from "moment";
import "moment/locale/th";
const styles = theme => ({
root: {
// padding: "2px 4px",
......@@ -130,7 +133,9 @@ class HomePage extends Component {
open: false,
list: false,
rating: 0,
shops: []
shops: [],
columns: [{ title: "เวลา", field: "time" }],
data: [],
};
handleClickOpen = () => {
this.setState({
......@@ -180,6 +185,15 @@ class HomePage extends Component {
tab: tab,
shops: response.data
});
// console.log("response", response.data);
// let { timeopen, timeclose } = response.data;
// timeopen = timeopen.split(":");
// timeclose = timeclose.split(":");
// let dateClose = new Date();
// dateClose.setHours(parseInt(timeclose[0]));
// dateClose.setMinutes(parseInt(timeclose[1]));
// const result = this.calculate(moment(dateClose), timeopen);
};
handleChangeTab = (event, newValue) => {
......@@ -212,7 +226,8 @@ class HomePage extends Component {
const { classes } = this.props;
// const tab = this.state.tab;
// หรือ
const { tab, date, open, list, value, rating, shops } = this.state;
const { tab, date, open, list, value, rating, shops, columns,
data, } = this.state;
return (
<div>
<AppBra tab={tab} handleChangeTab={this.handleChangeTab} />
......@@ -297,7 +312,9 @@ class HomePage extends Component {
</Button>
<Dialog
open={open}
onClose={this.handleClose}
fullWidth={true}
maxWidth="md"
onClose={this.handleCloseQ}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
>
......@@ -305,12 +322,13 @@ class HomePage extends Component {
{"จองคิว"}
</DialogTitle>
<DialogContent>
<h6>
วันที่ที่เลือกคือ{" "}
{format(new Date(date), "dd MMMM yyyy", {
locale: th
})}
</h6>
<div className="row">
<div className="col s12 m5">
<div
style={{
maxWidth: "fit-content"
}}
>
<DatePicker
autoOk
orientation="static"
......@@ -320,34 +338,19 @@ class HomePage extends Component {
value={date}
onChange={this.handleChangeDate}
/>
</DialogContent>
<DialogActions>
<Button
variant="outlined"
onClick={this.handleClose}
color="primary"
>
ยกเลิก
</Button>
<Button
variant="outlined"
color="primary"
onClick={this.ClickOpen}
>
ถัดไป
</Button>
</DialogActions>
</Dialog>
<Dialog
open={list}
onClose={this.Close}
aria-labelledby="max-width-dialog-title"
>
<DialogTitle id="max-width-dialog-title">
กรุณาเลือกข้อมูลการจอง
</DialogTitle>
<DialogContent>
<DialogContentText>
</div>
</div>
<div className="col s12 m7">
<Typography>
วันที่ที่เลือกคือ{" "}
{format(new Date(date), "dd MMMM yyyy", {
locale: th
})}
</Typography>
<div className="mt-2">
<Typography>กรุณาเลือกข้อมูลการจอง</Typography>
<div className="row mt-2">
<div className="col">
<TextField
className={classes.margin}
id="list"
......@@ -368,11 +371,16 @@ class HomePage extends Component {
}}
>
{currencieslist.map(option => (
<option key={option.value} value={option.value}>
<option
key={option.value}
value={option.value}
>
{option.label}
</option>
))}
</TextField>
</div>
<div className="col">
<TextField
className={classes.margin}
id="list"
......@@ -393,19 +401,59 @@ class HomePage extends Component {
}}
>
{currencies.map(option => (
<option key={option.value} value={option.value}>
<option
key={option.value}
value={option.value}
>
{option.label}
</option>
))}
</TextField>
</DialogContentText>
</div>
<div className="col s12 mt-2">
<MaterialTable
title=""
columns={columns}
data={data}
onRowClick={(evt, selectedRow) => {
console.log("selectedRow", selectedRow);
this.setState({ selectedRow });
}}
options={{
selection: false,
search: false,
showTitle: false,
toolbar: false,
rowStyle: rowData => ({
backgroundColor:
this.state.selectedRow &&
this.state.selectedRow.tableData.id ===
rowData.tableData.id
? "#EEE"
: "#FFF"
})
}}
/>
</div>
</div>
</div>
</div>
</div>
</DialogContent>
<DialogActions>
<Button onClick={this.Close} color="primary">
Cancel
<Button
variant="outlined"
onClick={this.handleCloseQ}
color="secondary"
>
ยกเลิก
</Button>
<Button onClick={this.Close} color="primary">
Subscribe
<Button
variant="outlined"
color="primary"
onClick={this.handleSaveQ}
>
ยืนยัน
</Button>
</DialogActions>
</Dialog>
......
......@@ -136,14 +136,89 @@ const currencies = [
label: "ช่าง"
}
];
const currenciesreview = [
{
value: "1",
label: " กรุณาเลือกหัวข้อการรีวิว "
},
{
value: "2",
label: "รีวิวช่าง"
},
{
value: "3",
label: "รีวิวร้าน"
},
{
value: "4",
label: "การให้บริการ"
},
{
value: "5",
label: "การต้อนรับ"
},
{
value: "6",
label: "บรรยากาศ"
},
{
value: "7",
label: "อื่นๆ"
}
];
const currenciespoint = [
{
value: "1",
label: " กรุณาเลือกคะแนน "
},
{
value: "2",
label: "0.5"
},
{
value: "3",
label: "1"
},
{
value: "4",
label: "1.5"
},
{
value: "5",
label: "2"
},
{
value: "6",
label: "2.5"
},
{
value: "7",
label: "3"
},
{
value: "8",
label: "3.5"
},
{
value: "9",
label: "4"
},
{
value: "10",
label: "4.5"
},
{
value: "11",
label: "5"
}
];
class ShopPage extends Component {
state = {
reviweOpen: false,
list: false,
date: new Date(),
open: true,
// open: false,
// open: true,
open: false,
shop: null,
reviwe: {
topic: "",
......@@ -151,8 +226,15 @@ class ShopPage extends Component {
point: ""
},
columns: [{ title: "เวลา", field: "time" }],
columnslist: [
{ title: "ชื่อรายการ", field: "name" },
{ title: "ราคา", field: "price" },
{ title: "เวลาที่จอง", field: "time" }
],
data: [],
selectedRow: null
selectedRow: null,
datalist: []
};
handleClickOpenreview = () => {
......@@ -217,6 +299,7 @@ class ShopPage extends Component {
const id = location.state.id;
const response = await axios.get(
`http://localhost:9000/api/shop/getShopId/${id}`
// `http://localhost:9000/api/list//getListshop/${id}`
);
console.log("response", response.data);
let { timeopen, timeclose } = response.data;
......@@ -227,10 +310,20 @@ class ShopPage extends Component {
dateClose.setMinutes(parseInt(timeclose[1]));
const result = this.calculate(moment(dateClose), timeopen);
// console.log("response.data", response.data);
// if (response.data) {
// this.setState({
// datalist: response.data
// });
// } else {
// console.log("cannot get shop data");
// }
this.setState({
shop: response.data,
data: result
});
// console.log(this.state.shop);
};
......@@ -266,7 +359,9 @@ class ShopPage extends Component {
open,
columns,
data,
selectedRow
datalist,
selectedRow,
columnslist
} = this.state;
return (
......@@ -303,7 +398,7 @@ class ShopPage extends Component {
<Dialog
open={list}
fullWidth={true}
maxWidth="md"
// maxWidth="mr"
onClose={this.Close}
aria-labelledby="max-width-dialog-title"
>
......@@ -312,8 +407,16 @@ class ShopPage extends Component {
</DialogTitle>
<DialogContent>
<DialogContentText>
You can set my maximum width and whether to adapt or
not.
<div className="row">
<MaterialTable
title="รายการ"
columns={columnslist}
data={datalist}
options={{
selection: false
}}
/>
</div>
</DialogContentText>
</DialogContent>
<DialogActions>
......@@ -609,14 +712,17 @@ class ShopPage extends Component {
</Button>
<Dialog
open={reviweOpen}
// TransitionComponent={Transition}
keepMounted
onClose={this.handleClosereview}
aria-labelledby="form-dialog-title"
aria-labelledby="alert-dialog-slide-title"
aria-describedby="alert-dialog-slide-description"
>
<DialogTitle id="form-dialog-title">
<DialogTitle id="alert-dialog-slide-title">
เขียนรีวิวติชม
</DialogTitle>
<DialogContent>
<DialogContentText>
<DialogContentText id="alert-dialog-slide-description">
<div className={classes.root}>
<TextField
className={classes.margin}
......@@ -637,7 +743,7 @@ class ShopPage extends Component {
)
}}
>
{currencieslist.map(option => (
{currenciesreview.map(option => (
<option key={option.value} value={option.value}>
{option.label}
</option>
......@@ -663,7 +769,7 @@ class ShopPage extends Component {
)
}}
>
{currencieslist.map(option => (
{currenciespoint.map(option => (
<option key={option.value} value={option.value}>
{option.label}
</option>
......@@ -690,11 +796,11 @@ class ShopPage extends Component {
</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={this.handleClosereview} color="primary">
Cancel
<Button onClick={this.handleClickOpenreview} color="primary">
ยกเลิก
</Button>
<Button onClick={this.handleClosereview} color="primary">
Subscribe
<Button onClick={this.handleClickOpenreview} color="primary">
ยันยัน
</Button>
</DialogActions>
</Dialog>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment