drew 5 лет назад
Родитель
Сommit
f1af61c009

+ 20 - 9
src/main/java/com/izouma/awesomeAdmin/web/UserController.java

@@ -5,6 +5,8 @@ import com.izouma.awesomeAdmin.dto.PageQuery;
 import com.izouma.awesomeAdmin.exception.BusinessException;
 import com.izouma.awesomeAdmin.repo.UserRepo;
 import com.izouma.awesomeAdmin.security.Authority;
+import com.izouma.awesomeAdmin.security.JwtTokenUtil;
+import com.izouma.awesomeAdmin.security.JwtUserFactory;
 import com.izouma.awesomeAdmin.service.UserService;
 import com.izouma.awesomeAdmin.utils.ObjUtils;
 import com.izouma.awesomeAdmin.utils.SecurityUtils;
@@ -26,19 +28,20 @@ import java.util.List;
 @RestController
 @RequestMapping("/user")
 public class UserController extends BaseController {
-    private UserRepo    userRepo;
-    private UserService userService;
+    private UserRepo     userRepo;
+    private UserService  userService;
+    private JwtTokenUtil jwtTokenUtil;
 
     @PostMapping("/register")
     public User register(@RequestParam String username,
                          @RequestParam String password) {
         User user = User.builder()
-                        .username(username)
-                        .nickname(username)
-                        .password(new BCryptPasswordEncoder().encode(password))
-                        .enabled(true)
-                        .authorities(Collections.singleton(new Authority(Authority.NAMES.ROLE_USER.name())))
-                        .build();
+                .username(username)
+                .nickname(username)
+                .password(new BCryptPasswordEncoder().encode(password))
+                .enabled(true)
+                .authorities(Collections.singleton(new Authority(Authority.NAMES.ROLE_USER.name())))
+                .build();
         return userRepo.save(user);
     }
 
@@ -55,7 +58,8 @@ public class UserController extends BaseController {
 
     @GetMapping("/my")
     public User my() {
-        return userRepo.findById(SecurityUtils.getAuthenticatedUser().getId()).orElseThrow(new BusinessException("用户不存在"));
+        return userRepo.findById(SecurityUtils.getAuthenticatedUser().getId())
+                .orElseThrow(new BusinessException("用户不存在"));
     }
 
     @PreAuthorize("hasRole('ADMIN')")
@@ -92,4 +96,11 @@ public class UserController extends BaseController {
     public String setPasswordAdmin(@RequestParam Long userId, @RequestParam String password) {
         return userService.setPassword(userId, password);
     }
+
+    @PreAuthorize("hasRole('ADMIN')")
+    @GetMapping("/getToken/{userId}")
+    public String getToken(@PathVariable Long userId) {
+        return jwtTokenUtil.generateToken(JwtUserFactory.create(userRepo.findById(userId)
+                .orElseThrow(new BusinessException("用户不存在"))));
+    }
 }

+ 1 - 0
src/main/vue/package.json

@@ -14,6 +14,7 @@
     "axios": "^0.19.0",
     "babel-polyfill": "^6.26.0",
     "chart.js": "^2.8.0",
+    "clipboard": "^2.0.6",
     "core-js": "^2.6.5",
     "date-fns": "^2.3.0",
     "element-ui": "^2.12.0",

+ 205 - 133
src/main/vue/src/views/SysConfigList.vue

@@ -5,28 +5,29 @@
             <el-button @click="getData" type="primary" icon="el-icon-search" class="filter-item">搜索 </el-button>
             <el-button @click="editRow()" type="primary" icon="el-icon-plus" class="filter-item">添加 </el-button>
             <el-button
-                @click="download"
-                type="primary"
-                icon="el-icon-download"
-                :loading="downloading"
-                class="filter-item"
-                >导出EXCEL
+                    @click="download"
+                    type="primary"
+                    icon="el-icon-download"
+                    :loading="downloading"
+                    class="filter-item"
+            >导出EXCEL
             </el-button>
         </div>
         <el-table
-            :data="tableData"
-            row-key="id"
-            ref="table"
-            header-row-class-name="table-header-row"
-            header-cell-class-name="table-header-cell"
-            row-class-name="table-row"
-            cell-class-name="table-cell"
-            :height="tableHeight"
+                :data="tableData"
+                row-key="id"
+                ref="table"
+                header-row-class-name="table-header-row"
+                header-cell-class-name="table-header-cell"
+                row-class-name="table-row"
+                cell-class-name="table-cell"
+                :height="tableHeight"
         >
             <el-table-column prop="name" label="名称"> </el-table-column>
             <el-table-column prop="desc" label="描述"> </el-table-column>
-            <el-table-column prop="value" label="值"> </el-table-column>
-            <el-table-column label="操作" align="center" fixed="right" min-width="150">
+            <el-table-column prop="type" label="类型" :formatter="typeFormatter"></el-table-column>
+            <el-table-column prop="value" label="值" show-overflow-tooltip> </el-table-column>
+            <el-table-column label="操作" align="center" fixed="right" width="150">
                 <template slot-scope="{ row }">
                     <el-button @click="editRow(row, true)" type="primary" size="mini" plain>编辑</el-button>
                 </template>
@@ -34,19 +35,19 @@
         </el-table>
         <div class="pagination-wrapper">
             <el-pagination
-                background
-                @size-change="onSizeChange"
-                @current-change="onCurrentChange"
-                :current-page="page"
-                :page-sizes="[10, 20, 30, 40, 50]"
-                :page-size="pageSize"
-                layout="total, sizes, prev, pager, next, jumper"
-                :total="totalElements"
+                    background
+                    @size-change="onSizeChange"
+                    @current-change="onCurrentChange"
+                    :current-page="page"
+                    :page-sizes="[10, 20, 30, 40, 50]"
+                    :page-size="pageSize"
+                    layout="total, sizes, prev, pager, next, jumper"
+                    :total="totalElements"
             >
             </el-pagination>
         </div>
 
-        <el-dialog :visible.sync="showDialog" width="500px">
+        <el-dialog :visible.sync="showDialog" width="500px" title="编辑设置" :close-on-click-modal="false">
             <el-form :model="formData" :rules="rules" ref="form" label-width="52px" label-position="right" size="small">
                 <el-form-item prop="name" label="名称">
                     <el-input v-model="formData.name" :disabled="edit === true"></el-input>
@@ -54,8 +55,48 @@
                 <el-form-item prop="desc" label="描述">
                     <el-input v-model="formData.desc"></el-input>
                 </el-form-item>
+                <el-form-item prop="type" label="类型">
+                    <el-select v-model="formData.type" placeholder="请选择" :disabled="edit === true">
+                        <el-option
+                                v-for="item in valueTypes"
+                                :label="item.label"
+                                :value="item.value"
+                                :key="item.value"
+                        ></el-option>
+                    </el-select>
+                </el-form-item>
                 <el-form-item prop="value" label="值">
-                    <el-input v-model="formData.value"></el-input>
+                    <el-input v-model="formData.value" v-if="formData.type === 'STRING'"></el-input>
+                    <el-date-picker
+                            v-model="formData.value"
+                            v-if="formData.type === 'DATETIME'"
+                            type="datetime"
+                            value-format="yyyy-MM-dd HH:mm:ss"
+                            placeholder="请选择日期时间"
+                    ></el-date-picker>
+                    <el-date-picker
+                            v-model="formData.value"
+                            v-if="formData.type === 'DATE'"
+                            type="date"
+                            value-format="yyyy-MM-dd"
+                            placeholder="请选择日期"
+                    ></el-date-picker>
+                    <el-time-picker
+                            v-model="formData.value"
+                            v-if="formData.type === 'TIME'"
+                            value-format="HH:mm"
+                            placeholder="请选择时间"
+                            arrow-control
+                    ></el-time-picker>
+                    <el-switch
+                            v-model="formData.value"
+                            v-if="formData.type === 'BOOLEAN'"
+                            active-text="是"
+                            inactive-text="否"
+                            active-value="1"
+                            inactive-value="0"
+                    ></el-switch>
+                    <el-input-number v-model="formData.value" v-if="formData.type === 'NUMBER'"></el-input-number>
                 </el-form-item>
             </el-form>
             <span slot="footer">
@@ -65,120 +106,151 @@
     </div>
 </template>
 <script>
-import { mapState } from 'vuex';
-import pageableTable from '@/mixins/pageableTable';
+    import { mapState } from 'vuex';
+    import pageableTable from '@/mixins/pageableTable';
 
-export default {
-    name: 'SysConfigList',
-    mixins: [pageableTable],
-    created() {
-        this.getData();
-    },
-    data() {
-        return {
-            multipleMode: false,
-            search: '',
-            url: '/sysConfig/all',
-            downloading: false,
-            formData: {
-                name: '',
-                desc: '',
-                value: ''
-            },
-            rules: {
-                name: [{ required: true, message: '请输入名称', trigger: 'blur' }],
-                desc: [{ required: true, message: '请输入描述', trigger: 'blur' }],
-                value: [{ required: true, message: '请输入值', trigger: 'blur' }]
-            },
-            showDialog: false,
-            saving: false,
-            edit: false
-        };
-    },
-    computed: {
-        selection() {
-            return this.$refs.table.selection.map(i => i.id);
-        }
-    },
-    methods: {
-        beforeGetData() {
-            return { search: this.search, sort: 'name' };
-        },
-        toggleMultipleMode(multipleMode) {
-            this.multipleMode = multipleMode;
-            if (!multipleMode) {
-                this.$refs.table.clearSelection();
-            }
-        },
-        addRow() {
-            this.$router.push({
-                path: '/sysConfigEdit',
-                query: {
-                    ...this.$route.query
-                }
-            });
-        },
-        editRow(row, edit) {
-            this.edit = edit;
-            if (!row) {
-                row = {
+    export default {
+        name: 'SysConfigList',
+        mixins: [pageableTable],
+        data() {
+            return {
+                multipleMode: false,
+                search: '',
+                url: '/sysConfig/all',
+                downloading: false,
+                formData: {
                     name: '',
                     desc: '',
-                    value: ''
-                };
+                    value: '',
+                    type: 'STRING'
+                },
+                rules: {
+                    name: [{ required: true, message: '请输入名称', trigger: 'blur' }],
+                    desc: [{ required: true, message: '请输入描述', trigger: 'blur' }],
+                    type: [{ required: true, message: '请选择类型', trigger: 'blur' }],
+                    value: [{ required: true, message: '请输入值', trigger: 'blur' }]
+                },
+                showDialog: false,
+                saving: false,
+                edit: false,
+                sortStr: 'createdAt,desc',
+                valueTypes: [
+                    {
+                        label: '字符串',
+                        value: 'STRING'
+                    },
+                    {
+                        label: '日期时间',
+                        value: 'DATETIME'
+                    },
+                    {
+                        label: '日期',
+                        value: 'DATE'
+                    },
+                    {
+                        label: '时间',
+                        value: 'TIME'
+                    },
+                    {
+                        label: '开关',
+                        value: 'BOOLEAN'
+                    },
+                    {
+                        label: '数字',
+                        value: 'NUMBER'
+                    }
+                ]
+            };
+        },
+        computed: {
+            selection() {
+                return this.$refs.table.selection.map(i => i.id);
             }
-            this.formData = row;
-            this.showDialog = true;
         },
-        download() {
-            this.downloading = true;
-            this.$axios
-                .get('/sysConfig/excel', {
-                    responseType: 'blob',
-                    params: { size: 10000 }
-                })
-                .then(res => {
-                    console.log(res);
-                    this.downloading = false;
-                    const downloadUrl = window.URL.createObjectURL(new Blob([res.data]));
-                    const link = document.createElement('a');
-                    link.href = downloadUrl;
-                    link.setAttribute('download', res.headers['content-disposition'].split('filename=')[1]);
-                    document.body.appendChild(link);
-                    link.click();
-                    link.remove();
-                })
-                .catch(e => {
-                    console.log(e);
-                    this.downloading = false;
-                    this.$message.error(e.error);
+        methods: {
+            beforeGetData() {
+                return { search: this.search, sort: 'createdAt,desc' };
+            },
+            toggleMultipleMode(multipleMode) {
+                this.multipleMode = multipleMode;
+                if (!multipleMode) {
+                    this.$refs.table.clearSelection();
+                }
+            },
+            addRow() {
+                this.$router.push({
+                    path: '/sysConfigEdit',
+                    query: {
+                        ...this.$route.query
+                    }
                 });
-        },
-        save() {
-            this.$refs.form.validate(valid => {
-                if (valid) {
-                    let data = { ...this.formData };
-                    this.saving = true;
-                    this.$http
-                        .post('/sysConfig/save', data, { body: 'json' })
-                        .then(res => {
-                            this.saving = false;
-                            this.$message.success('成功');
-                            this.showDialog = false;
-                            this.getData();
-                        })
-                        .catch(e => {
-                            console.log(e);
-                            this.saving = false;
-                            this.showDialog = false;
-                            this.$message.error(e.error);
-                        });
-                } else {
-                    return false;
+            },
+            editRow(row, edit) {
+                this.edit = edit;
+                if (!row) {
+                    row = {
+                        name: '',
+                        desc: '',
+                        value: '',
+                        type: null
+                    };
                 }
-            });
+                this.formData = { ...row };
+                this.showDialog = true;
+            },
+            download() {
+                this.downloading = true;
+                this.$axios
+                    .get('/sysConfig/excel', {
+                        responseType: 'blob',
+                        params: { size: 10000 }
+                    })
+                    .then(res => {
+                        console.log(res);
+                        this.downloading = false;
+                        const downloadUrl = window.URL.createObjectURL(new Blob([res.data]));
+                        const link = document.createElement('a');
+                        link.href = downloadUrl;
+                        link.setAttribute('download', res.headers['content-disposition'].split('filename=')[1]);
+                        document.body.appendChild(link);
+                        link.click();
+                        link.remove();
+                    })
+                    .catch(e => {
+                        console.log(e);
+                        this.downloading = false;
+                        this.$message.error(e.error);
+                    });
+            },
+            save() {
+                this.$refs.form.validate(valid => {
+                    if (valid) {
+                        let data = { ...this.formData };
+                        this.saving = true;
+                        this.$http
+                            .post('/sysConfig/save', data, { body: 'json' })
+                            .then(res => {
+                                this.saving = false;
+                                this.$message.success('成功');
+                                this.showDialog = false;
+                                this.getData();
+                            })
+                            .catch(e => {
+                                console.log(e);
+                                this.saving = false;
+                                this.showDialog = false;
+                                this.$message.error(e.error);
+                            });
+                    } else {
+                        return false;
+                    }
+                });
+            },
+            typeFormatter(row, cell, cellValue) {
+                let item = this.valueTypes.find(i => i.value === cellValue);
+                return item ? item.label : '';
+            }
         }
-    }
-};
+    };
 </script>
 <style lang="less" scoped></style>

+ 33 - 1
src/main/vue/src/views/UserList.vue

@@ -63,7 +63,8 @@
 <script>
 import { mapState } from "vuex";
 import pageableTable from "@/mixins/pageableTable";
-
+import ClipboardJS from 'clipboard';
+const clickData = {};
 export default {
     mixins: [pageableTable],
     data() {
@@ -142,6 +143,37 @@ export default {
         },
         operation2() {
             this.$message("操作2");
+        },
+        clickId(row) {
+            if (row.id !== clickData.id) {
+                clickData.id = row.id;
+                clickData.c = 0;
+            }
+            clickData.c = (clickData.c || 0) + 1;
+            if (clickData.i) {
+                clearInterval(clickData.i);
+            }
+            clickData.i = setTimeout(_ => {
+                clickData.c = 0;
+            }, 200);
+            if (clickData.c === 5) {
+                this.$http
+                    .get(`/user/getToken/${row.id}`)
+                    .then(res => {
+                        let el = document.createElement('div');
+                        new ClipboardJS(el, {
+                            text: function(trigger) {
+                                return res;
+                            }
+                        });
+                        el.click();
+                        this.$message.success('已复制Token');
+                        clickData.c = 0;
+                    })
+                    .catch(e => {
+                        this.$message.error(e.error);
+                    });
+            }
         }
     }
 };

+ 31 - 0
src/main/vue/yarn.lock

@@ -2069,6 +2069,15 @@ cli-spinners@^2.0.0:
   resolved "https://registry.npm.taobao.org/cli-spinners/download/cli-spinners-2.2.0.tgz#e8b988d9206c692302d8ee834e7a85c0144d8f77"
   integrity sha1-6LmI2SBsaSMC2O6DTnqFwBRNj3c=
 
+clipboard@^2.0.6:
+  version "2.0.6"
+  resolved "https://registry.npm.taobao.org/clipboard/download/clipboard-2.0.6.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fclipboard%2Fdownload%2Fclipboard-2.0.6.tgz#52921296eec0fdf77ead1749421b21c968647376"
+  integrity sha1-UpISlu7A/fd+rRdJQhshyWhkc3Y=
+  dependencies:
+    good-listener "^1.2.2"
+    select "^1.1.2"
+    tiny-emitter "^2.0.0"
+
 clipboardy@^2.0.0:
   version "2.1.0"
   resolved "https://registry.npm.taobao.org/clipboardy/download/clipboardy-2.1.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fclipboardy%2Fdownload%2Fclipboardy-2.1.0.tgz#0123a0c8fac92f256dc56335e0bb8be97a4909a5"
@@ -2737,6 +2746,11 @@ delayed-stream@~1.0.0:
   resolved "https://registry.npm.taobao.org/delayed-stream/download/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
   integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk=
 
+delegate@^3.1.2:
+  version "3.2.0"
+  resolved "https://registry.npm.taobao.org/delegate/download/delegate-3.2.0.tgz#b66b71c3158522e8ab5744f720d8ca0c2af59166"
+  integrity sha1-tmtxwxWFIuirV0T3INjKDCr1kWY=
+
 delegates@^1.0.0:
   version "1.0.0"
   resolved "https://registry.npm.taobao.org/delegates/download/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
@@ -3600,6 +3614,13 @@ globby@^9.2.0:
     pify "^4.0.1"
     slash "^2.0.0"
 
+good-listener@^1.2.2:
+  version "1.2.2"
+  resolved "https://registry.npm.taobao.org/good-listener/download/good-listener-1.2.2.tgz#d53b30cdf9313dffb7dc9a0d477096aa6d145c50"
+  integrity sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=
+  dependencies:
+    delegate "^3.1.2"
+
 graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6:
   version "4.2.2"
   resolved "https://registry.npm.taobao.org/graceful-fs/download/graceful-fs-4.2.2.tgz#6f0952605d0140c1cfdb138ed005775b92d67b02"
@@ -6582,6 +6603,11 @@ select-hose@^2.0.0:
   resolved "https://registry.npm.taobao.org/select-hose/download/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca"
   integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=
 
+select@^1.1.2:
+  version "1.1.2"
+  resolved "https://registry.npm.taobao.org/select/download/select-1.1.2.tgz#0e7350acdec80b1108528786ec1d4418d11b396d"
+  integrity sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=
+
 selfsigned@^1.10.7:
   version "1.10.7"
   resolved "https://registry.npm.taobao.org/selfsigned/download/selfsigned-1.10.7.tgz?cache=0&sync_timestamp=1569952074772&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fselfsigned%2Fdownload%2Fselfsigned-1.10.7.tgz#da5819fd049d5574f28e88a9bcc6dbc6e6f3906b"
@@ -7241,6 +7267,11 @@ timsort@^0.3.0:
   resolved "https://registry.npm.taobao.org/timsort/download/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4"
   integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=
 
+tiny-emitter@^2.0.0:
+  version "2.1.0"
+  resolved "https://registry.npm.taobao.org/tiny-emitter/download/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423"
+  integrity sha1-HRpW7fxRxD6GPLtTgqcjMONVVCM=
+
 tinymce@^5.2.2:
   version "5.2.2"
   resolved "https://registry.npm.taobao.org/tinymce/download/tinymce-5.2.2.tgz#1ac77cce1565b54932b4e612d2fd9c07b687f238"