xiongzhu 4 лет назад
Родитель
Сommit
862d43081e

+ 5 - 1
src/main/java/com/izouma/nineth/domain/Activity.java

@@ -1,6 +1,7 @@
 package com.izouma.nineth.domain;
 
 import com.izouma.nineth.annotations.Searchable;
+import com.izouma.nineth.converter.StringArrayConverter;
 import io.swagger.annotations.ApiModel;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
@@ -8,7 +9,9 @@ import lombok.Data;
 import lombok.NoArgsConstructor;
 
 import javax.persistence.Column;
+import javax.persistence.Convert;
 import javax.persistence.Entity;
+import java.util.List;
 
 @Data
 @Entity
@@ -24,6 +27,7 @@ public class Activity extends BaseEntity {
     private String cover;
 
     @Column(columnDefinition = "TEXT")
-    private String detail;
+    @Convert(converter = StringArrayConverter.class)
+    private List<String> detail;
 
 }

+ 26 - 2
src/main/resources/templates/WxMpTest.ftlh

@@ -7,7 +7,7 @@
     <meta http-equiv="X-UA-Compatible" content="ie=edge">
     <link rel="stylesheet" type="text/css" href="https://res.wx.qq.com/open/libs/weui/2.1.4/weui.min.css"/>
     <script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
-    <script src="https://cdn.bootcss.com/vConsole/3.3.4/vconsole.min.js"></script>
+    <script src="https://cdn.bootcdn.net/ajax/libs/eruda/2.4.1/eruda.min.js"></script>
     <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
     <title>微信测试页面</title>
     <style>
@@ -148,6 +148,30 @@
         </div>
     </div>
 </div>
+
+<div class="weui-form__control-area">
+    <div class="weui-cells__group weui-cells__group_form">
+        <div class="weui-cells__title">小程序测试</div>
+        <div class="weui-cells weui-cells_form">
+            <div class="weui-cell weui-cell_active">
+                <div class="weui-cell__hd"><label class="weui-label">username</label></div>
+                <div class="weui-cell__bd">
+                    <input id="username" class="weui-input" placeholder="填写username">
+                </div>
+            </div>
+            <div class="weui-cell weui-cell_active">
+                <div class="weui-cell__hd"><label class="weui-label">path</label></div>
+                <div class="weui-cell__bd">
+                    <input id="path" class="weui-input" placeholder="填写path">
+                </div>
+            </div>
+            <div class="weui-cell">
+                <button onclick="setupShare()" class="weui-btn weui-btn_primary">设置</button>
+            </div>
+        </div>
+    </div>
+</div>
+
 <div id="successToast" style="display: none;">
     <div class="weui-mask_transparent"></div>
     <div class="weui-toast">
@@ -176,7 +200,7 @@
 </div>
 </body>
 <script>
