Commit 7f2cddcbb7c26f652d4c8c7b2cbbe684d38ee789
1 parent
5c5dc3cd
开发完成营销功能
Showing
14 changed files
with
1486 additions
and
0 deletions
src/api/mall/convenienceMenusManageApi.js
0 → 100644
| 1 | +import request from '@/utils/request' | ||
| 2 | + | ||
| 3 | +// 获取便民服务菜单列表 | ||
| 4 | +export function getConvenienceMenusList(params) { | ||
| 5 | + return new Promise((resolve, reject) => { | ||
| 6 | + request({ | ||
| 7 | + url: '/convenienceMenus/queryConvenienceMenus', | ||
| 8 | + method: 'get', | ||
| 9 | + params | ||
| 10 | + }).then(response => { | ||
| 11 | + const res = response.data | ||
| 12 | + if (res.code == 0) { | ||
| 13 | + resolve({ | ||
| 14 | + data: res.data, | ||
| 15 | + total: res.total | ||
| 16 | + }) | ||
| 17 | + } else { | ||
| 18 | + reject(new Error(res.msg || '获取便民服务菜单列表失败')) | ||
| 19 | + } | ||
| 20 | + }).catch(error => { | ||
| 21 | + reject(error) | ||
| 22 | + }) | ||
| 23 | + }) | ||
| 24 | +} | ||
| 25 | + | ||
| 26 | +// 添加便民服务菜单 | ||
| 27 | +export function addConvenienceMenus(data) { | ||
| 28 | + return new Promise((resolve, reject) => { | ||
| 29 | + request({ | ||
| 30 | + url: '/convenienceMenus/saveConvenienceMenus', | ||
| 31 | + method: 'post', | ||
| 32 | + data | ||
| 33 | + }).then(response => { | ||
| 34 | + const res = response.data | ||
| 35 | + if (res.code == 0) { | ||
| 36 | + resolve(res) | ||
| 37 | + } else { | ||
| 38 | + reject(new Error(res.msg || '添加便民服务菜单失败')) | ||
| 39 | + } | ||
| 40 | + }).catch(error => { | ||
| 41 | + reject(error) | ||
| 42 | + }) | ||
| 43 | + }) | ||
| 44 | +} | ||
| 45 | + | ||
| 46 | +// 删除便民服务菜单 | ||
| 47 | +export function deleteConvenienceMenus(data) { | ||
| 48 | + return new Promise((resolve, reject) => { | ||
| 49 | + request({ | ||
| 50 | + url: '/convenienceMenus/deleteConvenienceMenus', | ||
| 51 | + method: 'post', | ||
| 52 | + data | ||
| 53 | + }).then(response => { | ||
| 54 | + const res = response.data | ||
| 55 | + if (res.code == 0) { | ||
| 56 | + resolve(res) | ||
| 57 | + } else { | ||
| 58 | + reject(new Error(res.msg || '删除便民服务菜单失败')) | ||
| 59 | + } | ||
| 60 | + }).catch(error => { | ||
| 61 | + reject(error) | ||
| 62 | + }) | ||
| 63 | + }) | ||
| 64 | +} | ||
| 65 | + | ||
| 66 | +// 上传文件 | ||
| 67 | +export function uploadFile(data) { | ||
| 68 | + return new Promise((resolve, reject) => { | ||
| 69 | + request({ | ||
| 70 | + url: '/uploadFile', | ||
| 71 | + method: 'post', | ||
| 72 | + data, | ||
| 73 | + headers: { | ||
| 74 | + 'Content-Type': 'multipart/form-data' | ||
| 75 | + } | ||
| 76 | + }).then(response => { | ||
| 77 | + const res = response.data | ||
| 78 | + if (res.code == 0) { | ||
| 79 | + resolve(res) | ||
| 80 | + } else { | ||
| 81 | + reject(new Error(res.msg || '上传文件失败')) | ||
| 82 | + } | ||
| 83 | + }).catch(error => { | ||
| 84 | + reject(error) | ||
| 85 | + }) | ||
| 86 | + }) | ||
| 87 | +} | ||
| 0 | \ No newline at end of file | 88 | \ No newline at end of file |
src/api/mall/storeInfoManageApi.js
0 → 100644
| 1 | +import request from '@/utils/request' | ||
| 2 | + | ||
| 3 | +// 查询商户信息列表 | ||
| 4 | +export function queryStoreInfo(params) { | ||
| 5 | + return new Promise((resolve, reject) => { | ||
| 6 | + request({ | ||
| 7 | + url: '/storeInfo/queryStoreInfo', | ||
| 8 | + method: 'get', | ||
| 9 | + params | ||
| 10 | + }).then(response => { | ||
| 11 | + const res = response.data | ||
| 12 | + if (res.code === 0) { | ||
| 13 | + resolve({ | ||
| 14 | + data: res.data, | ||
| 15 | + total: res.total | ||
| 16 | + }) | ||
| 17 | + } else { | ||
| 18 | + reject(new Error(res.msg || 'Failed to query store info')) | ||
| 19 | + } | ||
| 20 | + }).catch(error => { | ||
| 21 | + reject(error) | ||
| 22 | + }) | ||
| 23 | + }) | ||
| 24 | +} | ||
| 25 | + | ||
| 26 | +// 查询便民菜单列表 | ||
| 27 | +export function queryConvenienceMenus(params) { | ||
| 28 | + return new Promise((resolve, reject) => { | ||
| 29 | + request({ | ||
| 30 | + url: '/convenienceMenus/queryConvenienceMenus', | ||
| 31 | + method: 'get', | ||
| 32 | + params | ||
| 33 | + }).then(response => { | ||
| 34 | + const res = response.data | ||
| 35 | + if (res.code === 0) { | ||
| 36 | + resolve({ | ||
| 37 | + data: res.data, | ||
| 38 | + total: res.total | ||
| 39 | + }) | ||
| 40 | + } else { | ||
| 41 | + reject(new Error(res.msg || 'Failed to query convenience menus')) | ||
| 42 | + } | ||
| 43 | + }).catch(error => { | ||
| 44 | + reject(error) | ||
| 45 | + }) | ||
| 46 | + }) | ||
| 47 | +} | ||
| 48 | + | ||
| 49 | +// 保存商户信息 | ||
| 50 | +export function saveStoreInfo(data) { | ||
| 51 | + return new Promise((resolve, reject) => { | ||
| 52 | + request({ | ||
| 53 | + url: '/storeInfo/saveStoreInfo', | ||
| 54 | + method: 'post', | ||
| 55 | + data | ||
| 56 | + }).then(response => { | ||
| 57 | + const res = response.data | ||
| 58 | + if (res.code === 0) { | ||
| 59 | + resolve(res) | ||
| 60 | + } else { | ||
| 61 | + reject(new Error(res.msg || 'Failed to save store info')) | ||
| 62 | + } | ||
| 63 | + }).catch(error => { | ||
| 64 | + reject(error) | ||
| 65 | + }) | ||
| 66 | + }) | ||
| 67 | +} | ||
| 68 | + | ||
| 69 | +// 更新商户信息 | ||
| 70 | +export function updateStoreInfo(data) { | ||
| 71 | + return new Promise((resolve, reject) => { | ||
| 72 | + request({ | ||
| 73 | + url: '/storeInfo/updateStoreInfo', | ||
| 74 | + method: 'post', | ||
| 75 | + data | ||
| 76 | + }).then(response => { | ||
| 77 | + const res = response.data | ||
| 78 | + if (res.code === 0) { | ||
| 79 | + resolve(res) | ||
| 80 | + } else { | ||
| 81 | + reject(new Error(res.msg || 'Failed to update store info')) | ||
| 82 | + } | ||
| 83 | + }).catch(error => { | ||
| 84 | + reject(error) | ||
| 85 | + }) | ||
| 86 | + }) | ||
| 87 | +} | ||
| 88 | + | ||
| 89 | +// 删除商户信息 | ||
| 90 | +export function deleteStoreInfo(data) { | ||
| 91 | + return new Promise((resolve, reject) => { | ||
| 92 | + request({ | ||
| 93 | + url: '/storeInfo/deleteStoreInfo', | ||
| 94 | + method: 'post', | ||
| 95 | + data | ||
| 96 | + }).then(response => { | ||
| 97 | + const res = response.data | ||
| 98 | + if (res.code === 0) { | ||
| 99 | + resolve(res) | ||
| 100 | + } else { | ||
| 101 | + reject(new Error(res.msg || 'Failed to delete store info')) | ||
| 102 | + } | ||
| 103 | + }).catch(error => { | ||
| 104 | + reject(error) | ||
| 105 | + }) | ||
| 106 | + }) | ||
| 107 | +} | ||
| 108 | + | ||
| 109 | +// 上传文件 | ||
| 110 | +export function uploadFile(data) { | ||
| 111 | + return new Promise((resolve, reject) => { | ||
| 112 | + request({ | ||
| 113 | + url: '/uploadFile', | ||
| 114 | + method: 'post', | ||
| 115 | + data, | ||
| 116 | + headers: { | ||
| 117 | + 'Content-Type': 'multipart/form-data' | ||
| 118 | + } | ||
| 119 | + }).then(response => { | ||
| 120 | + const res = response.data | ||
| 121 | + if (res.code === 0) { | ||
| 122 | + resolve(res) | ||
| 123 | + } else { | ||
| 124 | + reject(new Error(res.msg || 'Failed to upload file')) | ||
| 125 | + } | ||
| 126 | + }).catch(error => { | ||
| 127 | + reject(error) | ||
| 128 | + }) | ||
| 129 | + }) | ||
| 130 | +} | ||
| 0 | \ No newline at end of file | 131 | \ No newline at end of file |
src/components/mall/AddConvenienceMenus.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <el-dialog :title="$t('convenienceMenus.addTitle')" :visible.sync="visible" width="50%" @close="handleClose"> | ||
| 3 | + <el-form ref="form" :model="form" :rules="rules" label-width="120px"> | ||
| 4 | + <el-form-item :label="$t('convenienceMenus.menuName')" prop="name"> | ||
| 5 | + <el-input v-model="form.name" :placeholder="$t('convenienceMenus.menuNamePlaceholder')" /> | ||
| 6 | + </el-form-item> | ||
| 7 | + <el-form-item :label="$t('convenienceMenus.imageUrl')" prop="icon"> | ||
| 8 | + <upload-image-url ref="uploadImage" @uploadCoverImage="handleImageChange" /> | ||
| 9 | + </el-form-item> | ||
| 10 | + <el-form-item :label="$t('convenienceMenus.pagePath')" prop="url"> | ||
| 11 | + <el-input v-model="form.url" :placeholder="$t('convenienceMenus.pagePathPlaceholder')" /> | ||
| 12 | + </el-form-item> | ||
| 13 | + <el-form-item :label="$t('convenienceMenus.displayOrder')" prop="seq"> | ||
| 14 | + <el-input-number v-model="form.seq" :min="1" /> | ||
| 15 | + </el-form-item> | ||
| 16 | + <el-form-item :label="$t('convenienceMenus.remark')" prop="remark"> | ||
| 17 | + <el-input v-model="form.remark" type="textarea" :rows="3" /> | ||
| 18 | + </el-form-item> | ||
| 19 | + </el-form> | ||
| 20 | + | ||
| 21 | + <span slot="footer" class="dialog-footer"> | ||
| 22 | + <el-button @click="visible = false">{{ $t('common.cancel') }}</el-button> | ||
| 23 | + <el-button type="primary" @click="handleSubmit">{{ $t('common.confirm') }}</el-button> | ||
| 24 | + </span> | ||
| 25 | + </el-dialog> | ||
| 26 | +</template> | ||
| 27 | + | ||
| 28 | +<script> | ||
| 29 | +import { addConvenienceMenus } from '@/api/mall/convenienceMenusManageApi' | ||
| 30 | +import UploadImageUrl from '@/components/upload/UploadImageUrl' | ||
| 31 | + | ||
| 32 | +export default { | ||
| 33 | + name: 'AddConvenienceMenus', | ||
| 34 | + components: { | ||
| 35 | + UploadImageUrl | ||
| 36 | + }, | ||
| 37 | + data() { | ||
| 38 | + return { | ||
| 39 | + visible: false, | ||
| 40 | + form: { | ||
| 41 | + name: '', | ||
| 42 | + icon: '', | ||
| 43 | + url: '', | ||
| 44 | + seq: 1, | ||
| 45 | + remark: '' | ||
| 46 | + }, | ||
| 47 | + rules: { | ||
| 48 | + name: [ | ||
| 49 | + { required: true, message: this.$t('convenienceMenus.menuNameRequired'), trigger: 'blur' }, | ||
| 50 | + { max: 50, message: this.$t('convenienceMenus.menuNameMaxLength'), trigger: 'blur' } | ||
| 51 | + ], | ||
| 52 | + url: [ | ||
| 53 | + { max: 100, message: this.$t('convenienceMenus.pagePathMaxLength'), trigger: 'blur' } | ||
| 54 | + ], | ||
| 55 | + seq: [ | ||
| 56 | + { required: true, message: this.$t('convenienceMenus.displayOrderRequired'), trigger: 'blur' } | ||
| 57 | + ], | ||
| 58 | + remark: [ | ||
| 59 | + { max: 200, message: this.$t('convenienceMenus.remarkMaxLength'), trigger: 'blur' } | ||
| 60 | + ] | ||
| 61 | + } | ||
| 62 | + } | ||
| 63 | + }, | ||
| 64 | + methods: { | ||
| 65 | + open() { | ||
| 66 | + this.visible = true | ||
| 67 | + }, | ||
| 68 | + handleClose() { | ||
| 69 | + this.$refs.form.resetFields() | ||
| 70 | + this.$refs.uploadImage.clear() | ||
| 71 | + }, | ||
| 72 | + handleImageChange(url) { | ||
| 73 | + this.form.icon = url | ||
| 74 | + }, | ||
| 75 | + async handleSubmit() { | ||
| 76 | + this.$refs.form.validate(async valid => { | ||
| 77 | + if (valid) { | ||
| 78 | + try { | ||
| 79 | + await addConvenienceMenus(this.form) | ||
| 80 | + this.$message.success(this.$t('common.addSuccess')) | ||
| 81 | + this.visible = false | ||
| 82 | + this.$emit('success') | ||
| 83 | + } catch (error) { | ||
| 84 | + this.$message.error(error.message) | ||
| 85 | + } | ||
| 86 | + } | ||
| 87 | + }) | ||
| 88 | + } | ||
| 89 | + } | ||
| 90 | +} | ||
| 91 | +</script> | ||
| 0 | \ No newline at end of file | 92 | \ No newline at end of file |
src/components/mall/AddStoreInfo.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <el-dialog | ||
| 3 | + :title="$t('storeInfoManage.common.add')" | ||
| 4 | + :visible.sync="visible" | ||
| 5 | + width="50%" | ||
| 6 | + @close="handleClose" | ||
| 7 | + > | ||
| 8 | + <el-form ref="form" :model="form" :rules="rules" label-width="120px"> | ||
| 9 | + <el-form-item | ||
| 10 | + :label="$t('storeInfoManage.table.storeName')" | ||
| 11 | + prop="name" | ||
| 12 | + > | ||
| 13 | + <el-input | ||
| 14 | + v-model="form.name" | ||
| 15 | + :placeholder="$t('storeInfoManage.search.storeName')" | ||
| 16 | + /> | ||
| 17 | + </el-form-item> | ||
| 18 | + <el-form-item | ||
| 19 | + :label="$t('storeInfoManage.table.convenienceType')" | ||
| 20 | + prop="convenienceMenusId" | ||
| 21 | + > | ||
| 22 | + <el-select | ||
| 23 | + v-model="form.convenienceMenusId" | ||
| 24 | + :placeholder="$t('storeInfoManage.search.convenienceType')" | ||
| 25 | + style="width: 100%" | ||
| 26 | + > | ||
| 27 | + <el-option | ||
| 28 | + v-for="item in menuInfos" | ||
| 29 | + :key="item.convenienceMenusId" | ||
| 30 | + :label="item.name" | ||
| 31 | + :value="item.convenienceMenusId" | ||
| 32 | + /> | ||
| 33 | + </el-select> | ||
| 34 | + </el-form-item> | ||
| 35 | + <el-form-item | ||
| 36 | + :label="$t('storeInfoManage.table.isShow')" | ||
| 37 | + prop="isShow" | ||
| 38 | + > | ||
| 39 | + <el-select | ||
| 40 | + v-model="form.isShow" | ||
| 41 | + :placeholder="$t('storeInfoManage.search.isShow')" | ||
| 42 | + style="width: 100%" | ||
| 43 | + > | ||
| 44 | + <el-option | ||
| 45 | + :label="$t('storeInfoManage.common.yes')" | ||
| 46 | + value="Y" | ||
| 47 | + /> | ||
| 48 | + <el-option | ||
| 49 | + :label="$t('storeInfoManage.common.no')" | ||
| 50 | + value="N" | ||
| 51 | + /> | ||
| 52 | + </el-select> | ||
| 53 | + </el-form-item> | ||
| 54 | + <el-form-item | ||
| 55 | + :label="$t('storeInfoManage.table.icon')" | ||
| 56 | + prop="icon" | ||
| 57 | + > | ||
| 58 | + <upload-image | ||
| 59 | + ref="uploadImage" | ||
| 60 | + :image-count="1" | ||
| 61 | + @change="handleImageChange" | ||
| 62 | + /> | ||
| 63 | + </el-form-item> | ||
| 64 | + <el-form-item | ||
| 65 | + :label="$t('storeInfoManage.table.tel')" | ||
| 66 | + prop="tel" | ||
| 67 | + > | ||
| 68 | + <el-input | ||
| 69 | + v-model="form.tel" | ||
| 70 | + :placeholder="$t('storeInfoManage.search.storeName')" | ||
| 71 | + /> | ||
| 72 | + </el-form-item> | ||
| 73 | + <el-form-item | ||
| 74 | + :label="$t('storeInfoManage.table.site')" | ||
| 75 | + prop="site" | ||
| 76 | + > | ||
| 77 | + <el-input | ||
| 78 | + v-model="form.site" | ||
| 79 | + :placeholder="$t('storeInfoManage.search.storeName')" | ||
| 80 | + /> | ||
| 81 | + </el-form-item> | ||
| 82 | + <el-form-item | ||
| 83 | + :label="$t('storeInfoManage.table.seq')" | ||
| 84 | + prop="seq" | ||
| 85 | + > | ||
| 86 | + <el-input | ||
| 87 | + v-model="form.seq" | ||
| 88 | + :placeholder="$t('storeInfoManage.search.storeName')" | ||
| 89 | + /> | ||
| 90 | + </el-form-item> | ||
| 91 | + <el-form-item | ||
| 92 | + :label="$t('storeInfoManage.table.workTime')" | ||
| 93 | + prop="workTime" | ||
| 94 | + > | ||
| 95 | + <el-input | ||
| 96 | + v-model="form.workTime" | ||
| 97 | + :placeholder="$t('storeInfoManage.search.storeName')" | ||
| 98 | + /> | ||
| 99 | + </el-form-item> | ||
| 100 | + <el-form-item | ||
| 101 | + :label="$t('storeInfoManage.table.remark')" | ||
| 102 | + prop="remark" | ||
| 103 | + > | ||
| 104 | + <el-input | ||
| 105 | + v-model="form.remark" | ||
| 106 | + type="textarea" | ||
| 107 | + :rows="4" | ||
| 108 | + :placeholder="$t('storeInfoManage.search.storeName')" | ||
| 109 | + /> | ||
| 110 | + </el-form-item> | ||
| 111 | + </el-form> | ||
| 112 | + <span slot="footer" class="dialog-footer"> | ||
| 113 | + <el-button @click="handleClose"> | ||
| 114 | + {{ $t('storeInfoManage.common.cancel') }} | ||
| 115 | + </el-button> | ||
| 116 | + <el-button type="primary" @click="handleSubmit"> | ||
| 117 | + {{ $t('storeInfoManage.common.save') }} | ||
| 118 | + </el-button> | ||
| 119 | + </span> | ||
| 120 | + </el-dialog> | ||
| 121 | +</template> | ||
| 122 | + | ||
| 123 | +<script> | ||
| 124 | +import { saveStoreInfo } from '@/api/mall/storeInfoManageApi' | ||
| 125 | +import UploadImage from '@/components/mall/UploadImage' | ||
| 126 | + | ||
| 127 | +export default { | ||
| 128 | + name: 'AddStoreInfo', | ||
| 129 | + components: { | ||
| 130 | + UploadImage | ||
| 131 | + }, | ||
| 132 | + props: { | ||
| 133 | + menuInfos: { | ||
| 134 | + type: Array, | ||
| 135 | + default: () => [] | ||
| 136 | + } | ||
| 137 | + }, | ||
| 138 | + data() { | ||
| 139 | + return { | ||
| 140 | + visible: false, | ||
| 141 | + form: { | ||
| 142 | + name: '', | ||
| 143 | + convenienceMenusId: '', | ||
| 144 | + isShow: '', | ||
| 145 | + icon: '', | ||
| 146 | + tel: '', | ||
| 147 | + site: '', | ||
| 148 | + seq: '', | ||
| 149 | + workTime: '', | ||
| 150 | + remark: '' | ||
| 151 | + }, | ||
| 152 | + rules: { | ||
| 153 | + name: [ | ||
| 154 | + { required: true, message: this.$t('storeInfoManage.search.storeName'), trigger: 'blur' }, | ||
| 155 | + { max: 50, message: this.$t('storeInfoManage.error.maxLength50'), trigger: 'blur' } | ||
| 156 | + ], | ||
| 157 | + tel: [ | ||
| 158 | + { max: 13, message: this.$t('storeInfoManage.error.maxLength13'), trigger: 'blur' } | ||
| 159 | + ], | ||
| 160 | + site: [ | ||
| 161 | + { max: 100, message: this.$t('storeInfoManage.error.maxLength100'), trigger: 'blur' } | ||
| 162 | + ], | ||
| 163 | + seq: [ | ||
| 164 | + { required: true, message: this.$t('storeInfoManage.error.required'), trigger: 'blur' }, | ||
| 165 | + { type: 'number', message: this.$t('storeInfoManage.error.number'), trigger: 'blur' } | ||
| 166 | + ], | ||
| 167 | + workTime: [ | ||
| 168 | + { max: 200, message: this.$t('storeInfoManage.error.maxLength200'), trigger: 'blur' } | ||
| 169 | + ], | ||
| 170 | + remark: [ | ||
| 171 | + { max: 5000, message: this.$t('storeInfoManage.error.maxLength5000'), trigger: 'blur' } | ||
| 172 | + ] | ||
| 173 | + } | ||
| 174 | + } | ||
| 175 | + }, | ||
| 176 | + methods: { | ||
| 177 | + open() { | ||
| 178 | + this.visible = true | ||
| 179 | + this.$nextTick(() => { | ||
| 180 | + this.$refs.form && this.$refs.form.resetFields() | ||
| 181 | + this.$refs.uploadImage && this.$refs.uploadImage.clear() | ||
| 182 | + }) | ||
| 183 | + }, | ||
| 184 | + handleClose() { | ||
| 185 | + this.visible = false | ||
| 186 | + this.$emit('close') | ||
| 187 | + }, | ||
| 188 | + handleImageChange(images) { | ||
| 189 | + this.form.icon = images.length > 0 ? images[0] : '' | ||
| 190 | + }, | ||
| 191 | + async handleSubmit() { | ||
| 192 | + try { | ||
| 193 | + await this.$refs.form.validate() | ||
| 194 | + const formData = { ...this.form } | ||
| 195 | + if (formData.seq) { | ||
| 196 | + formData.seq = Number(formData.seq) | ||
| 197 | + } | ||
| 198 | + | ||
| 199 | + await saveStoreInfo(formData) | ||
| 200 | + this.$message.success(this.$t('storeInfoManage.common.saveSuccess')) | ||
| 201 | + this.$emit('success') | ||
| 202 | + this.handleClose() | ||
| 203 | + } catch (error) { | ||
| 204 | + if (error !== 'validate') { | ||
| 205 | + this.$message.error(error.message || this.$t('storeInfoManage.error.saveFailed')) | ||
| 206 | + } | ||
| 207 | + } | ||
| 208 | + } | ||
| 209 | + } | ||
| 210 | +} | ||
| 211 | +</script> | ||
| 0 | \ No newline at end of file | 212 | \ No newline at end of file |
src/components/mall/DeleteConvenienceMenus.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <el-dialog :title="$t('common.deleteConfirm')" :visible.sync="visible" width="30%" @close="handleClose"> | ||
| 3 | + <p>{{ $t('convenienceMenus.deleteConfirm') }}</p> | ||
| 4 | + <span slot="footer" class="dialog-footer"> | ||
| 5 | + <el-button @click="visible = false">{{ $t('common.cancel') }}</el-button> | ||
| 6 | + <el-button type="primary" @click="handleConfirm">{{ $t('common.confirm') }}</el-button> | ||
| 7 | + </span> | ||
| 8 | + </el-dialog> | ||
| 9 | +</template> | ||
| 10 | + | ||
| 11 | +<script> | ||
| 12 | +import { deleteConvenienceMenus } from '@/api/mall/convenienceMenusManageApi' | ||
| 13 | + | ||
| 14 | +export default { | ||
| 15 | + name: 'DeleteConvenienceMenus', | ||
| 16 | + data() { | ||
| 17 | + return { | ||
| 18 | + visible: false, | ||
| 19 | + convenienceMenusId: '' | ||
| 20 | + } | ||
| 21 | + }, | ||
| 22 | + methods: { | ||
| 23 | + open(row) { | ||
| 24 | + this.convenienceMenusId = row.convenienceMenusId | ||
| 25 | + this.visible = true | ||
| 26 | + }, | ||
| 27 | + handleClose() { | ||
| 28 | + this.convenienceMenusId = '' | ||
| 29 | + }, | ||
| 30 | + async handleConfirm() { | ||
| 31 | + try { | ||
| 32 | + await deleteConvenienceMenus({ convenienceMenusId: this.convenienceMenusId }) | ||
| 33 | + this.$message.success(this.$t('common.deleteSuccess')) | ||
| 34 | + this.visible = false | ||
| 35 | + this.$emit('success') | ||
| 36 | + } catch (error) { | ||
| 37 | + this.$message.error(error.message) | ||
| 38 | + } | ||
| 39 | + } | ||
| 40 | + } | ||
| 41 | +} | ||
| 42 | +</script> | ||
| 0 | \ No newline at end of file | 43 | \ No newline at end of file |
src/components/mall/DeleteStoreInfo.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <el-dialog | ||
| 3 | + :title="$t('storeInfoManage.common.confirm')" | ||
| 4 | + :visible.sync="visible" | ||
| 5 | + width="30%" | ||
| 6 | + > | ||
| 7 | + <div> | ||
| 8 | + {{ $t('storeInfoManage.delete.confirmDelete') }} {{ storeInfo.name }}? | ||
| 9 | + </div> | ||
| 10 | + <span slot="footer" class="dialog-footer"> | ||
| 11 | + <el-button @click="visible = false"> | ||
| 12 | + {{ $t('storeInfoManage.common.cancel') }} | ||
| 13 | + </el-button> | ||
| 14 | + <el-button type="primary" @click="handleConfirm"> | ||
| 15 | + {{ $t('storeInfoManage.common.confirm') }} | ||
| 16 | + </el-button> | ||
| 17 | + </span> | ||
| 18 | + </el-dialog> | ||
| 19 | +</template> | ||
| 20 | + | ||
| 21 | +<script> | ||
| 22 | +import { deleteStoreInfo } from '@/api/mall/storeInfoManageApi' | ||
| 23 | + | ||
| 24 | +export default { | ||
| 25 | + name: 'DeleteStoreInfo', | ||
| 26 | + props: { | ||
| 27 | + storeInfo: { | ||
| 28 | + type: Object, | ||
| 29 | + default: () => ({}) | ||
| 30 | + } | ||
| 31 | + }, | ||
| 32 | + data() { | ||
| 33 | + return { | ||
| 34 | + visible: false | ||
| 35 | + } | ||
| 36 | + }, | ||
| 37 | + methods: { | ||
| 38 | + open() { | ||
| 39 | + this.visible = true | ||
| 40 | + }, | ||
| 41 | + async handleConfirm() { | ||
| 42 | + try { | ||
| 43 | + await deleteStoreInfo({ storeInfoId: this.storeInfo.storeInfoId }) | ||
| 44 | + this.$message.success(this.$t('storeInfoManage.common.deleteSuccess')) | ||
| 45 | + this.visible = false | ||
| 46 | + this.$emit('success') | ||
| 47 | + } catch (error) { | ||
| 48 | + this.$message.error(error.message || this.$t('storeInfoManage.error.deleteFailed')) | ||
| 49 | + } | ||
| 50 | + } | ||
| 51 | + } | ||
| 52 | +} | ||
| 53 | +</script> | ||
| 0 | \ No newline at end of file | 54 | \ No newline at end of file |
src/components/mall/EditStoreInfo.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <el-dialog | ||
| 3 | + :title="$t('storeInfoManage.common.edit')" | ||
| 4 | + :visible.sync="visible" | ||
| 5 | + width="50%" | ||
| 6 | + @close="handleClose" | ||
| 7 | + > | ||
| 8 | + <el-form ref="form" :model="form" :rules="rules" label-width="120px"> | ||
| 9 | + <el-form-item | ||
| 10 | + :label="$t('storeInfoManage.table.storeName')" | ||
| 11 | + prop="name" | ||
| 12 | + > | ||
| 13 | + <el-input | ||
| 14 | + v-model="form.name" | ||
| 15 | + :placeholder="$t('storeInfoManage.search.storeName')" | ||
| 16 | + /> | ||
| 17 | + </el-form-item> | ||
| 18 | + <el-form-item | ||
| 19 | + :label="$t('storeInfoManage.table.convenienceType')" | ||
| 20 | + prop="convenienceMenusId" | ||
| 21 | + > | ||
| 22 | + <el-select | ||
| 23 | + v-model="form.convenienceMenusId" | ||
| 24 | + :placeholder="$t('storeInfoManage.search.convenienceType')" | ||
| 25 | + style="width: 100%" | ||
| 26 | + > | ||
| 27 | + <el-option | ||
| 28 | + v-for="item in menuInfos" | ||
| 29 | + :key="item.convenienceMenusId" | ||
| 30 | + :label="item.name" | ||
| 31 | + :value="item.convenienceMenusId" | ||
| 32 | + /> | ||
| 33 | + </el-select> | ||
| 34 | + </el-form-item> | ||
| 35 | + <el-form-item | ||
| 36 | + :label="$t('storeInfoManage.table.isShow')" | ||
| 37 | + prop="isShow" | ||
| 38 | + > | ||
| 39 | + <el-select | ||
| 40 | + v-model="form.isShow" | ||
| 41 | + :placeholder="$t('storeInfoManage.search.isShow')" | ||
| 42 | + style="width: 100%" | ||
| 43 | + > | ||
| 44 | + <el-option | ||
| 45 | + :label="$t('storeInfoManage.common.yes')" | ||
| 46 | + value="Y" | ||
| 47 | + /> | ||
| 48 | + <el-option | ||
| 49 | + :label="$t('storeInfoManage.common.no')" | ||
| 50 | + value="N" | ||
| 51 | + /> | ||
| 52 | + </el-select> | ||
| 53 | + </el-form-item> | ||
| 54 | + <el-form-item | ||
| 55 | + :label="$t('storeInfoManage.table.icon')" | ||
| 56 | + prop="icon" | ||
| 57 | + > | ||
| 58 | + <upload-image | ||
| 59 | + ref="uploadImage" | ||
| 60 | + :image-count="1" | ||
| 61 | + :initial-images="[form.icon]" | ||
| 62 | + @change="handleImageChange" | ||
| 63 | + /> | ||
| 64 | + </el-form-item> | ||
| 65 | + <el-form-item | ||
| 66 | + :label="$t('storeInfoManage.table.tel')" | ||
| 67 | + prop="tel" | ||
| 68 | + > | ||
| 69 | + <el-input | ||
| 70 | + v-model="form.tel" | ||
| 71 | + :placeholder="$t('storeInfoManage.search.storeName')" | ||
| 72 | + /> | ||
| 73 | + </el-form-item> | ||
| 74 | + <el-form-item | ||
| 75 | + :label="$t('storeInfoManage.table.site')" | ||
| 76 | + prop="site" | ||
| 77 | + > | ||
| 78 | + <el-input | ||
| 79 | + v-model="form.site" | ||
| 80 | + :placeholder="$t('storeInfoManage.search.storeName')" | ||
| 81 | + /> | ||
| 82 | + </el-form-item> | ||
| 83 | + <el-form-item | ||
| 84 | + :label="$t('storeInfoManage.table.seq')" | ||
| 85 | + prop="seq" | ||
| 86 | + > | ||
| 87 | + <el-input | ||
| 88 | + v-model="form.seq" | ||
| 89 | + :placeholder="$t('storeInfoManage.search.storeName')" | ||
| 90 | + /> | ||
| 91 | + </el-form-item> | ||
| 92 | + <el-form-item | ||
| 93 | + :label="$t('storeInfoManage.table.workTime')" | ||
| 94 | + prop="workTime" | ||
| 95 | + > | ||
| 96 | + <el-input | ||
| 97 | + v-model="form.workTime" | ||
| 98 | + :placeholder="$t('storeInfoManage.search.storeName')" | ||
| 99 | + /> | ||
| 100 | + </el-form-item> | ||
| 101 | + <el-form-item | ||
| 102 | + :label="$t('storeInfoManage.table.remark')" | ||
| 103 | + prop="remark" | ||
| 104 | + > | ||
| 105 | + <el-input | ||
| 106 | + v-model="form.remark" | ||
| 107 | + type="textarea" | ||
| 108 | + :rows="4" | ||
| 109 | + :placeholder="$t('storeInfoManage.search.storeName')" | ||
| 110 | + /> | ||
| 111 | + </el-form-item> | ||
| 112 | + </el-form> | ||
| 113 | + <span slot="footer" class="dialog-footer"> | ||
| 114 | + <el-button @click="handleClose"> | ||
| 115 | + {{ $t('storeInfoManage.common.cancel') }} | ||
| 116 | + </el-button> | ||
| 117 | + <el-button type="primary" @click="handleSubmit"> | ||
| 118 | + {{ $t('storeInfoManage.common.save') }} | ||
| 119 | + </el-button> | ||
| 120 | + </span> | ||
| 121 | + </el-dialog> | ||
| 122 | +</template> | ||
| 123 | + | ||
| 124 | +<script> | ||
| 125 | +import { updateStoreInfo } from '@/api/mall/storeInfoManageApi' | ||
| 126 | +import UploadImage from '@/components/mall/UploadImage' | ||
| 127 | + | ||
| 128 | +export default { | ||
| 129 | + name: 'EditStoreInfo', | ||
| 130 | + components: { | ||
| 131 | + UploadImage | ||
| 132 | + }, | ||
| 133 | + props: { | ||
| 134 | + storeInfo: { | ||
| 135 | + type: Object, | ||
| 136 | + default: () => ({}) | ||
| 137 | + }, | ||
| 138 | + menuInfos: { | ||
| 139 | + type: Array, | ||
| 140 | + default: () => [] | ||
| 141 | + } | ||
| 142 | + }, | ||
| 143 | + data() { | ||
| 144 | + return { | ||
| 145 | + visible: false, | ||
| 146 | + form: { | ||
| 147 | + storeInfoId: '', | ||
| 148 | + name: '', | ||
| 149 | + convenienceMenusId: '', | ||
| 150 | + isShow: '', | ||
| 151 | + icon: '', | ||
| 152 | + tel: '', | ||
| 153 | + site: '', | ||
| 154 | + seq: '', | ||
| 155 | + workTime: '', | ||
| 156 | + remark: '' | ||
| 157 | + }, | ||
| 158 | + rules: { | ||
| 159 | + name: [ | ||
| 160 | + { required: true, message: this.$t('storeInfoManage.search.storeName'), trigger: 'blur' }, | ||
| 161 | + { max: 50, message: this.$t('storeInfoManage.error.maxLength50'), trigger: 'blur' } | ||
| 162 | + ], | ||
| 163 | + tel: [ | ||
| 164 | + { max: 13, message: this.$t('storeInfoManage.error.maxLength13'), trigger: 'blur' } | ||
| 165 | + ], | ||
| 166 | + site: [ | ||
| 167 | + { max: 100, message: this.$t('storeInfoManage.error.maxLength100'), trigger: 'blur' } | ||
| 168 | + ], | ||
| 169 | + seq: [ | ||
| 170 | + { required: true, message: this.$t('storeInfoManage.error.required'), trigger: 'blur' }, | ||
| 171 | + { type: 'number', message: this.$t('storeInfoManage.error.number'), trigger: 'blur' } | ||
| 172 | + ], | ||
| 173 | + workTime: [ | ||
| 174 | + { max: 200, message: this.$t('storeInfoManage.error.maxLength200'), trigger: 'blur' } | ||
| 175 | + ], | ||
| 176 | + remark: [ | ||
| 177 | + { max: 5000, message: this.$t('storeInfoManage.error.maxLength5000'), trigger: 'blur' } | ||
| 178 | + ], | ||
| 179 | + storeInfoId: [ | ||
| 180 | + { required: true, message: this.$t('storeInfoManage.error.required'), trigger: 'blur' } | ||
| 181 | + ] | ||
| 182 | + } | ||
| 183 | + } | ||
| 184 | + }, | ||
| 185 | + watch: { | ||
| 186 | + storeInfo: { | ||
| 187 | + immediate: true, | ||
| 188 | + handler(val) { | ||
| 189 | + if (val) { | ||
| 190 | + this.form = { ...val } | ||
| 191 | + } | ||
| 192 | + } | ||
| 193 | + } | ||
| 194 | + }, | ||
| 195 | + methods: { | ||
| 196 | + open() { | ||
| 197 | + this.visible = true | ||
| 198 | + }, | ||
| 199 | + handleClose() { | ||
| 200 | + this.visible = false | ||
| 201 | + this.$emit('close') | ||
| 202 | + }, | ||
| 203 | + handleImageChange(images) { | ||
| 204 | + this.form.icon = images.length > 0 ? images[0] : '' | ||
| 205 | + }, | ||
| 206 | + async handleSubmit() { | ||
| 207 | + try { | ||
| 208 | + await this.$refs.form.validate() | ||
| 209 | + const formData = { ...this.form } | ||
| 210 | + if (formData.seq) { | ||
| 211 | + formData.seq = Number(formData.seq) | ||
| 212 | + } | ||
| 213 | + | ||
| 214 | + await updateStoreInfo(formData) | ||
| 215 | + this.$message.success(this.$t('storeInfoManage.common.updateSuccess')) | ||
| 216 | + this.$emit('success') | ||
| 217 | + this.handleClose() | ||
| 218 | + } catch (error) { | ||
| 219 | + if (error !== 'validate') { | ||
| 220 | + this.$message.error(error.message || this.$t('storeInfoManage.error.updateFailed')) | ||
| 221 | + } | ||
| 222 | + } | ||
| 223 | + } | ||
| 224 | + } | ||
| 225 | +} | ||
| 226 | +</script> | ||
| 0 | \ No newline at end of file | 227 | \ No newline at end of file |
src/components/mall/UploadImage.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div class="upload-image-container"> | ||
| 3 | + <div v-for="(image, index) in images" :key="index" class="image-item"> | ||
| 4 | + <el-image | ||
| 5 | + :src="image" | ||
| 6 | + fit="cover" | ||
| 7 | + style="width: 100px; height: 100px;" | ||
| 8 | + :preview-src-list="[image]" | ||
| 9 | + ></el-image> | ||
| 10 | + <i class="el-icon-delete" @click="removeImage(index)"></i> | ||
| 11 | + </div> | ||
| 12 | + <el-upload | ||
| 13 | + v-if="images.length < maxCount" | ||
| 14 | + action="" | ||
| 15 | + :show-file-list="false" | ||
| 16 | + :before-upload="beforeUpload" | ||
| 17 | + :http-request="handleUpload" | ||
| 18 | + > | ||
| 19 | + <div class="upload-btn"> | ||
| 20 | + <i class="el-icon-plus"></i> | ||
| 21 | + </div> | ||
| 22 | + </el-upload> | ||
| 23 | + </div> | ||
| 24 | +</template> | ||
| 25 | + | ||
| 26 | +<script> | ||
| 27 | +import { uploadFile } from '@/api/mall/convenienceMenusManageApi' | ||
| 28 | + | ||
| 29 | +export default { | ||
| 30 | + name: 'UploadImage', | ||
| 31 | + props: { | ||
| 32 | + maxCount: { | ||
| 33 | + type: Number, | ||
| 34 | + default: 1 | ||
| 35 | + } | ||
| 36 | + }, | ||
| 37 | + data() { | ||
| 38 | + return { | ||
| 39 | + images: [] | ||
| 40 | + } | ||
| 41 | + }, | ||
| 42 | + methods: { | ||
| 43 | + beforeUpload(file) { | ||
| 44 | + const isImage = file.type.includes('image/') | ||
| 45 | + const isLt2M = file.size / 1024 / 1024 < 2 | ||
| 46 | + | ||
| 47 | + if (!isImage) { | ||
| 48 | + this.$message.error(this.$t('upload.imageTypeError')) | ||
| 49 | + } | ||
| 50 | + if (!isLt2M) { | ||
| 51 | + this.$message.error(this.$t('upload.imageSizeError')) | ||
| 52 | + } | ||
| 53 | + return isImage && isLt2M | ||
| 54 | + }, | ||
| 55 | + async handleUpload({ file }) { | ||
| 56 | + try { | ||
| 57 | + const formData = new FormData() | ||
| 58 | + formData.append('uploadFile', file) | ||
| 59 | + const { url } = await uploadFile(formData) | ||
| 60 | + this.images.push(url) | ||
| 61 | + this.$emit('change', url) | ||
| 62 | + } catch (error) { | ||
| 63 | + this.$message.error(error.message) | ||
| 64 | + } | ||
| 65 | + }, | ||
| 66 | + removeImage(index) { | ||
| 67 | + this.images.splice(index, 1) | ||
| 68 | + this.$emit('change', this.images[0] || '') | ||
| 69 | + }, | ||
| 70 | + clear() { | ||
| 71 | + this.images = [] | ||
| 72 | + this.$emit('change', '') | ||
| 73 | + } | ||
| 74 | + } | ||
| 75 | +} | ||
| 76 | +</script> | ||
| 77 | + | ||
| 78 | +<style lang="scss" scoped> | ||
| 79 | +.upload-image-container { | ||
| 80 | + display: flex; | ||
| 81 | + flex-wrap: wrap; | ||
| 82 | + gap: 10px; | ||
| 83 | + | ||
| 84 | + .image-item { | ||
| 85 | + position: relative; | ||
| 86 | + | ||
| 87 | + .el-icon-delete { | ||
| 88 | + position: absolute; | ||
| 89 | + top: 5px; | ||
| 90 | + right: 5px; | ||
| 91 | + color: #f56c6c; | ||
| 92 | + cursor: pointer; | ||
| 93 | + font-size: 16px; | ||
| 94 | + background: rgba(255, 255, 255, 0.7); | ||
| 95 | + border-radius: 50%; | ||
| 96 | + padding: 5px; | ||
| 97 | + } | ||
| 98 | + } | ||
| 99 | + | ||
| 100 | + .upload-btn { | ||
| 101 | + width: 100px; | ||
| 102 | + height: 100px; | ||
| 103 | + display: flex; | ||
| 104 | + justify-content: center; | ||
| 105 | + align-items: center; | ||
| 106 | + border: 1px dashed #d9d9d9; | ||
| 107 | + border-radius: 6px; | ||
| 108 | + cursor: pointer; | ||
| 109 | + background-color: #fbfdff; | ||
| 110 | + | ||
| 111 | + &:hover { | ||
| 112 | + border-color: #409eff; | ||
| 113 | + } | ||
| 114 | + | ||
| 115 | + i { | ||
| 116 | + font-size: 28px; | ||
| 117 | + color: #8c939d; | ||
| 118 | + } | ||
| 119 | + } | ||
| 120 | +} | ||
| 121 | +</style> | ||
| 0 | \ No newline at end of file | 122 | \ No newline at end of file |
src/i18n/index.js
| @@ -103,6 +103,8 @@ import { messages as marketRuleMessages } from '../views/market/marketRuleLang' | @@ -103,6 +103,8 @@ import { messages as marketRuleMessages } from '../views/market/marketRuleLang' | ||
| 103 | import { messages as marketBlacklistManageMessages } from '../views/market/marketBlacklistManageLang' | 103 | import { messages as marketBlacklistManageMessages } from '../views/market/marketBlacklistManageLang' |
| 104 | import { messages as marketLogMessages } from '../views/market/marketLogLang' | 104 | import { messages as marketLogMessages } from '../views/market/marketLogLang' |
| 105 | import { messages as advertManageMessages } from '../views/admin/advertManageLang' | 105 | import { messages as advertManageMessages } from '../views/admin/advertManageLang' |
| 106 | +import { messages as convenienceMenusManageMessages } from '../views/mall/convenienceMenusManageLang' | ||
| 107 | +import { messages as storeInfoManageMessages } from '../views/mall/storeInfoManageLang' | ||
| 106 | 108 | ||
| 107 | Vue.use(VueI18n) | 109 | Vue.use(VueI18n) |
| 108 | 110 | ||
| @@ -210,6 +212,8 @@ const messages = { | @@ -210,6 +212,8 @@ const messages = { | ||
| 210 | ...marketBlacklistManageMessages.en, | 212 | ...marketBlacklistManageMessages.en, |
| 211 | ...marketLogMessages.en, | 213 | ...marketLogMessages.en, |
| 212 | ...advertManageMessages.en, | 214 | ...advertManageMessages.en, |
| 215 | + ...convenienceMenusManageMessages.en, | ||
| 216 | + ...storeInfoManageMessages.en, | ||
| 213 | }, | 217 | }, |
| 214 | zh: { | 218 | zh: { |
| 215 | ...loginMessages.zh, | 219 | ...loginMessages.zh, |
| @@ -313,6 +317,8 @@ const messages = { | @@ -313,6 +317,8 @@ const messages = { | ||
| 313 | ...marketBlacklistManageMessages.zh, | 317 | ...marketBlacklistManageMessages.zh, |
| 314 | ...marketLogMessages.zh, | 318 | ...marketLogMessages.zh, |
| 315 | ...advertManageMessages.zh, | 319 | ...advertManageMessages.zh, |
| 320 | + ...convenienceMenusManageMessages.zh, | ||
| 321 | + ...storeInfoManageMessages.zh, | ||
| 316 | } | 322 | } |
| 317 | } | 323 | } |
| 318 | 324 |
src/router/index.js
| @@ -501,6 +501,16 @@ const routes = [ | @@ -501,6 +501,16 @@ const routes = [ | ||
| 501 | name: '/pages/property/advertManage', | 501 | name: '/pages/property/advertManage', |
| 502 | component: () => import('@/views/admin/advertManageList.vue') | 502 | component: () => import('@/views/admin/advertManageList.vue') |
| 503 | }, | 503 | }, |
| 504 | + { | ||
| 505 | + path:'/pages/admin/convenienceMenusManage', | ||
| 506 | + name:'/pages/admin/convenienceMenusManage', | ||
| 507 | + component: () => import('@/views/mall/convenienceMenusManageList.vue') | ||
| 508 | + }, | ||
| 509 | + { | ||
| 510 | + path:'/pages/admin/storeInfoManage', | ||
| 511 | + name:'/pages/admin/storeInfoManage', | ||
| 512 | + component: () => import('@/views/mall/storeInfoManageList.vue') | ||
| 513 | + }, | ||
| 504 | // 其他子路由可以在这里添加 | 514 | // 其他子路由可以在这里添加 |
| 505 | ] | 515 | ] |
| 506 | }, | 516 | }, |
src/views/mall/convenienceMenusManageLang.js
0 → 100644
| 1 | +export const messages = { | ||
| 2 | + en: { | ||
| 3 | + convenienceMenus: { | ||
| 4 | + title: 'Convenience Services', | ||
| 5 | + assetId: 'Asset ID', | ||
| 6 | + menuName: 'Menu Name', | ||
| 7 | + imageUrl: 'Image URL', | ||
| 8 | + pagePath: 'Page Path', | ||
| 9 | + displayOrder: 'Display Order', | ||
| 10 | + remark: 'Remark', | ||
| 11 | + fetchError: 'Failed to fetch convenience menus', | ||
| 12 | + addTitle: 'Add Convenience Menu', | ||
| 13 | + editTitle: 'Edit Convenience Menu', | ||
| 14 | + deleteConfirm: 'Are you sure to delete this convenience menu?' | ||
| 15 | + } | ||
| 16 | + }, | ||
| 17 | + zh: { | ||
| 18 | + convenienceMenus: { | ||
| 19 | + title: '便民服务', | ||
| 20 | + assetId: '资产ID', | ||
| 21 | + menuName: '菜单名称', | ||
| 22 | + imageUrl: '图片地址', | ||
| 23 | + pagePath: '页面路径', | ||
| 24 | + displayOrder: '显示序号', | ||
| 25 | + remark: '备注', | ||
| 26 | + fetchError: '获取便民服务菜单失败', | ||
| 27 | + addTitle: '添加便民服务菜单', | ||
| 28 | + editTitle: '修改便民服务菜单', | ||
| 29 | + deleteConfirm: '确定删除便民服务菜单吗?' | ||
| 30 | + } | ||
| 31 | + } | ||
| 32 | +} | ||
| 0 | \ No newline at end of file | 33 | \ No newline at end of file |
src/views/mall/convenienceMenusManageList.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div class="convenience-menus-container"> | ||
| 3 | + <el-card class="box-card"> | ||
| 4 | + <div slot="header" class="clearfix flex justify-between"> | ||
| 5 | + <span>{{ $t('convenienceMenus.title') }}</span> | ||
| 6 | + <el-button type="primary" size="small" style="float: right" @click="openAddModal"> | ||
| 7 | + <i class="el-icon-plus"></i> | ||
| 8 | + {{ $t('common.add') }} | ||
| 9 | + </el-button> | ||
| 10 | + </div> | ||
| 11 | + | ||
| 12 | + <el-table :data="tableData" border style="width: 100%"> | ||
| 13 | + <el-table-column prop="convenienceMenusId" :label="$t('convenienceMenus.assetId')" align="center" /> | ||
| 14 | + <el-table-column prop="name" :label="$t('convenienceMenus.menuName')" align="center" /> | ||
| 15 | + <el-table-column :label="$t('convenienceMenus.imageUrl')" align="center"> | ||
| 16 | + <template slot-scope="scope"> | ||
| 17 | + <el-image style="width: 60px; height: 60px; border-radius: 5px;" :src="scope.row.icon" | ||
| 18 | + :preview-src-list="[scope.row.icon]" fit="cover"></el-image> | ||
| 19 | + </template> | ||
| 20 | + </el-table-column> | ||
| 21 | + <el-table-column prop="url" :label="$t('convenienceMenus.pagePath')" align="center" /> | ||
| 22 | + <el-table-column prop="seq" :label="$t('convenienceMenus.displayOrder')" align="center" /> | ||
| 23 | + <el-table-column prop="remark" :label="$t('convenienceMenus.remark')" align="center" /> | ||
| 24 | + <el-table-column :label="$t('common.operation')" align="center" width="200"> | ||
| 25 | + <template slot-scope="scope"> | ||
| 26 | + <el-button size="mini" type="danger" @click="openDeleteModal(scope.row)"> | ||
| 27 | + {{ $t('common.delete') }} | ||
| 28 | + </el-button> | ||
| 29 | + </template> | ||
| 30 | + </el-table-column> | ||
| 31 | + </el-table> | ||
| 32 | + | ||
| 33 | + <el-pagination :current-page="pagination.current" :page-sizes="[10, 20, 30, 50]" :page-size="pagination.size" | ||
| 34 | + :total="pagination.total" layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange" | ||
| 35 | + @current-change="handleCurrentChange" /> | ||
| 36 | + </el-card> | ||
| 37 | + | ||
| 38 | + <add-convenience-menus ref="addModal" @success="fetchData" /> | ||
| 39 | + <delete-convenience-menus ref="deleteModal" @success="fetchData" /> | ||
| 40 | + </div> | ||
| 41 | +</template> | ||
| 42 | + | ||
| 43 | +<script> | ||
| 44 | +import { getConvenienceMenusList } from '@/api/mall/convenienceMenusManageApi' | ||
| 45 | +import AddConvenienceMenus from '@/components/mall/AddConvenienceMenus' | ||
| 46 | +import DeleteConvenienceMenus from '@/components/mall/DeleteConvenienceMenus' | ||
| 47 | + | ||
| 48 | +export default { | ||
| 49 | + name: 'ConvenienceMenusManageList', | ||
| 50 | + components: { | ||
| 51 | + AddConvenienceMenus, | ||
| 52 | + DeleteConvenienceMenus | ||
| 53 | + }, | ||
| 54 | + data() { | ||
| 55 | + return { | ||
| 56 | + tableData: [], | ||
| 57 | + pagination: { | ||
| 58 | + current: 1, | ||
| 59 | + size: 10, | ||
| 60 | + total: 0 | ||
| 61 | + }, | ||
| 62 | + searchForm: { | ||
| 63 | + name: '' | ||
| 64 | + } | ||
| 65 | + } | ||
| 66 | + }, | ||
| 67 | + created() { | ||
| 68 | + this.fetchData() | ||
| 69 | + }, | ||
| 70 | + methods: { | ||
| 71 | + async fetchData() { | ||
| 72 | + try { | ||
| 73 | + const params = { | ||
| 74 | + page: this.pagination.current, | ||
| 75 | + row: this.pagination.size, | ||
| 76 | + ...this.searchForm | ||
| 77 | + } | ||
| 78 | + const { data, total } = await getConvenienceMenusList(params) | ||
| 79 | + this.tableData = data | ||
| 80 | + this.pagination.total = total | ||
| 81 | + } catch (error) { | ||
| 82 | + this.$message.error(this.$t('convenienceMenus.fetchError')) | ||
| 83 | + } | ||
| 84 | + }, | ||
| 85 | + openAddModal() { | ||
| 86 | + this.$refs.addModal.open() | ||
| 87 | + }, | ||
| 88 | + openEditModal(row) { | ||
| 89 | + this.$refs.editModal.open(row) | ||
| 90 | + }, | ||
| 91 | + openDeleteModal(row) { | ||
| 92 | + this.$refs.deleteModal.open(row) | ||
| 93 | + }, | ||
| 94 | + handleSizeChange(val) { | ||
| 95 | + this.pagination.size = val | ||
| 96 | + this.fetchData() | ||
| 97 | + }, | ||
| 98 | + handleCurrentChange(val) { | ||
| 99 | + this.pagination.current = val | ||
| 100 | + this.fetchData() | ||
| 101 | + } | ||
| 102 | + } | ||
| 103 | +} | ||
| 104 | +</script> | ||
| 105 | + | ||
| 106 | +<style lang="scss" scoped> | ||
| 107 | +.convenience-menus-container { | ||
| 108 | + padding: 20px; | ||
| 109 | + | ||
| 110 | + .box-card { | ||
| 111 | + margin-bottom: 20px; | ||
| 112 | + } | ||
| 113 | + | ||
| 114 | + .el-pagination { | ||
| 115 | + margin-top: 20px; | ||
| 116 | + text-align: right; | ||
| 117 | + } | ||
| 118 | +} | ||
| 119 | +</style> | ||
| 0 | \ No newline at end of file | 120 | \ No newline at end of file |
src/views/mall/storeInfoManageLang.js
0 → 100644
| 1 | +export const messages = { | ||
| 2 | + en: { | ||
| 3 | + storeInfoManage: { | ||
| 4 | + search: { | ||
| 5 | + title: 'Search Conditions', | ||
| 6 | + storeName: 'Please enter store name', | ||
| 7 | + convenienceType: 'Please select convenience type', | ||
| 8 | + isShow: 'Please select whether to display' | ||
| 9 | + }, | ||
| 10 | + list: { | ||
| 11 | + title: 'Store Information' | ||
| 12 | + }, | ||
| 13 | + table: { | ||
| 14 | + storeInfoId: 'Store ID', | ||
| 15 | + storeName: 'Store Name', | ||
| 16 | + icon: 'Image URL', | ||
| 17 | + tel: 'Store Phone', | ||
| 18 | + site: 'Store Location', | ||
| 19 | + seq: 'Display Sequence', | ||
| 20 | + isShow: 'Is Show', | ||
| 21 | + convenienceType: 'Convenience Type', | ||
| 22 | + workTime: 'Work Time', | ||
| 23 | + remark: 'Remark' | ||
| 24 | + }, | ||
| 25 | + common: { | ||
| 26 | + search: 'Search', | ||
| 27 | + add: 'Add', | ||
| 28 | + edit: 'Edit', | ||
| 29 | + delete: 'Delete', | ||
| 30 | + yes: 'Yes', | ||
| 31 | + no: 'No', | ||
| 32 | + operation: 'Operation', | ||
| 33 | + cancel: 'Cancel', | ||
| 34 | + save: 'Save', | ||
| 35 | + confirm: 'Confirm', | ||
| 36 | + saveSuccess: 'Save successfully', | ||
| 37 | + updateSuccess: 'Update successfully', | ||
| 38 | + deleteSuccess: 'Delete successfully', | ||
| 39 | + required: 'Required', | ||
| 40 | + optional: 'Optional' | ||
| 41 | + }, | ||
| 42 | + delete: { | ||
| 43 | + confirmDelete: 'Are you sure to delete store info' | ||
| 44 | + }, | ||
| 45 | + error: { | ||
| 46 | + fetchStoreInfoFailed: 'Failed to get store information', | ||
| 47 | + fetchConvenienceMenusFailed: 'Failed to get convenience menus', | ||
| 48 | + saveFailed: 'Failed to save store info', | ||
| 49 | + updateFailed: 'Failed to update store info', | ||
| 50 | + deleteFailed: 'Failed to delete store info', | ||
| 51 | + uploadFailed: 'Failed to upload image', | ||
| 52 | + uploadImageOnly: 'Only image files can be uploaded', | ||
| 53 | + imageSizeLimit: 'Image size cannot exceed 2MB', | ||
| 54 | + maxLength50: 'Cannot exceed 50 characters', | ||
| 55 | + maxLength13: 'Cannot exceed 13 characters', | ||
| 56 | + maxLength100: 'Cannot exceed 100 characters', | ||
| 57 | + maxLength200: 'Cannot exceed 200 characters', | ||
| 58 | + maxLength5000: 'Cannot exceed 5000 characters', | ||
| 59 | + required: 'This field is required', | ||
| 60 | + number: 'Please enter a valid number' | ||
| 61 | + }, | ||
| 62 | + validation: { | ||
| 63 | + storeNameRequired: 'Store name is required', | ||
| 64 | + seqRequired: 'Display sequence is required', | ||
| 65 | + seqNumber: 'Display sequence must be a number', | ||
| 66 | + telMaxLength: 'Phone number cannot exceed 13 characters', | ||
| 67 | + siteMaxLength: 'Location cannot exceed 100 characters', | ||
| 68 | + workTimeMaxLength: 'Work time cannot exceed 200 characters', | ||
| 69 | + remarkMaxLength: 'Remark cannot exceed 5000 characters' | ||
| 70 | + } | ||
| 71 | + } | ||
| 72 | + }, | ||
| 73 | + zh: { | ||
| 74 | + storeInfoManage: { | ||
| 75 | + search: { | ||
| 76 | + title: '查询条件', | ||
| 77 | + storeName: '请输入商户名称', | ||
| 78 | + convenienceType: '请选择便民种类', | ||
| 79 | + isShow: '请选择是否显示' | ||
| 80 | + }, | ||
| 81 | + list: { | ||
| 82 | + title: '商户信息' | ||
| 83 | + }, | ||
| 84 | + table: { | ||
| 85 | + storeInfoId: '商户信息ID', | ||
| 86 | + storeName: '商户名称', | ||
| 87 | + icon: '图片地址', | ||
| 88 | + tel: '商户电话', | ||
| 89 | + site: '商户位置', | ||
| 90 | + seq: '显示序号', | ||
| 91 | + isShow: '是否显示', | ||
| 92 | + convenienceType: '便民类型', | ||
| 93 | + workTime: '工作时间', | ||
| 94 | + remark: '备注' | ||
| 95 | + }, | ||
| 96 | + common: { | ||
| 97 | + search: '查询', | ||
| 98 | + add: '添加', | ||
| 99 | + edit: '修改', | ||
| 100 | + delete: '删除', | ||
| 101 | + yes: '是', | ||
| 102 | + no: '否', | ||
| 103 | + operation: '操作', | ||
| 104 | + cancel: '取消', | ||
| 105 | + save: '保存', | ||
| 106 | + confirm: '确认', | ||
| 107 | + saveSuccess: '保存成功', | ||
| 108 | + updateSuccess: '更新成功', | ||
| 109 | + deleteSuccess: '删除成功', | ||
| 110 | + required: '必填', | ||
| 111 | + optional: '选填' | ||
| 112 | + }, | ||
| 113 | + delete: { | ||
| 114 | + confirmDelete: '确定删除商户信息' | ||
| 115 | + }, | ||
| 116 | + error: { | ||
| 117 | + fetchStoreInfoFailed: '获取商户信息失败', | ||
| 118 | + fetchConvenienceMenusFailed: '获取便民菜单失败', | ||
| 119 | + saveFailed: '保存商户信息失败', | ||
| 120 | + updateFailed: '更新商户信息失败', | ||
| 121 | + deleteFailed: '删除商户信息失败', | ||
| 122 | + uploadFailed: '上传图片失败', | ||
| 123 | + uploadImageOnly: '只能上传图片文件', | ||
| 124 | + imageSizeLimit: '图片大小不能超过2MB', | ||
| 125 | + maxLength50: '不能超过50个字符', | ||
| 126 | + maxLength13: '不能超过13个字符', | ||
| 127 | + maxLength100: '不能超过100个字符', | ||
| 128 | + maxLength200: '不能超过200个字符', | ||
| 129 | + maxLength5000: '不能超过5000个字符', | ||
| 130 | + required: '此字段为必填项', | ||
| 131 | + number: '请输入有效的数字' | ||
| 132 | + }, | ||
| 133 | + validation: { | ||
| 134 | + storeNameRequired: '商户名称为必填项', | ||
| 135 | + seqRequired: '显示序号为必填项', | ||
| 136 | + seqNumber: '显示序号必须为数字', | ||
| 137 | + telMaxLength: '电话号码不能超过13个字符', | ||
| 138 | + siteMaxLength: '位置不能超过100个字符', | ||
| 139 | + workTimeMaxLength: '工作时间不能超过200个字符', | ||
| 140 | + remarkMaxLength: '备注不能超过5000个字符' | ||
| 141 | + } | ||
| 142 | + } | ||
| 143 | + } | ||
| 144 | +} | ||
| 0 | \ No newline at end of file | 145 | \ No newline at end of file |
src/views/mall/storeInfoManageList.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div class="store-info-manage-container"> | ||
| 3 | + <!-- 查询条件 --> | ||
| 4 | + <el-card v-if="componentShow === 'storeInfoManage'" class="search-wrapper"> | ||
| 5 | + <div slot="header" class="clearfix text-left"> | ||
| 6 | + <span>{{ $t('storeInfoManage.search.title') }}</span> | ||
| 7 | + </div> | ||
| 8 | + <el-row :gutter="20"> | ||
| 9 | + <el-col :span="6"> | ||
| 10 | + <el-input v-model="conditions.name" :placeholder="$t('storeInfoManage.search.storeName')" clearable /> | ||
| 11 | + </el-col> | ||
| 12 | + <el-col :span="6"> | ||
| 13 | + <el-select v-model="conditions.convenienceMenusId" :placeholder="$t('storeInfoManage.search.convenienceType')" | ||
| 14 | + clearable> | ||
| 15 | + <el-option v-for="item in menuInfos" :key="item.convenienceMenusId" :label="item.name" | ||
| 16 | + :value="item.convenienceMenusId" /> | ||
| 17 | + </el-select> | ||
| 18 | + </el-col> | ||
| 19 | + <el-col :span="6"> | ||
| 20 | + <el-select v-model="conditions.isShow" :placeholder="$t('storeInfoManage.search.isShow')" clearable> | ||
| 21 | + <el-option :label="$t('storeInfoManage.common.yes')" value="Y" /> | ||
| 22 | + <el-option :label="$t('storeInfoManage.common.no')" value="N" /> | ||
| 23 | + </el-select> | ||
| 24 | + </el-col> | ||
| 25 | + <el-col :span="6"> | ||
| 26 | + <el-button type="primary" @click="handleQuery"> | ||
| 27 | + <i class="el-icon-search"></i> | ||
| 28 | + {{ $t('storeInfoManage.common.search') }} | ||
| 29 | + </el-button> | ||
| 30 | + </el-col> | ||
| 31 | + </el-row> | ||
| 32 | + </el-card> | ||
| 33 | + | ||
| 34 | + <!-- 商户信息列表 --> | ||
| 35 | + <el-card v-if="componentShow === 'storeInfoManage'" class="list-wrapper"> | ||
| 36 | + <div slot="header" class="clearfix flex justify-between"> | ||
| 37 | + <span>{{ $t('storeInfoManage.list.title') }}</span> | ||
| 38 | + <el-button type="primary" size="small" style="float: right;" @click="handleAdd"> | ||
| 39 | + <i class="el-icon-plus"></i> | ||
| 40 | + {{ $t('storeInfoManage.common.add') }} | ||
| 41 | + </el-button> | ||
| 42 | + </div> | ||
| 43 | + <el-table v-loading="loading" :data="storeInfos" border style="width: 100%"> | ||
| 44 | + <el-table-column prop="storeInfoId" :label="$t('storeInfoManage.table.storeInfoId')" align="center" /> | ||
| 45 | + <el-table-column prop="name" :label="$t('storeInfoManage.table.storeName')" align="center" /> | ||
| 46 | + <el-table-column :label="$t('storeInfoManage.table.icon')" align="center"> | ||
| 47 | + <template slot-scope="scope"> | ||
| 48 | + <el-image style="width: 60px; height: 60px; border-radius: 5px;" :src="scope.row.icon" | ||
| 49 | + :preview-src-list="[scope.row.icon]" fit="cover" /> | ||
| 50 | + </template> | ||
| 51 | + </el-table-column> | ||
| 52 | + <el-table-column prop="tel" :label="$t('storeInfoManage.table.tel')" align="center" /> | ||
| 53 | + <el-table-column prop="site" :label="$t('storeInfoManage.table.site')" align="center" /> | ||
| 54 | + <el-table-column prop="seq" :label="$t('storeInfoManage.table.seq')" align="center" /> | ||
| 55 | + <el-table-column :label="$t('storeInfoManage.table.isShow')" align="center"> | ||
| 56 | + <template slot-scope="scope"> | ||
| 57 | + {{ scope.row.isShow === 'Y' ? $t('storeInfoManage.common.yes') : $t('storeInfoManage.common.no') }} | ||
| 58 | + </template> | ||
| 59 | + </el-table-column> | ||
| 60 | + <el-table-column :label="$t('storeInfoManage.common.operation')" align="center" width="200"> | ||
| 61 | + <template slot-scope="scope"> | ||
| 62 | + <el-button size="mini" type="primary" @click="handleEdit(scope.row)"> | ||
| 63 | + {{ $t('storeInfoManage.common.edit') }} | ||
| 64 | + </el-button> | ||
| 65 | + <el-button size="mini" type="danger" @click="handleDelete(scope.row)"> | ||
| 66 | + {{ $t('storeInfoManage.common.delete') }} | ||
| 67 | + </el-button> | ||
| 68 | + </template> | ||
| 69 | + </el-table-column> | ||
| 70 | + </el-table> | ||
| 71 | + <el-pagination :current-page.sync="page.current" :page-sizes="[10, 20, 30, 50]" :page-size="page.size" | ||
| 72 | + :total="page.total" layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange" | ||
| 73 | + @current-change="handleCurrentChange" /> | ||
| 74 | + </el-card> | ||
| 75 | + | ||
| 76 | + <!-- 子组件 --> | ||
| 77 | + <add-store-info v-if="componentShow === 'addStoreInfo'" ref="addStoreInfo" @success="handleSuccess" | ||
| 78 | + @close="handleClose" /> | ||
| 79 | + <edit-store-info v-if="componentShow === 'editStoreInfo'" ref="editStoreInfo" :store-info="currentStoreInfo" | ||
| 80 | + @success="handleSuccess" @close="handleClose" /> | ||
| 81 | + <delete-store-info ref="deleteStoreInfo" :store-info="currentStoreInfo" @success="handleSuccess" /> | ||
| 82 | + </div> | ||
| 83 | +</template> | ||
| 84 | + | ||
| 85 | +<script> | ||
| 86 | +import { queryStoreInfo, queryConvenienceMenus } from '@/api/mall/storeInfoManageApi' | ||
| 87 | +import AddStoreInfo from '@/components/mall/AddStoreInfo' | ||
| 88 | +import EditStoreInfo from '@/components/mall/EditStoreInfo' | ||
| 89 | +import DeleteStoreInfo from '@/components/mall/DeleteStoreInfo' | ||
| 90 | + | ||
| 91 | +export default { | ||
| 92 | + name: 'StoreInfoManageList', | ||
| 93 | + components: { | ||
| 94 | + AddStoreInfo, | ||
| 95 | + EditStoreInfo, | ||
| 96 | + DeleteStoreInfo | ||
| 97 | + }, | ||
| 98 | + data() { | ||
| 99 | + return { | ||
| 100 | + loading: false, | ||
| 101 | + componentShow: 'storeInfoManage', | ||
| 102 | + conditions: { | ||
| 103 | + name: '', | ||
| 104 | + isShow: '', | ||
| 105 | + convenienceMenusId: '' | ||
| 106 | + }, | ||
| 107 | + storeInfos: [], | ||
| 108 | + menuInfos: [], | ||
| 109 | + currentStoreInfo: {}, | ||
| 110 | + page: { | ||
| 111 | + current: 1, | ||
| 112 | + size: 10, | ||
| 113 | + total: 0 | ||
| 114 | + } | ||
| 115 | + } | ||
| 116 | + }, | ||
| 117 | + created() { | ||
| 118 | + this.getStoreInfoList() | ||
| 119 | + this.getConvenienceMenusList() | ||
| 120 | + }, | ||
| 121 | + methods: { | ||
| 122 | + async getStoreInfoList() { | ||
| 123 | + try { | ||
| 124 | + this.loading = true | ||
| 125 | + const params = { | ||
| 126 | + page: this.page.current, | ||
| 127 | + row: this.page.size, | ||
| 128 | + ...this.conditions | ||
| 129 | + } | ||
| 130 | + const { data, total } = await queryStoreInfo(params) | ||
| 131 | + this.storeInfos = data | ||
| 132 | + this.page.total = total | ||
| 133 | + } catch (error) { | ||
| 134 | + this.$message.error(this.$t('storeInfoManage.error.fetchStoreInfoFailed')) | ||
| 135 | + } finally { | ||
| 136 | + this.loading = false | ||
| 137 | + } | ||
| 138 | + }, | ||
| 139 | + async getConvenienceMenusList() { | ||
| 140 | + try { | ||
| 141 | + const params = { | ||
| 142 | + page: 1, | ||
| 143 | + row: 50 | ||
| 144 | + } | ||
| 145 | + const { data } = await queryConvenienceMenus(params) | ||
| 146 | + this.menuInfos = data | ||
| 147 | + } catch (error) { | ||
| 148 | + this.$message.error(this.$t('storeInfoManage.error.fetchConvenienceMenusFailed')) | ||
| 149 | + } | ||
| 150 | + }, | ||
| 151 | + handleQuery() { | ||
| 152 | + this.page.current = 1 | ||
| 153 | + this.getStoreInfoList() | ||
| 154 | + }, | ||
| 155 | + handleAdd() { | ||
| 156 | + this.componentShow = 'addStoreInfo' | ||
| 157 | + this.$nextTick(() => { | ||
| 158 | + this.$refs.addStoreInfo.open() | ||
| 159 | + }) | ||
| 160 | + }, | ||
| 161 | + handleEdit(row) { | ||
| 162 | + this.componentShow = 'editStoreInfo' | ||
| 163 | + this.currentStoreInfo = { ...row } | ||
| 164 | + this.$nextTick(() => { | ||
| 165 | + this.$refs.editStoreInfo.open() | ||
| 166 | + }) | ||
| 167 | + }, | ||
| 168 | + handleDelete(row) { | ||
| 169 | + this.currentStoreInfo = { ...row } | ||
| 170 | + this.$nextTick(() => { | ||
| 171 | + this.$refs.deleteStoreInfo.open() | ||
| 172 | + }) | ||
| 173 | + }, | ||
| 174 | + handleSuccess() { | ||
| 175 | + this.componentShow = 'storeInfoManage' | ||
| 176 | + this.getStoreInfoList() | ||
| 177 | + }, | ||
| 178 | + handleClose() { | ||
| 179 | + this.componentShow = 'storeInfoManage' | ||
| 180 | + }, | ||
| 181 | + handleSizeChange(val) { | ||
| 182 | + this.page.size = val | ||
| 183 | + this.getStoreInfoList() | ||
| 184 | + }, | ||
| 185 | + handleCurrentChange(val) { | ||
| 186 | + this.page.current = val | ||
| 187 | + this.getStoreInfoList() | ||
| 188 | + } | ||
| 189 | + } | ||
| 190 | +} | ||
| 191 | +</script> | ||
| 192 | + | ||
| 193 | +<style lang="scss" scoped> | ||
| 194 | +.store-info-manage-container { | ||
| 195 | + padding: 20px; | ||
| 196 | + | ||
| 197 | + .search-wrapper { | ||
| 198 | + margin-bottom: 20px; | ||
| 199 | + | ||
| 200 | + .el-select { | ||
| 201 | + width: 100%; | ||
| 202 | + } | ||
| 203 | + } | ||
| 204 | + | ||
| 205 | + .list-wrapper { | ||
| 206 | + margin-bottom: 20px; | ||
| 207 | + } | ||
| 208 | + | ||
| 209 | + .el-pagination { | ||
| 210 | + margin-top: 20px; | ||
| 211 | + text-align: right; | ||
| 212 | + } | ||
| 213 | +} | ||
| 214 | +</style> | ||
| 0 | \ No newline at end of file | 215 | \ No newline at end of file |