变更数据库地址 & 删除前端代码

This commit is contained in:
2020-11-24 16:16:54 +08:00
parent 08fd287667
commit 4488f56d7d
28 changed files with 4 additions and 13992 deletions
@@ -36,8 +36,8 @@ public class SwaggerConfig {
return new ApiInfoBuilder()
.title("BookVO API")
.description("Bill接口")
.termsOfServiceUrl("http://fairy8.cn")
.contact(new Contact("Alawn","fairy8.cn","alawn.cn@gmail.com"))
.termsOfServiceUrl("http://alawn.cn")
.contact(new Contact("Alawn","alawn.cn","alawn.cn@gmail.com"))
.version("1.0")
.build();
}
@@ -37,8 +37,7 @@ spring.security.password=admin
spring.datasource.sql-script-encoding=utf-8
spring.datasource.initialization-mode=always
spring.datasource.druid.driverClassName=com.mysql.jdbc.Driver
#spring.datasource.druid.url=jdbc:mysql://fairy8.cn:3308/test?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.druid.url=jdbc:mysql://fairy8.cn:3308/test?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.druid.url=jdbc:mysql://alawn.cn:3308/test?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.druid.max-open-prepared-statements=25
spring.datasource.druid.username=test
spring.datasource.druid.password=newland15%
@@ -37,8 +37,7 @@ spring.security.password=admin
spring.datasource.sql-script-encoding=utf-8
spring.datasource.initialization-mode=always
spring.datasource.druid.driverClassName=com.mysql.jdbc.Driver
#spring.datasource.druid.url=jdbc:mysql://fairy8.cn:3308/test?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.druid.url=jdbc:mysql://fairy8.cn:3308/bill?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.druid.url=jdbc:mysql://alawn.cn:3308/bill?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.druid.max-open-prepared-statements=25
spring.datasource.druid.username=bill
spring.datasource.druid.password={VKH>229
-6
View File
@@ -1,6 +0,0 @@
module.exports = {
extends: 'eslint:recommended',
rules: {
'no-console': 'off',
},
};
-29
View File
@@ -1,29 +0,0 @@
# bill
## Project setup
```
yarn install
```
### Compiles and hot-reloads for development
```
yarn run serve
```
### Compiles and minifies for production
```
yarn run build
```
### Run your tests
```
yarn run test
```
### Lints and fixes files
```
yarn run lint
```
### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).
-5
View File
@@ -1,5 +0,0 @@
module.exports = {
presets: [
'@vue/app'
]
}
-6
View File
@@ -1,6 +0,0 @@
#!/usr/bin/env sh
cd dist
tar czvf ../dist.tar.gz *
cd ..
scp dist.tar.gz gc:/tmp/
ssh gc "sudo tar xzvf /tmp/dist.tar.gz -C /home/bill/www;sudo systemctl reload nginx"
-11502
View File
File diff suppressed because it is too large Load Diff
-52
View File
@@ -1,52 +0,0 @@
{
"name": "bill",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"axios": "^0.19.0",
"core-js": "^2.6.5",
"crypto-js": "^3.1.9-1",
"element-ui": "^2.9.1",
"moment": "^2.24.0",
"vue": "^2.6.10",
"vue-json-excel": "^0.2.98",
"vue-router": "^3.0.6"
},
"devDependencies": {
"@vue/cli-plugin-babel": "^3.8.0",
"@vue/cli-plugin-eslint": "^3.8.0",
"@vue/cli-service": "^3.8.0",
"babel-eslint": "^10.0.1",
"eslint": "^5.16.0",
"eslint-plugin-vue": "^5.0.0",
"vue-template-compiler": "^2.6.10"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/essential",
"eslint:recommended"
],
"rules": {},
"parserOptions": {
"parser": "babel-eslint"
}
},
"postcss": {
"plugins": {
"autoprefixer": {}
}
},
"browserslist": [
"> 1%",
"last 2 versions"
]
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

