6.用戶模塊
用戶模塊api
import request from '@/utils/request'
export function login(data) {
return request({
url: '/sys-user/login',
method: 'post',
data
})
}export function getInfo(token) {
return request({
url: '/sys-user/queryUserInfo',
method: 'get',
params: { token }
})
}
// 退出登錄
export const logout = () => request({ url: '/sys-user/logout', method: 'post' })// 獲取用戶列表
export const queryList = (param) => request({ url: '/sys-user/queryList', params: param, method: 'post' })// 修改或更新用戶
export const updateOrSave = (param) => request({ url: '/sys-user/updateOrSave', params: param, method: 'post' })// 修改或更新用戶
export const deleteUser = (id) => request({ url: `/sys-user/delete?id=${id}`, method: 'post' })
用戶模塊代碼
<template> <div> <span> 更新時間: <el-date-picker v-model="time" type="daterange" range-separator="至" start-placeholder="開始" end-placeholder="結束" size="default" /> </span> <span v-for="(item, index) in infoArray" :key="index"> {{ item.label }}: <el-select v-model="queryParam[item.value]" class="m-2" placeholder="請選擇"> <el-option v-for="item in infolist[item.value]" :key="item.value" :label="item.text" :value="item.value" /> </el-select> </span> <el-button type="primary" @click="queryList()">查詢</el-button> <el-button type="primary" @click="showDialog()">新增</el-button> <el-table :data="tableData" border style="width: 100%"> <template v-for="(item, index) in columnList"> <el-table-column :key="index" :prop="item.field" :label="item.title" :width="item.width"> <template slot-scope="scope"> <span> {{ scope.row[item.field] | qxSelffilter(item.value) }}</span> </template> </el-table-column> </template> <el-table-column label="操作"> <template slot-scope="{row,$index}"> <el-button type="primary" @click="updateShowDialog(row)"> 修改 </el-button> <el-button type="danger" @click="deleteUser(row)"> 刪除 </el-button> </template> </el-table-column> </el-table> <el-pagination style="margin-top: 20px; text-align: center" :current-page="queryParam.currentPage" :page-size="queryParam.pageSize" :page-sizes="[3, 5, 10, 20]" :total="total" :pager-count="5" layout=" prev, pager, next , total,sizes" @size-change="handleSizeChange" @current-change="goPage" /> <!-- 彈框 :visible.sync:控制對話框顯示與隱藏用的 Form 組件提供了表單驗證的功能,只需要通過 rules 屬性傳入約定的驗證規則,並將 Form-Item 的 prop 屬性設置爲需校驗的字段名即可 --> <el-dialog :visible.sync="dialogFormVisible" :title="dialogName"> <el-form ref="ruleForm" :model="form" :rules="rules"> <el-form-item label="賬號" prop="userName"> <el-input v-model="form.userName" autocomplete="off" /> </el-form-item> <el-form-item label="密碼" prop="password"> <el-input v-model="form.password" autocomplete="off" /> </el-form-item> <!-- 下拉選項 item: { label: "用戶狀態", value: "status", enumType: "status" }, obj: {"enumType":"status","value":"0","text":"啓用"} --> <span v-for="(item, index) in infoArray" :key="index"> <el-form-item :label="item.label" :prop="item.value"> <el-select v-model="form[item.value]" class="m-2" placeholder="請選擇"> <el-option v-for="obj in infolist[item.value]" :key="obj.value" :label="obj.text" :value="item.String ? obj.value : Number(obj.value)" /> </el-select> </el-form-item> </span> </el-form> <template #footer> <span class="dialog-footer"> <el-button @click="dialogFormVisible = false">取消</el-button> <el-button type="primary" @click="submitForm"> 確定 </el-button> </span> </template> </el-dialog> </div> </template> <script> import { EnumUtility } from '@/utils/EnumUtility' import * as DateUtil from '@/utils/DateUtil' export default { name: 'UserInfo', data() { const _startTime = DateUtil.ToString( DateUtil.AddDays(new Date(), -7), 'yyyy-MM-dd' ) const _endTime = DateUtil.ToString(new Date(), 'yyyy-MM-dd') // 自定義校驗規則 var validateUserName = (rule, value, callback) => { // 自定義校驗規則 if (value.length < 6 || value.length > 10) { callback(new Error('登錄賬號6-10位')) } else { callback() } } return { // 時間選擇器 time: [_startTime, _endTime], // 下拉選擇屬性 infoArray: [ /* * label:下拉選項的標題,如:用戶狀態 * value: 選擇值列表 與 傳到 服務端的字段: 如:status=30 * enumType:從字典=>枚舉 中的下拉選項映射值 , 枚舉值賦值是在創建vue對象後,即方法中實現的 */ { label: '用戶狀態', value: 'status', enumType: 'status' }, { label: '用戶類型', value: 'type', enumType: 'user_type' } ], // 下拉選項值 /* 枚舉中完成賦值的status,type*/ infolist: {}, // 列表查詢參數 queryParam: { currentPage: 1, pageSize: 10, startTime: _startTime, endTime: DateUtil.ToString( DateUtil.AddDays(_endTime, +1), 'yyyy-MM-dd' ) }, // 列表數據 tableData: [], total: 0, // 列字段 columnList: [ { title: '編號', field: 'id' }, { title: '賬號', field: 'userName' }, { title: '類型', field: 'type', value: { enum: 'user_type' }}, { title: '狀態', field: 'status', value: { enum: 'status' }}, { title: '備註', field: 'remark' }, { title: '更新時間', field: 'updateTime', value: { date: 'MM-dd hh:mm:ss' } }, { title: '創建時間', field: 'createTime', value: { date: 'MM-dd hh:mm:ss' } } ], dialogFormVisible: false, // 是否顯示彈框 dialogName: '', // 彈框標題 如:新增用戶 或 修改 用戶 form: { // 新增 或 修改表單數據 }, rules: { // 品牌名稱的驗證規則 // require:必須要校驗字段(前面五角星有關係) message 提示信息 trigger:用戶行爲設置(事件的設置:blur、change) // tmName 對應表單上的prop的名稱必須一致 <el-form-item label="品牌名稱" :label-width="formLabelWidth" prop="tmName"> userName: [ { required: true, message: '必須輸入登錄賬號', trigger: 'blur' }, // { min: 3, max: 5, message: '長度在 3 到 5 個字符', trigger: 'blur' }, // 自定義校驗規則 { validator: validateUserName, trigger: 'change' } ], password: [{ required: true, message: '請輸入密碼' }], status: [{ required: true, message: '請選擇狀態' }], type: [{ required: true, message: '請選擇類型' }] } } }, watch: { time(val) { if (!val) { // 參數爲空時清空數據 this.queryParam.startTime = '' this.queryParam.endTime = '' } if (val && val.length > 0) { this.queryParam.startTime = DateUtil.ToString(val[0], 'yyyy-MM-dd') this.queryParam.endTime = DateUtil.ToString( DateUtil.AddDays(val[1], +1), 'yyyy-MM-dd' ) } } }, mounted() { // this.queryList() }, created() { // 給枚舉賦值 const enumUtility = new EnumUtility() this.infoArray.forEach((element) => { if (element.enumType) { // 枚舉數據結構 [{"enumType":"status","value":"0","text":"啓用"},{"enumType":"status","value":"1","text":"禁用"}] console.log('element.enumType=', element.enumType) console.log('enumUtility.Get(element.enumType)', enumUtility.Get(element.enumType)) this.infolist[element.value] = enumUtility.Get(element.enumType) } }) }, methods: { async queryList() { const result = await this.$api.user.queryList(this.queryParam) if (result.code == '100') { this.tableData = result.data.list this.total = result.data.total } }, goPage(currentPage) { this.queryParam.currentPage = currentPage this.queryList() }, handleSizeChange(pageSize) { this.queryParam.pageSize = pageSize this.queryParam.currentPage = 1 this.queryList() }, showDialog() { // console.log('顯示彈框') this.dialogName = '添加用戶' this.form = {} this.dialogFormVisible = true }, updateShowDialog(row) { this.dialogName = '修改用戶' this.form = { ...row } // 顯示對話框 this.dialogFormVisible = true }, submitForm() { // 當全部驗證字段通過,再去書寫業務邏輯 this.$refs.ruleForm.validate(async(success) => { if (success) { const result = await this.$api.user.updateOrSave(this.form) if (result.code == '100') { // 關閉窗口 this.dialogFormVisible = false // 查詢數據 this.queryList() } } else { console.log('檢查提交參數') return false } }) }, deleteUser(row) { // 彈框 this.$confirm(`你確定刪除:${row.userName}?`, '提示', { confirmButtonText: '確定', cancelButtonText: '取消', type: 'warning' }) .then(async() => { // 當用戶點擊確定按鈕的時候會出發 // 向服務器發請求 const result = await this.$api.user.deleteUser(row.id) // 如果刪除成功 if (result.code == '100') { this.$message({ type: 'success', message: '刪除成功!' }) // 再次獲取品牌列表數據 this.queryList() } }) .catch(() => { // 當用戶點擊取消按鈕的時候會觸發 this.$message({ type: 'info', message: '已取消刪除' }) }) } } } </script> <style lang="scss"></style>
管道過濾器配置
// 全局過濾器要放在Vue實例化代碼前面,不然會報錯
// eslint-disable-next-line no-unused-vars
import qxfilter from '@/utils/filter/filter'
引入時間格式依賴
"moment": "^2.29.1"
頁面顯示
7.字典模塊
編輯彈框
<template> <el-dialog :title="ruleForm.dialogName" :visible.sync="showEdit" :close-on-click-modal="false" width="550px" center @close="close" > <el-form ref="ruleForm" :model="ruleForm" :rules="rules" label-width="100px" class="flex flex_center" > <el-form-item v-for="item in ruleList" :key="item.title" :label="item.title" :prop="item.field" > <el-input v-if="!item.option" v-model="ruleForm[item.field]" :type="item.type" clearable :disabled="item.field == 'enumType' && ruleForm.id" placeholder="請輸入" /> <el-select v-else v-model="ruleForm[item.field]" filterable placeholder="請選擇" > <el-option v-for="(it, Index) in infolist[item.option]" :key="Index" :label="it.text" :value="Number(it.value)" /> </el-select> </el-form-item> </el-form> <span slot="footer" class="dialog-footer"> <el-button type="primary" @click="submitForm('ruleForm')">提交</el-button> <el-button type="danger" @click="close()">取消</el-button> </span> </el-dialog> </template> <script> export default { props: { showEdit: Boolean, infolist: Object, ruleForm: Object }, data() { return { ruleList: [ { title: '字典類型', field: 'enumType' }, { title: '字典值', field: 'value' }, { title: '顯示名稱', field: 'text' }, { title: '排序編號', field: 'shortNo', type: 'number' }, { title: '狀態', field: 'status', option: 'status' } ], rules: {} } }, computed: {}, watch: { ruleForm(val) { // 監聽變化的值,及時校驗輸入看數據 if (!this.ruleForm.id && this.$refs['ruleForm']) { this.resetForm('ruleForm') } } }, created() { this.ruleList.forEach((element) => { this.rules[element.field] = [ { required: true, message: `${element.title}不能爲空` } ] }) }, mounted() {}, methods: { submitForm(formName) { this.$refs[formName].validate((valid) => { // valid 表示輸入框的校驗結果,校驗通過返回true if (valid) { this.saveOrUpdateDic() } else { return false } }) }, async saveOrUpdateDic() { const result = await this.$api.dic.saveOrUpdateDic(this.ruleForm) if (result.code === '100') { // 成功消息提示 this.$message.success('添加成功') // 關閉窗口 this.close('insert') } else { if (result.message) this.$message.error(result.message) } }, resetForm(formName) { this.$refs[formName].resetFields() }, // 關閉彈框 close(val) { const data = { name: 'showEdit', isRefresh: val } // 子組件向父組件通信 this.$emit('close', data) this.resetForm('ruleForm') } } } </script> <style scoped> </style>
列表頁面
<template> <div> <span v-for="(item, index) in infoArray" :key="index"> {{ item.label }}: <el-select v-model="queryParam[item.value]" class="m-2" placeholder="請選擇" > <el-option v-for="item in infolist[item.value]" :key="item.value" :label="item.text" :value="item.value" /> </el-select> </span> <span v-for="item in infoInput" :key="item.value" class="info"> <el-input v-model="queryParam[item.value]" :placeholder="item.placeholder" > <i slot="prefix" class="el-input__icon el-icon-search" /> </el-input> </span> <el-button type="primary" @click="queryList()">查詢</el-button> <el-button type="primary" @click="showDialog()">新增</el-button> <el-table :data="tableData" border style="width: 100%"> <template v-for="(item, index) in columnList"> <el-table-column :key="index" :prop="item.field" :label="item.title" :width="item.width" > <template slot-scope="scope"> <span> {{ scope.row[item.field] | qxSelffilter(item.value) }}</span> </template> </el-table-column> </template> <el-table-column label="操作"> <template slot-scope="{ row, $index }"> <el-button type="primary" @click="updateShowDialog(row)"> 修改 </el-button> <el-button type="danger" @click="deleteUser(row)"> 刪除 </el-button> </template> </el-table-column> </el-table> <edit-model :show-edit="dialogFormVisible" :infolist="infolist" :rule-form="itemEdit" @close="CloseShow" /> </div> </template> <script> import EditModel from './model/EditModel.vue' export default { name: 'DicInfo', components: { EditModel }, data() { return { // 下拉選擇屬性 infoArray: [ /* * label:下拉選項的標題,如:用戶狀態 * value: 選擇值列表 與 傳到 服務端的字段: 如:status=30 * enumType:從字典=>枚舉 中的下拉選項映射值 , 枚舉值賦值是在創建vue對象後,即方法中實現的 */ { label: '字典狀態', value: 'status', enumType: 'status' } ], infoInput: [ /* infoInput:輸入框數據 */ { placeholder: '輸入:字典類型', value: 'enumType' }, { placeholder: '輸入:顯示名稱', value: 'text' } ], // 下拉選項值 /* 枚舉中完成賦值的status,type*/ infolist: { status: [ { enumType: 'status', value: '0', text: '啓用' }, { enumType: 'status', value: '1', text: '禁用' } ] }, // 列表查詢參數 queryParam: {}, // 列表數據 tableData: [], // 列字段 columnList: [ { title: '編號', field: 'id' }, { title: '字典類型', field: 'enumType' }, { title: '字典值', field: 'value' }, { title: '顯示名稱', field: 'text' }, { title: '排序編號', field: 'shortNo' }, { title: '狀態', field: 'status', value: { enum: 'status' }}, { title: '更新時間', field: 'updateTime', value: { date: 'MM-dd hh:mm:ss' } }, { title: '創建時間', field: 'createTime', value: { date: 'MM-dd hh:mm:ss' } } ], dialogFormVisible: false, // 是否顯示彈框 itemEdit: { dialogName: '修改字典' // 彈框標題 如:新增用戶 或 修改 用戶 }, // 編輯或修改的字段,如name, idd等 rules: { // 品牌名稱的驗證規則 // require:必須要校驗字段(前面五角星有關係) message 提示信息 trigger:用戶行爲設置(事件的設置:blur、change) // tmName 對應表單上的prop的名稱必須一致 <el-form-item label="品牌名稱" :label-width="formLabelWidth" prop="tmName"> userName: [ { required: true, message: '必須輸入登錄賬號', trigger: 'blur' } ], password: [{ required: true, message: '請輸入密碼' }], status: [{ required: true, message: '請選擇狀態' }], type: [{ required: true, message: '請選擇類型' }] } } }, watch: {}, mounted() { // this.queryList() }, created() { // 給枚舉賦值 { label: "字典狀態", value: "status", enumType: "status" }, // let enumUtility = new EnumUtility(); // this.infoArray.forEach((element) => { // if (element.enumType) { // 枚舉數據結構 [{"enumType":"status","value":"0","text":"啓用"},{"enumType":"status","value":"1","text":"禁用"}] // this.infolist[element.value] = enumUtility.Get(element.enumType); // } // }); }, methods: { async queryList() { const result = await this.$api.dic.getDicList(this.queryParam) if (result.code == '100') { this.tableData = result.data } }, goPage() { this.queryList() }, showDialog() { // console.log('顯示彈框') this.dialogFormVisible = true this.itemEdit = { enumType: '', value: '', text: '', status: '', shortNo: '', dialogName: '添加字典' } }, updateShowDialog(row) { this.itemEdit = { ...row } this.itemEdit['dialogName'] = '修改字典' // 顯示對話框 this.dialogFormVisible = true }, submitForm() { // 當全部驗證字段通過,再去書寫業務邏輯 this.$refs.ruleForm.validate(async(success) => { if (success) { const result = await this.$api.user.updateOrSave(this.form) // eslint-disable-next-line eqeqeq if (result.code == '100') { // 關閉窗口 this.dialogFormVisible = false // 查詢數據 this.queryList() } } else { console.log('檢查提交參數') return false } }) }, deleteUser(row) { // 彈框 this.$confirm(`你確定刪除字典:${row.enumType}?`, '提示', { confirmButtonText: '確定', cancelButtonText: '取消', type: 'warning' }) .then(async() => { // 當用戶點擊確定按鈕的時候會出發 // 向服務器發請求 const result = await this.$api.dic.deleteDic(row.id) // 如果刪除成功 if (result.code == '100') { this.$message({ type: 'success', message: '刪除成功!' }) // 再次獲取品牌列表數據 this.queryList() } }) .catch(() => { // 當用戶點擊取消按鈕的時候會觸發 this.$message({ type: 'info', message: '已取消刪除' }) }) }, CloseShow(data) { // console.log(data); // 關閉對話 this.dialogFormVisible = false if (data.isRefresh == 'update') { this.queryList() // 更新的情況 } if (data.isRefresh == 'insert') { this.queryList() // 新增的情況 } } } } </script> <style lang="scss"> </style>
頁面顯示
8.打包部署
打包:
將dist文件壓縮上傳到nginx配置的路徑下
如果,nginx不熟悉,可以學習我們之前專門講解的nginx課程
這裏給出nginx在Windows下的常用命令,實際開發中nginx都是部署在linux上的,但是我們自己學習一般是在windows上操作,本質上是一樣的
1.啓動
start nginx
2.停止
taskkill /f /t /im nginx.exe
# 卡券後臺管理系統 upstream couponAdminApi{ server 127.0.0.1:6001; #server 127.1.2.51:6001; # 負載均衡配置 } server { listen 6002; server_name localhost; location / { root F:\vue\kecheng\webhome\quanyi; #vue打包後的項目地址 index index.html index.htm; } location /prod-api/ { # return 500; proxy_set_header Host pro.ldp.com; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Real_IP $remote_addr; proxy_pass http://couponAdminApi/; } }
部署好後,重啓nginx,訪問
http://localhost:6002/
完美!