-    var vConsole = new VConsole();
+    eruda.init();
     $('#url').html(location.origin + location.pathname);
     $.get('/wx/jsapiSign', {url: encodeURI(window.location.href.split('#')[0]),}, function (res) {
         res.debug = true;

+ 7 - 2
src/main/vue/src/components/MultiUpload.vue

@@ -8,6 +8,7 @@
             :on-remove="handleRemove"
             :on-success="handleSuccess"
             :file-list="fileList"
+            :accept="accept"
             multiple
         >
             <i class="el-icon-plus"></i>
@@ -31,7 +32,7 @@
 import resolveUrl from 'resolve-url';
 export default {
     created() {
-        this.uploadUrl = resolveUrl(this.$baseUrl, 'upload/file');
+        this.uploadUrl = resolveUrl(this.$baseUrl, 'upload/file?compress=' + this.compress);
         this.updateFileList(this.value);
     },
     props: {
@@ -42,7 +43,11 @@ export default {
         },
         url: {
             type: String
-        }
+        },
+        accept: {
+            default: '*/*'
+        },
+        compress: { type: Boolean, default: false }
     },
     data() {
         return {

+ 3 - 2
src/main/vue/src/components/SingleUpload.vue

@@ -24,7 +24,7 @@
 import resolveUrl from 'resolve-url';
 export default {
     created() {
-        this.uploadUrl = resolveUrl(this.$baseUrl, 'upload/file');
+        this.uploadUrl = resolveUrl(this.$baseUrl, 'upload/file?compress=' + this.compress);
         this.updateImageUrl(this.value);
     },
     props: {
@@ -35,7 +35,8 @@ export default {
         },
         url: {
             type: String
-        }
+        },
+        compress: { type: Boolean, default: false }
     },
     data() {
         return {

+ 8 - 0
src/main/vue/src/styles/app.less

@@ -233,6 +233,14 @@ li {
     }
 }
 
+.el-form-item__content {
+    .form_tip {
+        color: @text3;
+        font-size: 13px;
+        margin-top: 5px;
+    }
+}
+
 //experimental
 .light-blue {
     body {

+ 17 - 9
src/main/vue/src/views/ActivityEdit.vue

@@ -11,7 +11,7 @@
                     :model="formData"
                     :rules="rules"
                     ref="form"
-                    label-width="52px"
+                    label-width="80px"
                     label-position="right"
                     size="small"
                     style="max-width: 500px"
@@ -19,11 +19,13 @@
                     <el-form-item prop="name" label="名称">
                         <el-input v-model="formData.name"></el-input>
                     </el-form-item>
-                    <el-form-item prop="cover" label="主图">
-                        <object-upload v-model="formData.cover" compress></object-upload>
+                    <el-form-item prop="cover" label="列表图">
+                        <single-upload v-model="formData.cover" compress></single-upload>
+                        <div class="form_tip">1029x420</div>
                     </el-form-item>
-                    <el-form-item prop="detail" label="详情">
-                        <rich-text v-model="formData.detail"></rich-text>
+                    <el-form-item prop="detail" label="详情图">
+                        <multi-upload v-model="formData.detail" accept="image/*" compress></multi-upload>
+                        <div class="form_tip">宽度1080px,长度2000px以内,可上传多张</div>
                     </el-form-item>
                     <el-form-item class="form-submit">
                         <el-button @click="onSave" :loading="saving" type="primary"> 保存 </el-button>
@@ -39,8 +41,9 @@
 </template>
 <script>
 import RichText from '../components/RichText.vue';
+import SingleUpload from '../components/SingleUpload.vue';
 export default {
-    components: { RichText },
+    components: { RichText, SingleUpload },
     name: 'ActivityEdit',
     created() {
         if (this.$route.query.id) {
@@ -70,14 +73,19 @@ export default {
                 cover: [
                     {
                         required: true,
-                        message: '请输入主图',
+                        message: '请上传列表图',
                         trigger: 'blur'
                     }
                 ],
                 detail: [
                     {
-                        required: true,
-                        message: '请输入详情',
+                        validator: (rule, value, callback) => {
+                            if (value && value.length) {
+                                callback();
+                            } else {
+                                callback(new Error('请上传详情'));
+                            }
+                        },
                         trigger: 'blur'
                     }
                 ]

+ 146 - 128
src/main/vue/src/views/ActivityList.vue

@@ -1,59 +1,73 @@
 <template>
-    <div  class="list-view">
+    <div class="list-view">
         <page-title>
-            <el-button @click="addRow" type="primary" icon="el-icon-plus" :disabled="fetchingData || downloading" class="filter-item">
+            <el-button
+                @click="addRow"
+                type="primary"
+                icon="el-icon-plus"
+                :disabled="fetchingData || downloading"
+                class="filter-item"
+            >
                 新增
             </el-button>
-            <el-button @click="download" icon="el-icon-upload2" :loading="downloading" :disabled="fetchingData" class="filter-item">
+            <el-button
+                @click="download"
+                icon="el-icon-upload2"
+                :loading="downloading"
+                :disabled="fetchingData"
+                class="filter-item"
+            >
                 导出
             </el-button>
         </page-title>
         <div class="filters-container">
             <el-input
-                    placeholder="搜索..."
-                    v-model="search"
-                    clearable
-                    class="filter-item search"
-                    @keyup.enter.native="getData"
+                placeholder="搜索..."
+                v-model="search"
+                clearable
+                class="filter-item search"
+                @keyup.enter.native="getData"
             >
                 <el-button @click="getData" slot="append" icon="el-icon-search"> </el-button>
             </el-input>
         </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" v-loading="fetchingData">
-            <el-table-column v-if="multipleMode" align="center" type="selection"
-                             width="50">
+        <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"
+            v-loading="fetchingData"
+        >
+            <el-table-column v-if="multipleMode" align="center" type="selection" width="50"> </el-table-column>
+            <el-table-column prop="id" label="ID" width="100"> </el-table-column>
+            <el-table-column prop="name" label="名称"> </el-table-column>
+            <el-table-column prop="cover" label="列表图">
+                <template slot-scope="{ row }">
+                    <el-image
+                        style="width: 30px; height: 30px"
+                        :src="row.cover"
+                        fit="cover"
+                        :preview-src-list="[row.cover]"
+                    ></el-image>
+                </template>
             </el-table-column>
-            <el-table-column prop="id" label="ID" width="100">
+            <el-table-column prop="detail" label="详情图">
+                <template slot-scope="{ row }">
+                    <el-image
+                        style="width: 30px; height: 30px"
+                        :src="row.detail[0]"
+                        fit="cover"
+                        :preview-src-list="row.detail"
+                    ></el-image>
+                </template>
             </el-table-column>
-                                <el-table-column prop="name" label="名称"
->
-                    </el-table-column>
-                    <el-table-column prop="cover" label="主图"
->
-                            <template slot-scope="{row}">
-                                <el-image style="width: 30px; height: 30px"
-                                          :src="row.cover" fit="cover"
-                                          :preview-src-list="[row.cover]"></el-image>
-                            </template>
-                    </el-table-column>
-                    <el-table-column prop="detail" label="详情"
->
-                            <template slot-scope="{row}">
-                                <el-image style="width: 30px; height: 30px"
-                                          :src="row.detail" fit="cover"
-                                          :preview-src-list="[row.detail]"></el-image>
-                            </template>
-                    </el-table-column>
-            <el-table-column
-                    label="操作"
-                    align="center"
-                    fixed="right"
-                    width="150">
-                <template slot-scope="{row}">
+            <el-table-column prop="createdAt" label="创建时间"></el-table-column>
+            <el-table-column label="操作" align="center" fixed="right" width="150">
+                <template slot-scope="{ row }">
                     <el-button @click="editRow(row)" type="primary" size="mini" plain>编辑</el-button>
                     <el-button @click="deleteRow(row)" type="danger" size="mini" plain>删除</el-button>
                 </template>
@@ -68,112 +82,116 @@
                     <el-button @click="toggleMultipleMode(false)">取消</el-button>
                 </el-button-group>
             </div> -->
-            <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">
+            <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"
+            >
             </el-pagination>
         </div>
-
     </div>
 </template>
 <script>
-    import { mapState } from "vuex";
-    import pageableTable from "@/mixins/pageableTable";
+import { mapState } from 'vuex';
+import pageableTable from '@/mixins/pageableTable';
 
-    export default {
-        name: 'ActivityList',
-        mixins: [pageableTable],
-        data() {
-            return {
-                multipleMode: false,
-                search: "",
-                url: "/activity/all",
-                downloading: false,
-            }
+export default {
+    name: 'ActivityList',
+    mixins: [pageableTable],
+    data() {
+        return {
+            multipleMode: false,
+            search: '',
+            url: '/activity/all',
+            downloading: false
+        };
+    },
+    computed: {
+        selection() {
+            return this.$refs.table.selection.map(i => i.id);
+        }
+    },
+    methods: {
+        beforeGetData() {
+            return { search: this.search, query: { del: false } };
         },
-        computed: {
-            selection() {
-                return this.$refs.table.selection.map(i => i.id);
+        toggleMultipleMode(multipleMode) {
+            this.multipleMode = multipleMode;
+            if (!multipleMode) {
+                this.$refs.table.clearSelection();
             }
         },
-        methods: {
-            beforeGetData() {
-                return { search: this.search, query: { del: false } };
-            },
-            toggleMultipleMode(multipleMode) {
-                this.multipleMode = multipleMode;
-                if (!multipleMode) {
-                    this.$refs.table.clearSelection();
+        addRow() {
+            this.$router.push({
+                path: '/activityEdit',
+                query: {
+                    ...this.$route.query
                 }
-            },
-            addRow() {
-                this.$router.push({
-                    path: "/activityEdit",
-                    query: {
-                        ...this.$route.query
-                    }
-                });
-            },
-            editRow(row) {
-                this.$router.push({
-                    path: "/activityEdit",
-                    query: {
+            });
+        },
+        editRow(row) {
+            this.$router.push({
+                path: '/activityEdit',
+                query: {
                     id: row.id
-                    }
-                });
-            },
-            download() {
-                this.downloading = true;
-                this.$axios
-                    .get("/activity/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);
-                    });
-            },
-            operation1() {
-                this.$notify({
-                    title: '提示',
-                    message: this.selection
+                }
+            });
+        },
+        download() {
+            this.downloading = true;
+            this.$axios
+                .get('/activity/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);
                 });
-            },
-            operation2() {
-                this.$message('操作2');
-            },
-            deleteRow(row) {
-                this.$alert('删除将无法恢复,确认要删除么?', '警告', {type: 'error'}).then(() => {
-                    return this.$http.post(`/activity/del/${row.id}`)
-                }).then(() => {
+        },
+        operation1() {
+            this.$notify({
+                title: '提示',
+                message: this.selection
+            });
+        },
+        operation2() {
+            this.$message('操作2');
+        },
+        deleteRow(row) {
+            this.$alert('删除将无法恢复,确认要删除么?', '警告', { type: 'error' })
+                .then(() => {
+                    return this.$http.post(`/activity/del/${row.id}`);
+                })
+                .then(() => {
                     this.$message.success('删除成功');
                     this.getData();
-                }).catch(e => {
+                })
+                .catch(e => {
                     if (e !== 'cancel') {
                         this.$message.error(e.error);
                     }
-                })
-            },
+                });
         }
     }
+};
 </script>
 <style lang="less" scoped>
 </style>

+ 11 - 2
src/main/vue/src/views/BannerEdit.vue

@@ -44,8 +44,12 @@
                     </el-form-item>
                     <el-form-item prop="linkType" label="跳转类型" v-if="formData.link">
                         <el-select v-model="formData.linkType">
-                            <el-option label="藏品/盲盒" value="collection"></el-option>
-                            <el-option label="铸造者" value="user"></el-option>
+                            <el-option
+                                v-for="item in linkTypeOptions"
+                                :key="item.value"
+                                :label="item.label"
+                                :value="item.value"
+                            ></el-option>
                         </el-select>
                     </el-form-item>
                     <el-form-item prop="linkContent" label="跳转内容" v-if="formData.link">
@@ -131,6 +135,11 @@ export default {
                 { label: '市场', value: 'MARKET' },
                 { label: 'PC官方活动', value: 'PC_ACT' },
                 { label: 'PC首页大图', value: 'PC_TITLE' }
+            ],
+            linkTypeOptions: [
+                { label: '藏品/盲盒', value: 'collection' },
+                { label: '铸造者', value: 'user' },
+                { label: '活动', value: 'activity' }
             ]
         };
     },

+ 11 - 3
src/main/vue/src/views/BannerList.vue

@@ -59,10 +59,10 @@
             <el-table-column prop="type" label="展示位置" :formatter="typeFormatter"> </el-table-column>
             <el-table-column prop="link" label="跳转">
                 <template slot-scope="{ row }">
-                    <el-tag :type="row.link ? '' : 'info'">{{ row.link }}</el-tag>
+                    <el-tag :type="row.link ? 'success' : 'info'">{{ row.link ? '是' : '否' }}</el-tag>
                 </template>
             </el-table-column>
-            <el-table-column prop="linkType" label="跳转类型"> </el-table-column>
+            <el-table-column prop="linkType" label="跳转类型" :formatter="linkTypeFormatter"> </el-table-column>
             <el-table-column prop="linkContent" label="跳转内容"> </el-table-column>
             <el-table-column label="操作" align="center" fixed="right" width="150">
                 <template slot-scope="{ row }">
@@ -115,7 +115,12 @@ export default {
                 { label: 'PC官方活动', value: 'PC_ACT' },
                 { label: 'PC首页大图', value: 'PC_TITLE' }
             ],
-            type: null
+            type: null,
+            linkTypeOptions: [
+                { label: '藏品/盲盒', value: 'collection' },
+                { label: '铸造者', value: 'user' },
+                { label: '活动', value: 'activity' }
+            ]
         };
     },
     computed: {
@@ -131,6 +136,9 @@ export default {
             }
             return '';
         },
+        linkTypeFormatter(row, column, cellValue, index) {
+            return (this.linkTypeOptions.find(i => i.value === cellValue) || {}).label;
+        },
         beforeGetData() {
             return { search: this.search, query: { del: false, type: this.type }, sort: 'sort' };
         },