# vue admin template

自己不断修改的vue admin 模板

## 全局的form表单验证

```html
<!-- 验证方法在@/utils/rules里面 -->
<el-form :model="loginForm" :rules="formRules" ref="loginForm" label-position="top">
    <el-form-item prop="username" :rules="formRules.required">
        <el-input placeholder="用户名" v-model="loginForm.username" size="default"> <i slot="prepend" class="el-icon-user-solid"></i> </el-input>
    </el-form-item>
    <el-form-item prop="password" :rules="formRules.password">
        <el-input show-password placeholder="密码" v-model="loginForm.password" size="default" @keydown.enter.native="handleSubmit"> <i slot="prepend" class="el-icon-lock"></i> </el-input>
    </el-form-item>
    <el-button @click="handleSubmit" type="primary" class="button-login" size="default" >提交</el-button>
</el-form>

<!-- 传其余参数可以使用下面的方法 -->
<el-form-item prop="confirmPassword" :rules="formRules.confirmPassword(registerForm)">
    <el-input show-password placeholder="再次输入密码" v-model="registerForm.confirmPassword" size="default">
        <i slot="prepend" class="el-icon-lock"></i>
    </el-input>
</el-form-item>
```

## 需要共享的全局枚举参数

> 全部放在`@/utils/enum.js`里面，已全部挂载到Vue.prototype下面

## 需要共享的全局方法

> 全部放在`@/utils/filter.js`里面，已全部挂载到Vue.prototype下面

## 所有的api请求

> 统一的axios参数在`@/api/index.js`下面，已全部挂载到Vue.prototype下面

```js
// 具体使用方法，例：
// 
methods: {
    async handleSubmit() {
        this.$refs.form.validate(async valid => {
            if (valid) {
                // this.$fetch第三个参数可选，默认'post',如果是使用get方法，第三个参数传'get'
                const data = await this.$fetch('/v1/front/otherApi', { ...this.form})
                if (data.code === 0) {
                    this.$message.success('提交成功')
                    this.$emit('success')
                    this.dialog = false
                } else {
                    this.reloadImg()
                }
            }
            
        })
    },
}
```

## dialog弹窗

> dialog弹窗尽量使用组件引入，dialog例子在`@/components/_dialog/exampleDialog`里面

```html
<!-- 应用例子 -->
<template>
    <exampleDialog v-if="exampleDialog.show" v-model="exampleDialog.show" :exampleData="exampleDialog.data" @success="searchSubmit"></exampleDialog>
</template>
```

## 表格统一分页，统一风格

> 使用`@/mixin/page.js` 使用前最好看一下

> 下面例子包含了表格统一和全局枚举（enum）的应用

```js
// 页面引用js部分
import page from '@/mixin/page'
export default {
    mixins: [page],
    data() {
        return {
            time: [],
            searchForm: {},
            tableData: [],
            tableUrl: '/v1/front/user/list'
        }
    },
    methods: {
        
    },
    mounted () {
        this.init()
    },
}
```

```html
<!-- template部分 -->
<template>
    <div>
        <div class="search-box">
            <el-form ref="form" :inline="true" :model="searchForm" clearable label-width="100px">
                <el-form-item label="变更时间:">
                    <el-date-picker
                        :editable="false"
                        v-model="time"
                        @change="timearr => {timearr ? (searchForm.create_time_start = timearr[0], searchForm.create_time_end = timearr[1]) : searchForm.create_time_start = searchForm.create_time_end = undefined}"
                        type="daterange"
                        value-format="yyyy-MM-dd"
                        start-placeholder="开始时间"
                        end-placeholder="结束时间"
                    ></el-date-picker>
                </el-form-item>
                <el-form-item label="收支状态:">
                    <el-select v-model="searchForm.budget_type" placeholder="全部">
                        <el-option label="全部" value></el-option>
                        <!-- 注意，这里budget_type就是放在全局enum中的参数 -->
                        <el-option v-for="(item, index) in budget_type" :key="index" :label="item" :value="index"></el-option>
                    </el-select>
                </el-form-item>
                <el-form-item class="ml-10">
                    <el-button class type="primary" @click="searchSubmit">查询</el-button>
                </el-form-item>
            </el-form>
        </div>
        <!-- 这里的vheight根据实际情况来 -->
        <el-table :data="tableData" stripe v-loading="tableLoading" fit class="marginT-10 order-table" border :max-height="vheight">
            <el-table-column label="创建时间" prop="create_time"></el-table-column>
            <el-table-column label="收支类型" align="center" prop="budget_type" :formatter="row => budget_type[row.budget_type]"></el-table-column>
            <el-table-column label="变更类型" align="center" prop="change_type" :formatter="row => $store.getters.enum.coin_change_type_arr[row.change_type]"></el-table-column>
            <el-table-column label="变更数目"  align="center" prop="coin_change_number" :formatter="row => row.coin_change_number + '金币'"></el-table-column>
            <el-table-column label="变更后数目"  align="center" prop="after_change_remain_coins" :formatter="row => row.after_change_remain_coins + '金币'"></el-table-column>
            <el-table-column label="备注" prop="remarks"></el-table-column>
        </el-table>
        <el-pagination 
            class="marginT-20"
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
            :hide-on-single-page="true"
            :current-page="page"
            :page-size="page_size"
            :page-sizes="[10, 20, 100, 200, 300, 400]"
            background
            layout="total, sizes, prev, pager, next, jumper"
            :total="totalCount" />
    </div>
</template>
```