-17
View File
@@ -1,17 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title>bill</title>
</head>
<body>
<noscript>
<strong>We're sorry but bill doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
-97
View File
@@ -1,97 +0,0 @@
<template>
<div id="app">
<!-- <img alt="logo" src="https://fairy8-1258530674.picsh.myqcloud.com/img/20190611100737.png" width="400px"> -->
<!-- <el-row :gutter="10"> -->
<div
style="width:800px;text-align:center;align-self: center;margin: auto;top: 0;left: 0;right: 0;bottom: 0;"
>
<!-- <div> -->
<el-row>
<!-- <el-col :span="4"><div class="grid-content bg-purple">b</div></el-col> -->
<el-col :span="16" :offset="4">
<div class="grid-content bg-purple" style="color:#0081FF;font-size:22px">Bill Assistant</div>
</el-col>
<el-col :span="4" style="text-align:right;">
<el-button v-if="showLogout()" type="text" @click="logout()">登出</el-button>
</el-col>
<!-- <el-col :span="16">
<div>
<span style="color:#0081FF;font-size:22px">Bills Assistant</span>
</div>
</el-col>
<el-col :span="4">
<el-button type="text">logout</el-button>
</el-col>-->
</el-row>
<!-- <HR align=center width=300 color=#987cb9 SIZE=1> -->
<!-- <hr style="border:1 dashed #987cb9" width="50%" color=#ACACAC size=1/> -->
<!-- <br/> -->
<!-- <router-link to="/login">登录页</router-link> -->
<p/>
<router-view v-if="isRouterAlive"/>
</div>
<!-- <HelloWorld msg="Welcome to Your Vue.js App"/> -->
<p/>
<img
alt="footer"
src="https://fairy8-1258530674.picsh.myqcloud.com/img/20190611100310.png"
width="150px"
>
</div>
</template>
<script>
// import HelloWorld from './components/HelloWorld.vue'
export default {
name: "app",
provide () {
return {
reload: this.reload
}
},
data(){
return {
isRouterAlive: true,
}
},
methods: {
logout() {
console.log("logout!");
window.localStorage.removeItem("token");
// console.log("window.localStorage:" + window.localStorage);
this.reload();
},
reload () {
this.isRouterAlive = false
this.$nextTick(function () {
this.isRouterAlive = true
})
},
showLogout () {
console.info("showLogout");
if (localStorage.token) {
console.info("showLogout:true");
return true;
}
else {
console.info("showLogout:false");
return false;
}
}
}
/*components: {
HelloWorld
}*/
};
</script>
<style>
#app {
font-family: "Avenir", Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
-59
View File
@@ -1,59 +0,0 @@
import HttpRequest from '@/axios/api.request'
export const newMerchant = (merc) => {
return HttpRequest.request({
url: 'api/merchants',
method: 'post',
data: merc
})
}
export const fetchMerchants = () => {
return HttpRequest.request({
url: 'api/merchants',
method: 'get'
})
}
export const fetchTitles = () => {
return HttpRequest.request({
url: 'api/titles',
method: 'get'
})
}
export const addTitle = (title) => {
return HttpRequest.request({
url: 'api/titles',
method: 'post',
data: title
})
}
export const getMerchant = (id) => {
return HttpRequest.request({
url: 'api/merchants/' + id,
method: 'get'
})
}
export const addPost = (post) => {
return HttpRequest.request({
url: 'api/posts',
method: 'post',
data: post
})
}
export const fetchPosts = () => {
return HttpRequest.request({
url: 'api/posts',
method: 'get'
})
}
export const getPost = (id) => {
return HttpRequest.request({
url: 'api/posts/' + id,
method: 'get'
})
}
-25
View File
@@ -1,25 +0,0 @@
import HttpRequest from '@/axios/api.request'
export const newBill = (bill) => {
return HttpRequest.request({
url: 'api/bill/books',
method: 'post',
data: bill
})
}
export const fetchBooks = () => {
return HttpRequest.request({
url: 'api/bill/books',
method: 'get'
})
}
export const dropBook = (bookId) => {
return HttpRequest.request({
url: 'api/bill/books/' + bookId,
method: 'delete',
})
}
-24
View File
@@ -1,24 +0,0 @@
import HttpRequest from '@/axios/api.request'
export const login = (ruleForm) => {
return HttpRequest.request({
url: 'auth',
method: 'post',
data: ruleForm
})
}
export const register = (user) => {
return HttpRequest.request({
url: 'api/users',
method: 'post',
data: user
})
}
export const isTokenValid = (token) => {
return HttpRequest.request({
url: 'auth/valid?token=' + token,
method: 'post',
})
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

@@ -1,11 +0,0 @@
import axios from 'axios'
import config from './index'
const baseUrl = process.env.NODE_ENV === 'development' ? config.baseUrl.dev : config.baseUrl.pro
const HttpRequest = axios.create({
// api的base_url
baseURL: baseUrl,
// 请求超时时间
timeout: 10000
})
export default HttpRequest
-10
View File
@@ -1,10 +0,0 @@
export default {
/**
* @description api请求基础路径
*/
baseUrl: {
dev: 'http://localhost:30000',
pro: 'https://fairy8.cn:30443'
// pro: 'https://bill.fairy8.cn/api'
}
};
@@ -1,58 +0,0 @@
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<p>
For a guide and recipes on how to configure / customize this project,<br>
check out the
<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
</p>
<h3>Installed CLI Plugins</h3>
<ul>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a></li>
</ul>
<h3>Essential Links</h3>
<ul>
<li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
<li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
</ul>
<h3>Ecosystem</h3>
<ul>
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
</ul>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>
-133
View File
@@ -1,133 +0,0 @@
import Vue from 'vue'
import App from './App.vue'
import router from '@/router/index.js'
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.config.productionTip = false
Vue.component('downloadExcel', JsonExcel)
Vue.use(ElementUI)
Vue.prototype.$moment = moment;
/**
* Loading实现
* */
let loading //定义loading变量
function startLoading() { //使用Element loading-start 方法
loading = ElementUI.Loading.service({
lock: true,
text: '加载中……',
background: 'rgba(0, 0, 0, 0.7)'
})
}
function endLoading() { //使用Element loading-close 方法
loading.close()
}
let needLoadingRequestCount = 0
export function showFullScreenLoading() {
if (needLoadingRequestCount === 0) {
startLoading()
}
needLoadingRequestCount++
}
export function tryHideFullScreenLoading() {
if (needLoadingRequestCount <= 0) return
needLoadingRequestCount--
if (needLoadingRequestCount === 0) {
endLoading()
}
}
/**
* Axios 拦截器
*/
HttpRequest.interceptors.request.use(
config => {
// 判断token是否存在
if (localStorage.token) {
// 将token设置成请求头
config.headers.Authorization = localStorage.token
}
// config.headers.Authorization = "Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhbGF3biIsImNyZWF0ZWQiOjE1NTg2ODY4MTk0NjcsImlhdCI6MTU1ODY4NjgxOSwiZXhwIjoxNTU5MjkxNjE5fQ.N9ZSMrStIaUyngSpvmup_akXQaueLSIX5-h4Q_fixdM" //将token设置成请求头
// showFullScreenLoading()
return config
}, function(err) {
return Promise.reject(err)
}
)
// http response 拦截器
HttpRequest.interceptors.response.use(
response => {
// tryHideFullScreenLoading()
return response;
},
error => {
// tryHideFullScreenLoading()
if (error.response) {
switch (error.response.status) {
case 401:
// 返回 401 清除token信息并跳转到登录页面
// store.commit(types.LOGOUT);
localStorage.removeItem('token');
router.replace({
path: 'login',
query: {redirect: router.currentRoute.fullPath}
})
}
}
return Promise.reject(error.response.data) // 返回接口返回的错误信息
}
);
router.beforeEach((to, from, next) => {
if (to.meta.requireAuth) { // 判断该路由是否需要登录权限
if (localStorage.token) {
next();
}
else {
next({
path: '/login',
query: {redirect: to.fullPath} // 将跳转的路由path作为参数,登录成功后跳转到该路由
})
}
// if (store.state.token) {
// next();
// }
// else {
// next({
// path: '/login',
// query: {redirect: to.fullPath}
// })
// }
}
else {
next();
}
})
new Vue({
router,
render: h => h(App),
}).$mount('#app')
-48
View File
@@ -1,48 +0,0 @@
import Vue from 'vue'
import VueRouter from 'vue-router'
/** import HelloWorld from '@/components/HelloWorld'*/
Vue.use(VueRouter)
export default new VueRouter({
routes: [
{
path: '/',
name: 'Index',
redirect: '/gird'
},
{
path: '/merchant',
name: 'Merchant',
meta: {
requireAuth: true, // 添加该字段,表示进入这个路由是需要登录的
},
component: () => import('../views/Merchant.vue')
},
{
path: '/register',
name: 'Register',
component: () => import('../views/Register.vue')
},
{
path: '/login',
name: 'Login',
component: () => import('../views/Login.vue')
},
{
path: '/bill',
name: 'Bill',
meta: {
requireAuth: true, // 添加该字段,表示进入这个路由是需要登录的
},
component: () => import('../views/Bill.vue')
},
{
path: '/gird',
name: 'Gird',
meta: {
requireAuth: true, // 添加该字段,表示进入这个路由是需要登录的
},
component: () => import('../views/Gird.vue')
}
]
})
-50
View File
@@ -1,50 +0,0 @@
import CryptoJS from 'crypto-js/crypto-js'
// 默认的 KEY 与 iv
const KEY = CryptoJS.enc.Hex.parse("3132333435363738393041424344454631323334353637383930414243444566");
const IV = CryptoJS.enc.Hex.parse('30313233343536373839414243444546');
/**
* AES加密
*/
export function encrypt(word, keyStr, ivStr) {
let key = KEY
let iv = IV
if (keyStr) {
key = CryptoJS.enc.Utf8.parse(keyStr);
iv = CryptoJS.enc.Utf8.parse(ivStr);
}
// 传过来的密码
let srcs = CryptoJS.enc.Utf8.parse(word);
var encrypted = CryptoJS.AES.encrypt(srcs, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
// console.log("-=-=-=-", encrypted.ciphertext)
return encrypted.ciphertext.toString()
}
/**
* AES 解密
*
*/
export function decrypt(word, keyStr, ivStr) {
let key = KEY
let iv = IV
if (keyStr) {
key = CryptoJS.enc.Utf8.parse(keyStr);
iv = CryptoJS.enc.Utf8.parse(ivStr);
}
let src = CryptoJS.format.Hex.parse(word);
var decrypt = CryptoJS.AES.decrypt(src, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
return CryptoJS.enc.Utf8.stringify(decrypt)
}
-788
View File
@@ -1,788 +0,0 @@
<template>
<div class="main">
<div class="group">
<!-- <el-form ref="form" :model="form" :rules="rules" label-width="80px"> -->
<!-- <el-form ref="form" :model="form" label-width="800px"> -->
<el-form ref="billForm" :model="bill" :rules="rules" label-width="80px">
<el-row>
<el-col :span="17">
<el-form-item label="邮寄地址" prop="postContact">
<!--邮寄地址-->
<el-autocomplete
class="posts"
popper-class="my-autocomplete"
v-model="bill.postContact"
:fetch-suggestions="querySearchAsyncPosts"
placeholder="请输选择邮寄地址"
@select="handleSelectPosts"
:disabled="disabled"
>
<i class="el-icon-edit el-input__icon" slot="suffix" @click="handleIconClickPosts"></i>
<template slot-scope="{ item }">
<div class="name">{{ item.contact }}</div>
<span class="subtitle">{{ item.address }}</span>
<span class="subtitle">;</span>
<span class="subtitle">{{ item.mobile }}</span>
<span class="subtitle">;</span>
</template>
</el-autocomplete>
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item label="" label-width="80px">
<el-checkbox v-model="bill.sentQuick" :checked="true" :disabled="disabled">立即发送</el-checkbox>
</el-form-item>
</el-col>
</el-row>
<div class="gTable">
<!--增删改查-->
<!--明细-->
<!-- <el-form-item label="明细" prop="username"> -->
<!--分割线-->
<!-- <span><el-divider></el-divider></span> -->
<el-table :data="bill.items" height="400px" style="width: 100%" >
<el-table-column prop="dating" label="日期" width="100"></el-table-column>
<el-table-column prop="titleAbbr" label="抬头" width="150">
<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>
</template>
</el-table-column>
<el-table-column prop="merchantAbbr" label="餐饮商户" width="130"></el-table-column>
<el-table-column prop="amount" label="金额" width="80"></el-table-column>
<el-table-column prop="feeRate" label="税率" width="60"></el-table-column>
<el-table-column align="right">
<template slot="header">
<!-- <el-button class="itemBtn" type="primary" size="medium" @click="clearFocusRow();isAddShow = true;resetForm('addForm');" :disabled="disabled">添加</el-button> -->
<el-button
class="itemBtn"
type="primary"
size="small"
@click="clearFocusRow();isAddShow = true"
:disabled="disabled"
>添加</el-button>
</template>
<template slot-scope="scope">
<el-button-group>
<!-- type="success" -->
<el-button
size="mini"
icon="el-icon-edit"
@click="handleEdit(scope.$index, scope.row)"
:disabled="disabled"
>编辑</el-button>
<!-- type="danger" -->
<el-button
size="mini"
icon="el-icon-delete"
@click.native.prevent="handleDelete(scope.$index,bill.items)"
:disabled="disabled"
>删除</el-button>
</el-button-group>
</template>
</el-table-column>
</el-table>
<!-- </el-form-item> -->
</div>
<el-form-item label-width="2px">
<el-row >
<el-col :span="4">
<el-button class="submit" type="primary" @click="onSubmit('billForm')" :disabled="disabled" >提交</el-button>
</el-col>
<el-col :span="4">
<el-button class="submit" @click="cancel()" >取消</el-button>
</el-col>
<el-col :offset="2" :span="7">
<!-- 总金额 -->
<el-form-item label="总票额" style="padding:0">
<el-input type="text" v-model="totalAmount" :readonly="true" maxlength="20" prefix-icon="el-icon-coin" ></el-input>
</el-form-item>
</el-col>
<el-col :span="7">
<!-- 总费率 -->
<el-form-item label="总税金" style="padding:0">
<el-input type="text" v-model="totalFee" :readonly="true" maxlength="20" prefix-icon="el-icon-coin" ></el-input>
</el-form-item>
</el-col>
</el-row>
<!-- <el-input v-model="input" placeholder="请输入内容"></el-input> -->
</el-form-item>
</el-form>
</div>
<!--增加-->
<div width="600px">
<el-dialog title="增加" :visible.sync="isAddShow" width="700px" @close="resetFormFields('addForm')">
<el-form ref="addForm" :model="focusRow" :rules="rules" label-width="80px">
<el-row>
<el-col :span="24">
<!--抬头-->
<el-form-item label="抬头简称" prop="titleAbbr">
<el-autocomplete
class="titles"
popper-class="my-autocomplete"
v-model="focusRow.titleAbbr"
:fetch-suggestions="querySearchAsyncTitles"
placeholder="请输选择抬头"
@select="handleSelectTitles"
>
<i
class="el-icon-edit el-input__icon"
slot="suffix"
@click="handleIconClickTitles"
></i>
<template slot-scope="{ item }">
<div class="name">{{ item.abbr }}</div>
<span class="subtitle">{{ item.name }}</span>
<span class="subtitle">({{ item.taxNo }})</span>
</template>
</el-autocomplete>
</el-form-item>
</el-col>
</el-row>
<!--商户-->
<el-row>
<el-col :span="24">
<el-form-item label="开票商家" prop="merchantAbbr">
<el-autocomplete
class="merchants"
v-model="focusRow.merchantAbbr"
:fetch-suggestions="querySearchAsyncMerchant"
placeholder="请选择餐饮商户"
@select="handleSelectMerchant"
>
<i
class="el-icon-edit el-input__icon"
slot="suffix"
@click="handleIconClickMerchant"
></i>
<template slot-scope="{ item }">
<div class="name">{{ item.abbr }}</div>
<span class="subtitle">{{ item.name }}</span>
<span class="subtitle">(税率:{{ item.feeRate }})</span>
</template>
</el-autocomplete>
</el-form-item>
</el-col>
</el-row>
<!--日期 & 金额-->
<el-row>
<el-col :span="12">
<!--开票日期-->
<el-form-item label="开票日期" prop="dating">
<el-date-picker
type="date"
placeholder="选择日期"
v-model="focusRow.dating"
style="width: 100%;"
value-format="yyyy-MM-dd"
></el-date-picker>
</el-form-item>
</el-col>
<el-col :span="1">
<!--金额-->
<el-form-item label="开票金额" prop="amount">
<el-input-number
v-model="focusRow.amount"
:precision="2"
:step="100"
controls-position="right"
:min="0"
:max="5000"
></el-input-number>
</el-form-item>
</el-col>
</el-row>
<el-form-item>
<el-button type="primary" @click="addItem('addForm')" :disabled="disabled">确 定</el-button>
<el-button @click="resetFormFields('addForm')">重置</el-button>
</el-form-item>
</el-form>
</el-dialog>
</div>
<!--编辑-->
<div width="600px">
<el-dialog title="编辑" :visible.sync="isEditShow" width="700px" @close="resetFormFields('editForm')">
<el-form ref="editForm" :model="focusRow" :rules="rules" label-width="80px">
<el-row>
<el-col :span="24">
<!--抬头-->
<el-form-item label="抬头简称" prop="titleAbbr">
<el-autocomplete
class="titles"
popper-class="my-autocomplete"
v-model="focusRow.titleAbbr"
:fetch-suggestions="querySearchAsyncTitles"
placeholder="请输选择抬头"
@select="handleSelectTitles"
>
<i
class="el-icon-edit el-input__icon"
slot="suffix"
@click="handleIconClickTitles"
></i>
<template slot-scope="{ item }">
<div class="name">{{ item.abbr }}</div>
<span class="subtitle">{{ item.name }}</span>
<span class="subtitle">({{ item.taxNo }})</span>
</template>
</el-autocomplete>
</el-form-item>
</el-col>
</el-row>
<!--商户-->
<el-row>
<el-col :span="24">
<el-form-item label="开票商家" prop="merchantAbbr">
<el-autocomplete
class="merchants"
v-model="focusRow.merchantAbbr"
:fetch-suggestions="querySearchAsyncMerchant"
placeholder="请选择餐饮商户"
@select="handleSelectMerchant"
>
<i class="el-icon-edit el-input__icon" slot="suffix" @click="handleIconClickMerchant" ></i>
<template slot-scope="{ item }">
<div class="name">{{ item.abbr }}</div>
<span class="subtitle">{{ item.name }}</span>
<span class="subtitle">(税率:{{ item.feeRate }})</span>
</template>
</el-autocomplete>
</el-form-item>
</el-col>
</el-row>
<!--日期 & 金额-->
<el-row>
<el-col :span="12">
<!--开票日期-->
<el-form-item label="开票日期" prop="dating">
<el-date-picker
type="date"
placeholder="选择日期"
v-model="focusRow.dating"
style="width: 100%;"
value-format="yyyy-MM-dd"
></el-date-picker>
</el-form-item>
</el-col>
<el-col :span="1">
<!--金额-->
<el-form-item label="开票金额" prop="amount">
<el-input-number
v-model="focusRow.amount"
:precision="2"
:step="100"
controls-position="right"
:min="0"
:max="5000"
></el-input-number>
</el-form-item>
</el-col>
</el-row>
<!-- <div slot="footer" class="dialog-footer"> -->
<el-form-item>
<el-button type="primary" @click="updateItem('editForm')" :disabled="disabled">确 定</el-button>
<!-- <el-button type="primary" @click="updateItem()" >确 定</el-button> -->
<el-button @click="resetFormFields('editForm')">重置</el-button>
</el-form-item>
<!-- </div> -->
</el-form>
</el-dialog>
</div>
<!--添加邮寄地址-->
<div width="600px">
<el-dialog title="增加地址" :visible.sync="isPostEditShow" width="700px">
<el-form ref="addPost" :model="post" :rules="rules" label-width="80px">
<!--地址-->
<el-form-item label="地址">
<el-input v-model="post.address"></el-input>
</el-form-item>
<el-form-item label="联系人">
<el-input v-model="post.contact"></el-input>
</el-form-item>
<el-form-item label="联系电话">
<el-input v-model="post.mobile"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="addPost()">添加</el-button>
<!-- <el-button>取消</el-button> -->
</el-form-item>
<!-- <div slot="footer" class="dialog-footer">
<el-button type="primary" @click="addItem('addForm')" :disabled="disabled">确 定</el-button>
<el-button @click="resetForm('addForm')">重置</el-button>
</div> -->
</el-form>
</el-dialog>
</div>
<!--添加抬头-->
<div width="600px">
<el-dialog title="增加抬头" :visible.sync="isTitleEditShow" width="700px">
<el-form ref="addTitle" :model="title" :rules="rules" label-width="80px">
<!--地址-->
<el-form-item label="简称">
<el-input v-model="title.abbr"></el-input>
</el-form-item>
<el-form-item label="抬头">
<el-input v-model="title.contact"></el-input>
</el-form-item>
<el-form-item label="税号">
<el-input v-model="title.taxNo"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="addTitle()">添加</el-button>
</el-form-item>
</el-form>
</el-dialog>
</div>
</div>
</template>
<script>
import { addTitle, addPost, fetchPosts, getPost, fetchTitles, fetchMerchants } from "../api/basic.js";
import { newBill } from "../api/bill.js";
export default {
name: "Bill",
data() {
return {
isAddShow: false,
isEditShow: false,
isPostEditShow: false,
isTitleEditShow: 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 },
post:{address:"",contact:"",mobile:""},
title:{abbr:"",name:"",taxNo:""},
focusRow: {},
totalFee: 0.00,
totalAmount: 0.00,
bill: {
postId: "",
// postAddress: "",
postContact: "",
// postMobile : "",
// postId: "",
// postAddress: "",
sendQuick: false,
items: [
// { dating: "2019-05-28", titleId: null, titleAbbr: "上海沐融",titleName:"",taxNo: "" ,merchantId: null, merchantAbbr: "华容月",amount: 0.0 },
// { dating: "2019-05-28", titleId: null, titleAbbr: "上海沐融",titleName:"",taxNo: "" ,merchantId: null, merchantAbbr: "华容月",amount: 0.0 },
// { dating: "2019-05-28", titleId: null, titleAbbr: "上海沐融",merchantId: null, merchantAbbr: "华容月",amount: 0.0 },
// { dating: "2019-05-28", titleId: null, titleAbbr: "上海沐融",merchantId: null, merchantAbbr: "华容月",amount: 0.0 },
// { dating: "2019-05-28", titleId: null, titleAbbr: "上海沐融",merchantId: null, merchantAbbr: "华容月",amount: 0.0 },
]
},
rules: {
postContact: [
{ required: true, message: "请选择邮寄地址", trigger: "change" }
// { min: 3, max: 15, message: "长度在 3 到 15 个字符", trigger: "blur" }
],
merchantAbbr: [
{ required: true, message: "请选择餐饮商户", trigger: "change" }
],
titleAbbr: [
{ required: true, message: "请选择抬头", trigger: "change" }
],
dating: [{ required: true, message: "选择日期", trigger: "blur" }],
amount: [
{ required: true, message: "请输入金额", trigger: "blur" },
{ type: "number", message: "金额必须为数字值" }
]
}
};
},
methods: {
resetFormFields(formName){
// console.info('resetFormFields.formName:' + formName);
// console.info('resetFormFields.resetFields');
// this.$refs[formName].resetFields();
console.info('resetFormFields.formName:' + formName);
this.$nextTick(()=>{
// console.info('resetFormFields.this:' + JSON.stringify(this.$refs));
this.$refs[formName].resetFields();
});
},
addPost() {
addPost(this.post).then(res=>{
this.loadPosts();
this.isPostEditShow = false;
this.$message({ message: "提交成功", type: "success" });
})
},
cancel() {
this.$router.go(-1);
},
// resetForm(formName) {
// console.info('formName:' + formName);
// // console.info('this.$refs' + JSON.stringify(this.$refs));
// 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.items:" + JSON.stringify(this.bill.items)
);
this.recount();
this.bill.items.splice(0, 0, this.focusRow);
console.info(
"this.bill.items:" + JSON.stringify(this.bill.items)
);
// this.clearFocusRow();
console.info("focusRow:" + JSON.stringify(this.focusRow));
this.isAddShow = false;
} else {
console.log("error submit!!");
return false;
}
});
this.$nextTick(()=>{
console.info('resetFormFields.resetFields');
this.$refs[formName].resetFields();
});
this.clearFocusRow();
},
/** 在表格中添加明细 */
updateItem(formName) {
var oriForm = 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.items:" + JSON.stringify(this.bill.items)
);
var index = this.focusRow.index;
this.recount();
this.bill.items.splice(index, 1, this.focusRow);
console.info(
"this.bill.items:" + JSON.stringify(this.bill.items)
);
// this.clearFocusRow();
console.info("focusRow:" + JSON.stringify(this.focusRow));
this.isEditShow = false;
} else {
console.log("error submit!!");
return false;
}
});
this.$nextTick(()=>{
console.info('resetFormFields.resetFields');
this.$refs[formName].resetFields();
});
this.clearFocusRow();
},
recount() {
this.totalFee += this.focusRow.feeRate * this.focusRow.amount;
this.totalFee = parseFloat(this.totalFee).toFixed(2);
this.totalAmount += this.focusRow.amount;
this.totalAmount = parseFloat(this.totalAmount).toFixed(2);
console.info('totalAmount:' + this.totalAmount);
console.info('totalFee:' + this.totalFee);
},
/** 表格-编辑一行 */
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 => {
var _this = this;
if (valid) {
console.info("bill:" + JSON.stringify(this.bill));
this.disabled = true;
newBill(this.bill).then(response=> {
this.$message({ message: "提交成功", type: "success" });
console.info("response:" + response);
this.$router.push({ path: 'Gird' })
})
.catch(function(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: 'status:' + error.response.status + ',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);
_this.$message.error(error.error);
}
console.log(error.config);
});
} else {
console.log("error submit!!");
return false;
}
});
},
/** AutoComplete Posts 处理*/
querySearchAsyncPosts(queryString, cb) {
var results = queryString ? this.posts.filter(this.createFilterPosts(queryString)):this.posts;
cb(results);
},
createFilterPosts(queryString) {
return post => {
return (
post.contact.toLowerCase().indexOf(queryString.toLowerCase()) === 0
);
};
},
loadPosts() {
console.info("loadPosts");
// console.info("$ref:" + );
fetchPosts().then(res=>{
console.info("res:" + res);
console.info("res.data:" + JSON.stringify(res.data));
this.posts = res.data;
for (let i of this.posts) {
i.value = i.contact; //将想要展示的数据作为value
}
})
console.info("posts:" + JSON.stringify(this.posts));
},
handleSelectPosts(item) {
this.bill.postId = item.id;
console.log("postId:" + this.bill.postId);
console.log("postContact:" + this.bill.postContact);
},
handleIconClickPosts(ev) {
this.isPostEditShow = true;
console.log('handleIconClickPosts');
console.log(ev);
},
/** AutoComplete Titles 处理*/
querySearchAsyncTitles(queryString, cb) {
var results = queryString ? this.titles.filter(this.createFilterTitles(queryString)):this.titles;
cb(results);
},
createFilterTitles(queryString) {
return title => {
return (
title.abbr.toLowerCase().indexOf(queryString.toLowerCase()) === 0
);
};
},
loadTitles() {
fetchTitles().then(res=>{
this.titles = res.data;
for (let i of this.titles) {
i.value = i.abbr; //将想要展示的数据作为value
}
})
},
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 results = queryString ? this.merchants.filter(this.createFilterMerchant(queryString)):this.merchants;
cb(results);
},
createFilterMerchant(queryString) {
return merchant => {
return (
merchant.abbr.toLowerCase().indexOf(queryString.toLowerCase()) === 0
);
};
},
handleSelectMerchant(item) {
this.focusRow.merchantId = item.id;
this.focusRow.feeRate = item.feeRate;
this.focusRow.merchantsAbbr = item.abbr;
console.log("merchantId:" + this.focusRow.merchantId);
console.log("merchantsAbbr:" + this.focusRow.merchantsAbbr);
console.log("merchantsName:" + item.name);
console.log("merchantsFee:" + item.feeRate);
},
handleIconClickMerchant(ev) {
console.log(ev);
},
loadMerchant() {
fetchMerchants().then(res=>{
this.merchants = res.data;
for (let i of this.merchants) {
i.value = i.abbr; //将想要展示的数据作为value
}
})
},
/** 清理当前缓存 */
clearFocusRow() {
// console.log(this.$refs)
this.focusRow = {};
console.info("clearFocusRow");
}
},
async mounted() {
await this.loadPosts();
await this.loadTitles();
await this.loadMerchant();
}
};
</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;
}
.el-form-item {
/* width: 200px; */
/* margin: 10px; */
float: inherit;
padding: 20px;
}
.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: 800px;
/* 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;
}
.gTable {
/* 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: left;
width: 700px;
/* border-inline-width: 80px; */
/* padding: 24px; */
/* border-radius: 8px; */
align-self: left;
margin-left: 24px;
/* margin: auto; */
/* position: absolute; */
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.itemBtn {
width: 100px;
float: right;
}
.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; */
/* border-inline-width: 200px; */
padding: 24px;
border-radius: 4px;
/* align-self: center; */
align-self: center;
text-align: left;
/* width: 800px; */
}
.name {
text-overflow: ellipsis;
overflow: hidden;
/* line-height: small; */
}
.subtitle {
font-size: 13px;
color: #b4b4b4;
}
/* .highlighted .subtitle {
color: #ddd;
} */
/* .my-autocomplete {
li {
line-height: small;
padding: 1px;
.name {
text-overflow: ellipsis;
overflow: hidden;
}
.subtitle {
font-size: 12px;
color: #b4b4b4;
}
.highlighted .addr {
color: #ddd;
}
}
} */
.posts,
.titles,
.merchants {
width: 487px;
}
/* .posts {
width: 300px;
} */
.el-form-item {
margin-bottom: 0px;
}
.submit {
width: 100px;
}
</style>
-366
View File
@@ -1,366 +0,0 @@
<template>
<div class="main">
<div class="group">
<el-table
v-loading="isGirdLoading"
: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="totalFee" 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">
<p>手机: {{ scope.row.post.mobile }}</p>
<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="state" label="状态" width="100">
<template slot-scope="scope">
<!-- <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>
<span v-if="scope.row.state=='Droped'" style="color:gray;font-size:13px;">已撤销</span>
</template>
</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>
<el-button @click="dropBookHandle(scope.row)" type="text" size="small">
撤销
<i class="el-icon-delete-solid el-icon--right"></i>
</el-button>
</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>
</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="100"></el-table-column>
<el-table-column prop="fee" label="税金" width="80"></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 { fetchBooks, dropBook } from "../api/bill.js";
export default {
name: "Gird",
data() {
return {
isGirdLoading: true,
isAddShow: false,
isEditShow: false,
isDetailShow: false,
posts: [],
titles: [],
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: {
id: 0,
post: {
id: 0,
address: "",
contact: "",
mobile: ""
},
items: [
{
id: 0,
title: {
id: 0,
name: "",
abbr: "",
taxNo: ""
},
merchant: {
id: 0,
abbr: "",
name: "",
feeRate: 0,
trial: 0
},
dating: "",
amount: 0.0
}
],
state: "",
applyDate: "",
acceptDate: null,
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" }
// { min: 3, max: 15, message: "长度在 3 到 15 个字符", trigger: "blur" }
],
merchantAbbr: [
{ required: true, message: "请选择餐饮商户", trigger: "change" }
],
titleAbbr: [
{ required: true, message: "请选择抬头", trigger: "change" }
],
dating: [{ required: true, message: "选择日期", trigger: "blur" }],
amount: [
{ required: true, message: "请输入金额", trigger: "blur" },
{ type: "number", message: "金额必须为数字值" }
]
}
};
},
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;
},
dropBookHandle(rows) {
if (this.focusRow.state != "Applied") {
this.$message.error("只有申请中的才能撤销");
return;
}
this.$confirm("此操作将作废该开票请求, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
dropBook(this.focusRow.id).then(res => {
this.$message({ type: "success", message: "撤销成功!" });
this.refresh();
});
}).catch(() => {
this.$message({ type: 'info', message: '已取消' });
});
},
redirectBill() {
this.$router.push({ path: "Bill" });
},
refresh() {
fetchBooks().then(res => {
// console.info("res.data:" + res.data);
this.isGirdLoading = true;
this.book = res.data;
this.isGirdLoading = false;
});
},
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();
},
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() {
this.focusRow = {};
console.info("clearFocusRow");
}
},
mounted() {
this.refresh();
// this.posts = this.loadPosts();
// console.info('mounted.this.posts:' + posts);
}
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.subtitle {
font-size: 12px;
color: #b4b4b4;
}
h1,
h2 {
font-weight: normal;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
.el-form-item {
/* width: 200px; */
/* margin: 10px; */
float: inherit;
padding: 20px;
}
.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: 800px;
/* 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;
}
.gTable {
/* 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: left;
width: 700px;
/* border-inline-width: 80px; */
/* padding: 24px; */
/* border-radius: 8px; */
align-self: left;
margin-left: 24px;
/* margin: auto; */
/* position: absolute; */
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.billBtn {
width: 100px;
float: right;
}
.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; */
/* border-inline-width: 200px; */
padding: 24px;
border-radius: 4px;
/* align-self: center; */
align-self: center;
text-align: left;
/* width: 800px; */
}
.posts,
.titles,
.merchants {
width: 487px;
}
.el-form-item {
margin-bottom: 0px;
}
.submit {
width: 100px;
}
</style>
-207
View File
@@ -1,207 +0,0 @@
<template>
<div class="login">
<div class="group">
<el-form v-loading="disabled" 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="password">
<el-input
v-model="ruleForm.password"
@keyup.enter.native="onSubmit('ruleForm')"
show-password
placeholder="请输入密码"
></el-input>
</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>
</template>
<script>
import { login } from "../api/user.js";
import { encrypt, decrypt } from "../utils/encoder.js";
export default {
name: "Login",
data() {
return {
disabled: false,
ruleForm: {
username: "",
password: ""
},
rules: {
username: [
{ required: true, message: "请输入户名", trigger: "blur" },
{ min: 3, max: 15, message: "长度在 3 到 30 个字符", trigger: "blur" }
],
password: [
{ required: true, message: "请输入密码", trigger: "change" },
{ min: 3, max: 15, message: "长度在 3 到 30 个字符", trigger: "blur" }
]
}
};
},
methods: {
onSubmit(formName) {
this.$refs[formName].validate(valid => {
var _this = this;
if (valid) {
this.disabled = true;
/** 加密处理 */
var encoderStr = encrypt(this.ruleForm.password);
console.log("密文:" + encoderStr);
console.log("解密:" + decrypt(encoderStr));
this.ruleForm.password = encoderStr;
/** 访问登录服务 */
login(this.ruleForm)
.then(res => {
var token = "Bearer " + res.data.token;
console.log("token:" + token);
window.localStorage.setItem("token", token);
this.$message({ message: "登录成功", type: "success" });
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
_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);
console.log("Error", error.status);
if (error.status == 401) {
_this.$message.error("用户名或密码有误");
_this.reset("ruleForm");
// _this.ruleForm.password = '';
} else {
// _this.ruleForm.password = '';
_this.$message.error(error.status + ':' + error.message);
_this.reset("ruleForm");
}
}
console.log(error.config);
// _this.$message.error(error.response.statusText);
});
} else {
console.log("error submit!!");
return false;
}
});
},
reset(formName) {
console.log("reset");
this.$refs[formName].resetFields();
// this.$refs[formName].focus();
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>
-138
View File
@@ -1,138 +0,0 @@
<template>
<div class="merchant">
<div class="group">
<!-- <form class="el-form bill"> -->
<el-form ref="form" :model="form" label-width="80px">
<el-form-item label="商户简称">
<el-input v-model="merc.abbr"></el-input>
</el-form-item>
<el-form-item label="商户全称">
<el-input v-model="merc.name"></el-input>
</el-form-item>
<el-form-item label="费率">
<el-input v-model="merc.feeRate"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">立即创建</el-button>
<el-button>取消</el-button>
</el-form-item>
</el-form>
<!-- </form> -->
</div>
</div>
</template>
<script>
import { newMerchant, fetchMerchants, getMerchant } from "../api/basic.js";
export default {
name: "Merchant",
data() {
return {
merc: {
name: "",
abbr: "",
feeRate: 0.08
}
};
},
methods: {
onSubmit() {
console.log("submit!");
console.log("merc:" + this.merc.name);
// MerchantAddAction(JSON.stringify(this.merc))
newMerchant(this.merc).then(res => {
var merchantId = res.data.id;
console.log("res.data.code" + res.data.code);
this.$message({ message: "恭喜你,这是一条成功消息", type: "success" });
getMerchant(merchantId);
});
}
}
};
</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: 600px;
/* 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;
}
.merchant {
/* margin: 0 auto; */
/* text-align: center; */
/* background-color: #fff; */
/* border-radius: 20px; */
/* width: 300px;
height: 350px; */
/* 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: 480px;
}
</style>
-168
View File
@@ -1,168 +0,0 @@
<template>
<div class="merchant">
<div class="group">
<form class="el-form bill">
<el-form ref="form" :model="form" label-width="80px">
<el-form-item label="活动名称">
<el-input v-model="form.name"></el-input>
</el-form-item>
<el-form-item label="活动区域">
<el-select v-model="form.region" placeholder="请选择活动区域">
<el-option label="区域一" value="shanghai"></el-option>
<el-option label="区域二" value="beijing"></el-option>
</el-select>
</el-form-item>
<el-form-item label="活动时间">
<el-col :span="11">
<el-date-picker
type="date"
placeholder="选择日期"
v-model="form.date1"
style="width: 100%;"
></el-date-picker>
</el-col>
<el-col class="line" :span="2">-</el-col>
<el-col :span="11">
<el-time-picker placeholder="选择时间" v-model="form.date2" style="width: 100%;"></el-time-picker>
</el-col>
</el-form-item>
<el-form-item label="即时配送">
<el-switch v-model="form.delivery"></el-switch>
</el-form-item>
<el-form-item label="活动性质">
<el-checkbox-group v-model="form.type">
<el-checkbox label="美食/餐厅线上活动" name="type"></el-checkbox>
<el-checkbox label="地推活动" name="type"></el-checkbox>
<el-checkbox label="线下主题活动" name="type"></el-checkbox>
<el-checkbox label="单纯品牌曝光" name="type"></el-checkbox>
</el-checkbox-group>
</el-form-item>
<el-form-item label="特殊资源">
<el-radio-group v-model="form.resource">
<el-radio label="线上品牌商赞助"></el-radio>
<el-radio label="线下场地免费"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="活动形式">
<el-input type="textarea" v-model="form.desc"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">立即创建</el-button>
<el-button>取消</el-button>
</el-form-item>
</el-form>
</form>
</div>
</div>
</template>
<script>
export default {
name: "Merchant",
data() {
return {
form: {
name: "",
region: "",
date1: "",
date2: "",
delivery: false,
type: [],
resource: "",
desc: ""
}
};
},
methods: {
onSubmit() {
console.log("submit!");
}
}
};
</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: 600px;
/* 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;
}
.merchant {
/* margin: 0 auto; */
/* text-align: center; */
/* background-color: #fff; */
/* border-radius: 20px; */
/* width: 300px;
height: 350px; */
/* 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: 480px;
}
</style>
-187
View File
@@ -1,187 +0,0 @@
<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";
import { encrypt,decrypt } from "../utils/encoder.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 到 30 个字符", 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 到 30 个字符", trigger: "blur" }
]
}
};
},
methods: {
onSubmit(formName) {
this.$refs[formName].validate(valid => {
var _this = this;
if (valid) {
this.disabled = true;
/** 加密处理 */
var encoderStr = encrypt(this.ruleForm.password);
console.log('解密:' + decrypt(encoderStr));
this.ruleForm.password = encoderStr;
/** 访问注册服务 */
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.message);
}
console.log(error.config);
// return false;
_this.reset('ruleForm');
// _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>