完成Register && Gird

This commit is contained in:
2019-06-03 18:22:02 +08:00
parent 9b5d2ec4e5
commit 7473c0e36a
36 changed files with 2051 additions and 943 deletions
@@ -1,18 +1,20 @@
package net.alawn.bill.controller;
import lombok.extern.slf4j.Slf4j;
import net.alawn.bill.entity.dto.NewUser;
import net.alawn.bill.security.AuthUser;
import net.alawn.bill.security.JwtAuthenticationRequest;
import net.alawn.bill.security.JwtAuthenticationResponse;
import net.alawn.bill.security.JwtTokenUtil;
import net.alawn.bill.service.AuthService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
@@ -21,6 +23,7 @@ import javax.servlet.http.HttpServletRequest;
* @Description:
* @Date: Create in 09:59 2019-05-23
*/
@Slf4j
@RestController
public class AuthController {
@@ -30,6 +33,9 @@ public class AuthController {
@Autowired
private AuthService authService;
@Autowired
private JwtTokenUtil jwtTokenUtil;
@RequestMapping(value = "/auth", method = RequestMethod.POST)
public ResponseEntity<?> createAuthenticationToken(
@RequestBody JwtAuthenticationRequest authenticationRequest) throws AuthenticationException {
@@ -55,4 +61,12 @@ public class AuthController {
public NewUser register(@RequestBody NewUser addedUser) throws AuthenticationException, HttpRequestMethodNotSupportedException {
return authService.register(addedUser);
}
@RequestMapping(value = "/auth/valid", method = RequestMethod.POST)
public boolean valid(@RequestParam String token) throws AuthenticationException, HttpRequestMethodNotSupportedException {
log.info("token:" + token);
// AuthUser authUser = (AuthUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
boolean rs = jwtTokenUtil.isTokenExpired(token);
return !rs;
}
}
@@ -11,9 +11,12 @@ import net.alawn.bill.security.AuthUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import java.math.BigDecimal;
import java.util.List;
import java.util.Optional;
/**
@@ -27,6 +30,7 @@ import java.util.List;
@RequestMapping(value = "/bill")
@RestController
public class BillController {
final static double feeRate = 0.08;
@Autowired
BookRepo bookRepo;
@@ -38,22 +42,31 @@ public class BillController {
UserRepo userRepo;
@RequestMapping(value = "/books",method = RequestMethod.POST)
@Transactional(rollbackFor=Exception.class)
public ResponseEntity<Book> newBook(@RequestBody NewBill newBill){
AuthUser authUser = (AuthUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
long userId = authUser.getId();
log.info("newBill:" + newBill);
Book book = newBill.toBook();
book.setUser(new User(userId));
log.info("book:" + book);
/** 入库 */
bookRepo.save(book);
log.info("book:" + book);
bookRepo.flush();
/** 更新总金额 */
bookRepo.sumAmount(book.getId());
log.info("book:" + book);
// book = bookRepo.findById(book.getId()).get();
book = bookRepo.findById(book.getId()).get();
log.info("book:" + book);
log.info("book:" + book.getTotalAmount());
/** 费率计算 */
book.setFee(book.getTotalAmount().multiply(BigDecimal.valueOf(feeRate)));
bookRepo.save(book);
bookRepo.flush();
return ResponseEntity.ok(book);
}
@@ -62,9 +75,8 @@ public class BillController {
AuthUser authUser = (AuthUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
long userId = authUser.getId();
List<Book> books = bookRepo.findByUserId(userId);
List<Book> books = bookRepo.findByUserIdOrderByCreateTimeDesc(userId);
return ResponseEntity.ok(books);
}
}
@@ -80,7 +80,7 @@ public class TestController {
main.setApplyDate(new Date());
main.setAcceptDate(new Date());
main.setState(State.APPLIED);
main.setState(State.Applied);
main.setUser(user);
main.setPost(post);
main.addDetail(detail1);
@@ -24,7 +24,7 @@ public class NewBill {
Book book = new Book();
book.setApplyDate(new Date());
book.setPost(new Post(postId));
book.setState(State.APPLIED);
book.setState(State.Applied);
// List<Item> items = new ArrayList<>();
// for(BillItem rq: itemRQs){
@@ -9,11 +9,13 @@ import net.alawn.bill.entity.po.User;
public class NewUser {
private String username;
private String fullname;
private String password;
public User build() {
return User.builder()
.username(username)
.fullname(fullname)
.password(password)
.build();
}
@@ -50,6 +50,7 @@ public class Book extends EntityId {
private Date applyDate ;
private Date acceptDate ;
private BigDecimal totalAmount ;
private BigDecimal fee ;
public void addItem(Item item) {
item.setBook(this);
@@ -1,5 +1,6 @@
package net.alawn.bill.entity.po;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.*;
@@ -47,6 +48,8 @@ public class Item extends EntityId {
@NotFound(action = NotFoundAction.IGNORE)
private Merchant merchant;
// @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
@JsonFormat(pattern="yyyy-MM-dd",timezone = "GMT+8")
private Date dating;
private BigDecimal amount;
@@ -40,6 +40,10 @@ public class User extends EntityId {
/** 用户名称 */
private String username;
/** 用户全名 */
private String fullname;
/** 密钥 */
@JsonIgnore
private String password;
@@ -8,9 +8,11 @@ package net.alawn.bill.enums;
public enum State {
APPLIED ( "已申请"),
ACCEPTED ( "已受理"),
POSTED ( "已快递");
Applied ( "已申请"),
Rejected ( "已受理"),
Accepted ( "已受理"),
Posted ( "已快递"),
Finished ( "已完成");
private String desc;
@@ -19,9 +19,9 @@ import java.util.List;
@Repository
public interface BookRepo extends JpaRepository<Book, Long> {
List<Book> findByUserId(long userId);
List<Book> findByUserIdOrderByCreateTimeDesc(long userId);
@Modifying
@Modifying(clearAutomatically = true)
@Query(value = "update t_bill_books set total_amount = (select sum(amount) from t_bill_items where book_id = ?1) where id = ?1",nativeQuery = true)
void sumAmount(long bookId);
}
@@ -0,0 +1 @@
.test[data-v-22138d56]{margin:20px}.right[data-v-22138d56]{margin:15px}
@@ -0,0 +1 @@
#app{font-family:Avenir,Helvetica,Arial,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-align:center;color:#2c3e50}#nav{padding:30px}#nav a{font-weight:700;color:#2c3e50}#nav a.router-link-exact-active{color:#42b983}h3[data-v-37c79730]{margin:40px 0 0}ul[data-v-37c79730]{list-style-type:none;padding:0}li[data-v-37c79730]{display:inline-block;margin:0 10px}a[data-v-37c79730]{color:#42b983}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 542 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

+1
View File
@@ -0,0 +1 @@
<!DOCTYPE html><html><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1"><title>Vue App</title><link href=/css/about.6a0fc9a4.css rel=prefetch><link href=/js/about.e5fa4685.js rel=prefetch><link href=/css/app.f0d13c35.css rel=preload as=style><link href=/css/chunk-vendors.84a4f112.css rel=preload as=style><link href=/js/app.fe9495e6.js rel=preload as=script><link href=/js/chunk-vendors.c39976b3.js rel=preload as=script><link href=/css/chunk-vendors.84a4f112.css rel=stylesheet><link href=/css/app.f0d13c35.css rel=stylesheet></head><body><div id=app></div><script src=/js/chunk-vendors.c39976b3.js></script><script src=/js/app.fe9495e6.js></script></body></html>
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+23
View File
@@ -4752,6 +4752,11 @@
"integrity": "sha512-M3NhsLbV1i6HuGzBUH8vXrtxOk+tWmzWKDMbAVSUp3Zsjm7ywFeuwrUXhmhQyRK1q5B5GGy7hcXPbj3bnfZg2g==",
"dev": true
},
"downloadjs": {
"version": "1.4.7",
"resolved": "https://registry.npmjs.org/downloadjs/-/downloadjs-1.4.7.tgz",
"integrity": "sha1-9p+W+UDg0FU9rCkROYZaPNAQHjw="
},
"duplexer": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz",
@@ -5859,6 +5864,11 @@
}
}
},
"file-saver": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.2.tgz",
"integrity": "sha512-Wz3c3XQ5xroCxd1G8b7yL0Ehkf0TC9oYC6buPFkNnU9EnaPlifeAFCyCh+iewXTyFRcg0a6j3J7FmJsIhlhBdw=="
},
"file-uri-to-path": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
@@ -10044,6 +10054,11 @@
}
}
},
"moment": {
"version": "2.24.0",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz",
"integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg=="
},
"move-concurrently": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
@@ -15263,6 +15278,14 @@
}
}
},
"vue-json-excel": {
"version": "0.2.98",
"resolved": "https://registry.npmjs.org/vue-json-excel/-/vue-json-excel-0.2.98.tgz",
"integrity": "sha512-hPA3/cOe5nGbEZiJyfpdBIdqBExxF6EhMhpX6vC654PYbTVzdzp7O9ZsC1AgqbgRDR8VjzAaPaEeHg2vGS88FQ==",
"requires": {
"downloadjs": "^1.4.7"
}
},
"vue-loader": {
"version": "13.7.3",
"resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-13.7.3.tgz",
+3
View File
@@ -16,7 +16,10 @@
"dependencies": {
"axios": "^0.18.0",
"element-ui": "^2.8.2",
"file-saver": "^2.0.2",
"moment": "^2.24.0",
"vue": "^2.5.2",
"vue-json-excel": "^0.2.98",
"vue-router": "^3.0.1"
},
"devDependencies": {
+35 -35
View File
@@ -1,60 +1,60 @@
import HttpRequest from '@/axios/api.request'
export const addMerchant = (merc) => {
return HttpRequest.request({
url: 'basic/merchants',
method: 'post',
data: merc
})
return HttpRequest.request({
url: 'basic/merchants',
method: 'post',
data: merc
})
}
export const fetchMerchants = () => {
return HttpRequest.request({
url: 'basic/merchants',
method: 'get'
})
return HttpRequest.request({
url: 'basic/merchants',
method: 'get'
})
}
export const fetchTitles = () => {
return HttpRequest.request({
url: 'basic/titles',
method: 'get'
})
return HttpRequest.request({
url: 'basic/titles',
method: 'get'
})
}
export const getMerchant = (id) => {
return HttpRequest.request({
url: 'basic/merchants/' + id,
method: 'get'
})
return HttpRequest.request({
url: 'basic/merchants/' + id,
method: 'get'
})
}
export const addPost = (merc) => {
return HttpRequest.request({
url: 'basic/posts',
method: 'post',
data: merc
})
return HttpRequest.request({
url: 'basic/posts',
method: 'post',
data: merc
})
}
export const fetchPosts = () => {
return HttpRequest.request({
url: 'basic/posts',
method: 'get'
})
return HttpRequest.request({
url: 'basic/posts',
method: 'get'
})
}
export const getPost = (id) => {
return HttpRequest.request({
url: 'basic/posts/' + id,
method: 'get'
})
return HttpRequest.request({
url: 'basic/posts/' + id,
method: 'get'
})
}
export const newBill = (bill) => {
return HttpRequest.request({
url: 'bill/books',
method: 'post',
data: bill
})
return HttpRequest.request({
url: 'bill/books',
method: 'post',
data: bill
})
}
+9
View File
@@ -0,0 +1,9 @@
import HttpRequest from '@/axios/api.request'
export const fetchBooks = () => {
return HttpRequest.request({
url: 'bill/books',
method: 'get'
})
}
+15
View File
@@ -7,3 +7,18 @@ export const UserLoginAction = (ruleForm) => {
data: ruleForm
})
}
export const register = (user) => {
return HttpRequest.request({
url: 'auth/register',
method: 'post',
data: user
})
}
export const isTokenValid = (token) => {
return HttpRequest.request({
url: 'auth/valid?token=' + token,
method: 'post',
})
}
+4 -1
View File
@@ -6,9 +6,12 @@ import router from './router'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import HttpRequest from '@/axios/api.request'
import moment from "moment";
import JsonExcel from 'vue-json-excel'
Vue.component('downloadExcel', JsonExcel)
Vue.use(ElementUI)
Vue.prototype.$moment = moment;
Vue.config.productionTip = false
HttpRequest.interceptors.request.use(
+7 -2
View File
@@ -8,14 +8,19 @@ export default new Router({
routes: [
{
path: '/',
name: 'HelloWorld',
component: HelloWorld
name: 'Index',
redirect: '/login'
},
{
path: '/merchant',
name: 'Merchant',
component: () => import(/* webpackChunkName: "merchant" */ '../views/Merchant.vue')
},
{
path: '/register',
name: 'Register',
component: () => import(/* webpackChunkName: "merchant" */ '../views/Register.vue')
},
{
path: '/login',
name: 'Login',
-23
View File
@@ -1,23 +0,0 @@
<el-table
:data="tableData"
border
style="width: 100%">
<el-table-column
prop="date"
label="日期"
width="180">
</el-table-column>
<el-table-column
prop="name"
label="抬头"
width="180">
</el-table-column>
<el-table-column
prop="address"
label="餐饮商户">
</el-table-column>
<el-table-column
prop="address"
label="金额">
</el-table-column>
</el-table>
File diff suppressed because it is too large Load Diff
+150 -250
View File
@@ -1,9 +1,17 @@
<template>
<div class="main">
<div class="gTable">
<el-table :data="book" height="400px" style="width: 100%">
<el-table-column prop="applyDate" label="申请日期" width="150"></el-table-column>
<div class="group">
<el-table
:data="book"
height="600px"
style="width: 100%"
@cell-mouse-enter="handleMouseEnter"
>
<!-- highlight-current-row -->
<!-- @current-change="handleCurrentChange" -->
<el-table-column prop="applyDate" label="申请日期" width="150" :formatter="dateFormat"></el-table-column>
<el-table-column prop="totalAmount" label="总金额" width="100"></el-table-column>
<el-table-column prop="fee" label="税费" width="100"></el-table-column>
<el-table-column prop="post.contact" label="快递地址" width="100">
<template slot-scope="scope">
<el-popover trigger="hover" placement="right">
@@ -11,101 +19,140 @@
<p>地址: {{ scope.row.post.address }}</p>
<div slot="reference" class="name-wrapper">
<el-tag size="medium">{{ scope.row.post.contact }}</el-tag>
<!-- <el-tag size="small">{{ scope.row.post.contact }}</el-tag> -->
</div>
</el-popover>
</template>
</el-table-column>
<!-- <el-table-column prop="titleAbbr" label="抬头" width="150">
<el-table-column prop="state" label="状态" width="100">
<template slot-scope="scope">
<el-popover trigger="hover" placement="top">
<p>税号: {{ scope.row.taxNo }}</p>
<p>抬头: {{ scope.row.titleName }}</p>
<div slot="reference" class="name-wrapper">
<el-tag size="medium">{{ scope.row.titleAbbr }}</el-tag>
</div>
</el-popover>
<!-- <span v-if="scope.row.state=='Applied'" style="color:green;font-size:14px;">已申请</span> -->
<span v-if="scope.row.state=='Applied'" style="color:green;font-size:13px;">已申请</span>
<span v-if="scope.row.state=='Rejected'" style="color:red;font-size:13px;">已拒绝</span>
<span v-if="scope.row.state=='Accepted'" style="color:blue;font-size:13px;">已受理</span>
<span v-if="scope.row.state=='Posted'" style="color:blue;font-size:13px;">已投递</span>
<span v-if="scope.row.state=='Finished'" style="color:blue;font-size:13px;">已完成</span>
</template>
</el-table-column>-->
<!-- <el-table-column prop="amount" label="金额" width="80"></el-table-column> -->
</el-table-column>
<el-table-column align="right">
<template slot-scope="scope">
<el-button @click="showDetail(scope.row)" type="text" size="small">
详情
<i class="el-icon-view el-icon--right"></i>
</el-button>
<!-- <el-button type="text" size="small"></el-button> -->
<download-excel
class="el-button el-button--text el-button--small"
:footer="getFooter()"
:data="focusRow.items" :fields="json_fields" type="csv"
:name="getFileName()"
>导出<i class="el-icon-download el-icon--right"></i> </download-excel>
</template>
<template slot="header">
<!-- <el-button class="itemBtn" type="primary" size="medium" @click="clearFocusRow();isAddShow = true;resetForm('addForm');" :disabled="disabled">添加</el-button> -->
<el-button
class="bill"
type="primary"
size="small"
@click="redirectBill()"
:disabled="disabled"
>申请开票</el-button>
<el-button
class="refresh"
type="primary"
icon="el-icon-refresh-left"
size="small"
@click="refresh();"
:disabled="disabled"
></el-button>
</template>
</el-table-column>
</el-table>
<!-- </el-form-item> -->
</div>
<!--详情-->
<div width="600px">
<el-dialog title="编辑" :visible.sync="isDetailShow" width="700px">
<el-table :data="focusRow.items" height="400px" style="width: 100%" highlight-current-row>
<el-table-column prop="dating" label="开票日期" width="150" :formatter="dateFormat"></el-table-column>
<el-table-column prop="amount" label="金额" width="150"></el-table-column>
<el-table-column prop="title.abbr" label="抬头简称" width="150">
<template slot-scope="scope">
<el-popover trigger="hover" placement="right">
<p>抬头: {{ scope.row.title.name }}</p>
<p>税号: {{ scope.row.title.taxNo }}</p>
<div slot="reference" class="name-wrapper">
<!-- <el-tag size="medium">{{ scope.row.title.abbr }}</el-tag> -->
<el-tag size="medium">{{ scope.row.title.abbr }}</el-tag>
</div>
</el-popover>
</template>
</el-table-column>
<el-table-column prop="merchant.abbr" label="餐饮商户" width="150"></el-table-column>
</el-table>
</el-dialog>
</div>
</div>
</template>
<script>
import {
newPost,
fetchPosts,
getPost,
fetchTitles,
fetchMerchants,
newBill
} from "../api/basic.js";
/* import { newPost, fetchPosts, getPost, fetchTitles, fetchMerchants, newBill } from "../api/basic.js"; */
import { fetchBooks } from "../api/bill.js";
export default {
name: "Gird",
data() {
return {
isAddShow: false,
isEditShow: false,
isDetailShow: false,
posts: [],
titles: [],
merchants: [],
addBtnDisabled: false,
editBtnDisabled: false,
disabled: false,
// focusRow: { index: null,dating: "2019-05-28", titleId: null, titleAbbr: "上海沐融",titleName:"",taxNo:"",merchantId: null, merchantAbbr: "华容月",amount: 0.0 },
focusRow: {},
book: [
{
id: 592,
focusRow: {
id: 0,
post: {
id: 32,
address: "世博馆路52号鲁能国际B座11楼",
contact: "赵磊",
mobile: "18017581610"
id: 0,
address: "",
contact: "",
mobile: ""
},
items: [
{
id: 593,
id: 0,
title: {
id: 25,
name: "北京沐融信息科技股份有限公司",
abbr: "沐融北京总公司",
taxNo: "91110108071711408C"
id: 0,
name: "",
abbr: "",
taxNo: ""
},
merchant: {
id: 22,
abbr: "汇京粹",
name: "汇京粹(上海)餐饮管理有限公司"
id: 0,
abbr: "",
name: ""
},
dating: "2019-05-07T00:00:00.000+0000",
amount: 500.0
dating: "",
amount: 0.0
},
{
id: 594,
title: {
id: 24,
name: "北京沐融信息科技股份有限公司上海分公司",
abbr: "沐融上海分公司",
taxNo: "91310107MA1G07F91W"
},
merchant: {
id: 23,
abbr: "花蓉月",
name: "上海花蓉月餐饮有限公司"
},
dating: "2019-05-16T00:00:00.000+0000",
amount: 200.0
}
],
state: "APPLIED",
applyDate: "2019-05-30T13:02:11.000+0000",
state: "",
applyDate: "",
acceptDate: null,
totalAmount: 700.0
}
],
totalAmount: 0.0
},
json_fields: {
// 快递地址: "post.address",
// 联系人: "post.contact",
// 电话: "post.mobile",
开票日期: "dating",
开票金额: "amount",
抬头: "title.name",
税号: "title.taxNo",
商户: "merchant.abbr"
},
book: [],
rules: {
postContact: [
{ required: true, message: "请选择邮寄地址", trigger: "change" }
@@ -126,197 +173,49 @@ export default {
};
},
methods: {
getFileName(){
// cell.children[0].children[1].style.color="black";
return this.focusRow.id + '.csv';
},
handleMouseEnter:function(row, column, cell, event){
// cell.children[0].children[1].style.color="black";
// console.info('handleMouseEnter.row:' + JSON.stringify(row));
this.focusRow = row;
},
getFooter() {
// console.info('getFooter.row:' + JSON.stringify(row))
if(JSON.stringify(this.focusRow) == "{}") return "";
else return '收件地址:' + this.focusRow.post.address + ',收件人:' + this.focusRow.post.contact + ',手机:' + this.focusRow.post.mobile;
},
showDetail(rows) {
this.isDetailShow = true;
},
redirectBill() {
this.$router.push({ path: "Bill" });
},
refresh() {
fetchBooks().then(res => {
// console.info("res.data:" + res.data);
this.book = res.data;
});
},
handleCurrentChange(val) {
this.focusRow = val;
// console.info("this.focusRow:" + JSON.stringify(this.focusRow));
// this.$message.error("val:" + JSON.stringify(val));
},
resetForm(formName) {
this.$refs[formName].resetFields();
// this.disabled = false;
// this.clearFocusRow();
},
/** 在表格中添加明细 */
addItem(formName) {
var oriForm = formName;
this.$refs[formName].validate(valid => {
if (valid) {
console.info("addItem");
console.info("focusRow:" + JSON.stringify(this.focusRow));
console.info(
"this.bill.newItems:" + JSON.stringify(this.bill.newItems)
);
this.bill.newItems.splice(0, 0, this.focusRow);
console.info(
"this.bill.newItems:" + JSON.stringify(this.bill.newItems)
);
this.clearFocusRow();
console.info("focusRow:" + JSON.stringify(this.focusRow));
this.isAddShow = false;
// this.resetForm(oriForm);
} else {
console.log("error submit!!");
return false;
}
});
},
/** 在表格中添加明细 */
updateItem(formName) {
this.$refs[formName].validate(valid => {
if (valid) {
console.info("index:" + index);
console.info("updateItem");
console.info("focusRow:" + JSON.stringify(this.focusRow));
console.info(
"this.bill.newItems:" + JSON.stringify(this.bill.newItems)
);
var index = this.focusRow.index;
this.bill.newItems.splice(index, 1, this.focusRow);
console.info(
"this.bill.newItems:" + JSON.stringify(this.bill.newItems)
);
this.clearFocusRow();
console.info("focusRow:" + JSON.stringify(this.focusRow));
this.isEditShow = false;
} else {
console.log("error submit!!");
return false;
}
});
},
/** 表格-编辑一行 */
handleEdit(index, row) {
this.focusRow = row;
this.focusRow.index = index;
console.log(index, row);
this.isEditShow = true;
},
handleDelete(index, row) {
console.log(index, row);
row.splice(index, 1);
},
onSubmit(formName) {
this.$refs[formName].validate(valid => {
if (valid) {
console.info("bill:" + JSON.stringify(this.bill));
newBill(this.bill).then(function(response) {
console.info("response:" + response);
});
this.disabled = true;
this.$message({ message: "提交成功", type: "success" });
} else {
console.log("error submit!!");
return false;
}
});
},
reset(formName) {
// this.$refs[formName].resetFields();
// this.disabled = false;
},
// querySearch(queryString, cb) {
// var posts = this.posts;
// console.error("posts:" + posts);
// var results = queryString ? posts.filter(this.createFilter(queryString)) : posts;
// // 调用 callback 返回建议列表的数据
// cb(results);
// },
/** AutoComplete Posts 处理*/
querySearchAsyncPosts(queryString, cb) {
var list = [{}];
fetchPosts().then(function(response) {
for (let i of response.data) {
i.value = i.contact; //将想要展示的数据作为value
// i.value = i.contact; //将想要展示的数据作为value
}
list = response.data;
cb(list);
});
// var posts = this.posts;
// console.error("posts:" + posts);
// var results = queryString ? posts.filter(this.createFilter(queryString)) : posts;
// // 调用 callback 返回建议列表的数据
// cb(results);
},
createFilterPosts(queryString) {
return posts => {
return (
posts.contact.toLowerCase().indexOf(queryString.toLowerCase()) === 0
);
};
},
loadPosts() {
console.error("loadPosts");
},
handleSelectPosts(item) {
this.bill.postId = item.id;
console.log("postId:" + this.bill.postId);
console.log("postContact:" + this.bill.postContact);
},
handleIconClickPosts(ev) {
console.log(ev);
},
/** AutoComplete Titles 处理*/
querySearchAsyncTitles(queryString, cb) {
var list = [{}];
fetchTitles().then(function(response) {
console.info(response);
for (let i of response.data) {
i.value = i.abbr; // 将想要展示的数据作为value
}
list = response.data;
cb(list);
});
},
createFilterTitles(queryString) {
return titles => {
return (
titles.abbr.toLowerCase().indexOf(queryString.toLowerCase()) === 0
);
};
},
loadTitles() {
console.error("loadTitles");
},
handleSelectTitles(item) {
this.focusRow.titleId = item.id;
this.focusRow.titleName = item.name;
this.focusRow.taxNo = item.taxNo;
console.log("titleId:" + this.focusRow.titleId);
console.log("titleAbbr:" + this.focusRow.titleAbbr);
console.log("titleName:" + this.focusRow.titleName);
},
handleIconClickTitles(ev) {
console.log(ev);
},
/** AutoComplete Merchant 处理*/
querySearchAsyncMerchant(queryString, cb) {
var list = [{}];
fetchMerchants().then(function(response) {
for (let i of response.data) {
i.value = i.abbr; // 将想要展示的数据作为value
}
list = response.data;
cb(list);
});
},
createFilterMerchant(queryString) {
return merchants => {
return (
merchants.contact.toLowerCase().indexOf(queryString.toLowerCase()) ===
0
);
};
},
handleSelectMerchant(item) {
this.focusRow.merchantId = item.id;
this.focusRow.merchantsAbbr = item.abbr;
console.log("merchantId:" + this.focusRow.merchantId);
console.log("merchantsAbbr:" + this.focusRow.merchantsAbbr);
console.log("merchantsName:" + item.name);
},
handleIconClickMerchant(ev) {
console.log(ev);
},
loadMerchant() {
console.error("loadTitles");
dateFormat: function(row, column) {
var date = row[column.property];
if (date == undefined) {
return "";
}
// return this.$moment(date).format("YYYY-MM-DD HH:mm:ss");
return this.$moment(date).format("YYYY-MM-DD");
},
/** 清理当前缓存 */
clearFocusRow() {
@@ -325,6 +224,7 @@ export default {
}
},
mounted() {
this.refresh();
// this.posts = this.loadPosts();
// console.info('mounted.this.posts:' + posts);
}
@@ -393,7 +293,7 @@ a {
right: 0;
bottom: 0;
}
.itemBtn {
.billBtn {
width: 100px;
float: right;
}
+20 -9
View File
@@ -8,10 +8,21 @@
<el-form-item label="密码" prop="password">
<el-input v-model="ruleForm.password" @keyup.enter.native="onSubmit('ruleForm')" show-password placeholder="请输入密码"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit('ruleForm')" :disabled="disabled">登录</el-button>
<el-button @click="reset('ruleForm')">重置</el-button>
</el-form-item>
<!-- <el-row :gutter="20"> -->
<el-row>
<el-col :span="18">
<el-form-item>
<el-button type="primary" @click="onSubmit('ruleForm')" :disabled="disabled">登录</el-button>
<el-button @click="reset('ruleForm')">重置</el-button>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label-width="50px">
<span align="right"><el-link type="primary" :underline="false" href="/#/Register">注册</el-link></span>
</el-form-item>
</el-col>
</el-row>
</el-form>
</div>
</div>
@@ -45,20 +56,20 @@ export default {
this.$refs[formName].validate(valid => {
var _this = this;
if (valid) {
UserLoginAction(this.ruleForm)
this.disabled = true;
UserLoginAction(this.ruleForm)
.then(res => {
var token = "Bearer " + res.data.token;
console.log("token:" + token);
window.localStorage.setItem("token", token);
this.disabled = true;
this.$message({ message: "登录成功", type: "success" });
this.$router.push({ path: 'Bill' })
this.$router.push({ path: 'Gird' })
})
.catch(function(error) {
// _this.$message({ message: error.response.statusText, type: 'error' });
// _this.$message.error();
_this.disabled = false;
if (error.response) {
// The request was made and the server responded with a status code
// that falls out of the range of 2xx
+171
View File
@@ -0,0 +1,171 @@
<template>
<div class="login">
<div class="group">
<el-form ref="ruleForm" :model="ruleForm" :rules="rules" label-width="80px">
<el-form-item label="用户名" prop="username">
<el-input v-model="ruleForm.username" clearable placeholder="请输入用户名"></el-input>
</el-form-item>
<el-form-item label="姓名" prop="fullname">
<el-input v-model="ruleForm.fullname" clearable placeholder="请输入姓名"></el-input>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input v-model="ruleForm.password" @keyup.enter.native="onSubmit('ruleForm')" show-password placeholder="请输入密码"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit('ruleForm')" :disabled="disabled">登录</el-button>
<el-button @click="reset('ruleForm')">重置</el-button>
</el-form-item>
</el-form>
</div>
</div>
</template>
<script>
import { register } from "../api/user.js";
export default {
name: "Login",
data() {
return {
disabled: false,
ruleForm: {
username: "",
fullname: "",
password: ""
},
rules: {
username: [
{ required: true, message: "请输入用户名", trigger: "blur" },
{ min: 3, max: 15, message: "长度在 3 到 15 个字符", trigger: "blur" }
],
fullname: [
{ required: true, message: "请输入姓名", trigger: "blur" },
{ min: 1, max: 50, message: "长度在 1 到 50 个字符", trigger: "blur" }
],
password: [
{ required: true, message: "请输入密码", trigger: "change" },
{ min: 3, max: 15, message: "长度在 3 到 15 个字符", trigger: "blur" }
]
}
};
},
methods: {
onSubmit(formName) {
this.$refs[formName].validate(valid => {
var _this = this;
if (valid) {
this.disabled = true;
register(this.ruleForm)
.then(res => {
this.$message({ message: "注册成功", type: "success" });
this.$router.push({ path: 'Login' })
})
.catch(function(error) {
// _this.$message({ message: error.response.statusText, type: 'error' });
// _this.$message.error();
_this.disabled = false;
if (error.response) {
// The request was made and the server responded with a status code
// that falls out of the range of 2xx
_this.$message({ message: error.response.data.message, type: 'error' });
console.log(error.response.data);
console.log(error.response.status);
console.log(error.response.headers);
} else if (error.request) {
// The request was made but no response was received
// `error.request` is an instance of XMLHttpRequest in the browser and an instance of
// http.ClientRequest in node.js
// _this.$message.error(error.request);
console.log(error.request);
_this.$message.error('未知错误');
} else {
// Something happened in setting up the request that triggered an Error
console.log("Error", error.message);
_this.$message.error(error.response.message);
}
console.log(error.config);
// _this.$message.error(error.response.statusText);
});
} else {
console.log("error submit!!");
return false;
}
});
},
reset(formName) {
this.$refs[formName].resetFields();
this.disabled = false;
}
}
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1,
h2 {
font-weight: normal;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
.group {
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
/* box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12), 0 0 6px rgba(0, 0, 0, 0.04); */
text-align: center;
width: 500px;
/* border-inline-width: 80px; */
/* padding: 24px; */
border-radius: 8px;
align-self: center;
text-align: left;
margin: auto;
/* position: absolute; */
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.el-checkbox-group {
width: 320px;
float: left;
margin: 0;
padding: 0;
list-style: none;
}
.el-checkbox {
float: left;
width: 160px;
margin: 0;
padding: 0;
}
.el-radio-group {
width: 320px;
/* float:left; */
margin: 0;
padding: 0;
list-style: none;
}
.el-radio {
float: left;
width: 160px;
margin: 0;
padding: 0;
}
.el-form {
/* box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12), 0 0 6px rgba(0, 0, 0, 0.04); */
border-inline-width: 80px;
padding: 24px;
border-radius: 4px;
align-self: center;
text-align: left;
width: 350px;
}
</style>