## other

1. 有一些不需要放在vuex下面的，可以使用事件总线$bus,在`@/utils/vue-bus.js`里面。

## 需要node环境，最好在v10以上

---

### npm可以用，最好使用yarn

```bash
#npm 更换淘宝源
npm config set registry https://registry.npm.taobao.org
# 安装yarn
npm install yarn -g

#yarn 更换淘宝源
yarn config set registry https://registry.npm.taobao.org -g

#yarn 和 npm 设置 node-sass 参数
npm config set sass_binary_site=s://npm.taobao.org/mirrors/node-sass/ -g
yarn config set sass_binary_site https://npm.taobao.org/mirrors/node-sass/ -g

#npm 和 yarn 都设置一下puppeteer的下载参数 (暂时还不需要，如使用puppeteer服务器预渲染则需要设置)
// npm config set puppeteer_download_host=https://npm.taobao.org/mirrors
// yarn config set puppeteer_download_host https://npm.taobao.org/mirrors
```

### 安装依赖

```bash
yarn
## or
npm i
```

### 如果涉及到服务器预渲染，就需要下面依赖

```bash
# ubuntu
sudo apt install -y gconf-service libasound2 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget


#centos
sudo yum install pango.x86_64 libXcomposite.x86_64 libXcursor.x86_64 libXdamage.x86_64 libXext.x86_64 libXi.x86_64 libXtst.x86_64 cups-libs.x86_64 libXScrnSaver.x86_64 libXrandr.x86_64 GConf2.x86_64 alsa-lib.x86_64 atk.x86_64 gtk3.x86_64 ipa-gothic-fonts xorg-x11-fonts-100dpi xorg-x11-fonts-75dpi xorg-x11-utils xorg-x11-fonts-cyrillic xorg-x11-fonts-Type1 xorg-x11-fonts-misc
```

### 最后 打包

```bash
npm run build
## or
yarn build
```

### 数据导入
- [ ] 座位模板
- [ ] 艺人名单
- [ ] 艺人曲库
- [ ] 商品分类
- [ ] 商品附加
- [ ] 商品列表
- [ ] 门店

### 测试重点
* 订座
    * 不在开放预约预段内的，禁止预约
    * 当天的座位几点之后禁止预约
    * 同一种类型的座位，被预定完了，不能进入信息填写页面
    * 座位预定了，几点之后不能退订
    * 当天的座位退订几次以上，多长时间限制再次预约，联系客服接触限制【针对恶意竞争】
    * 退订的座位是不是回到可预订座位的池子里了
    * 预定信息填写也：默认值，到店人数最大值
    * 预定 - 支付 - 签到，流程是否可以走通，app、管理后台的演示
        * 是否可以提前签到【注：这里针对管理后台签到按钮被失误点了】，比如今天的把明天的预定给签到了
    * 直接到现场的客人怎么处理的
    
* 商品购买
    * 添加商品：同一种商品【分类、附加也是一样的】，重复添加是不是会报错
    * 商品购物车添加看下逻辑有没有错
    * 商品下架，前端下单会不会报错
    * 购物车 - 座位扫码 - 支付【扣款是不是包含了预定座位的钱：大于、小于、等于】 - 菜单打印 - 上桌
    * 购物车 - 座位扫码 - 支付 - 菜单打印 - 未上桌 - 退订【部分退订】
    * 购物车 - 座位扫码 - 支付 - 菜单打印 - 上桌 - 退订【部分退订】
