panhui пре 4 година
родитељ
комит
431ecf4f47

+ 1 - 0
.gitignore

@@ -33,3 +33,4 @@ build/
 .DS_Store
 
 **/src/main/**/*.lock
+**/node_modules/**

+ 230 - 0
src/main/zhi-rong-web/src/components/FilterList.vue

@@ -0,0 +1,230 @@
+<template>
+    <div class="container">
+        <div class="filter">
+            <div class="filter-item">
+                <div class="filter-name">应用领域</div>
+                <div class="filter-content">
+                    <el-tag size="mini" effect="dark"> 全部 </el-tag>
+                    <el-tag size="mini" v-for="i in 30" :key="i" type="info" effect="plain"> 科研生产试验场 </el-tag>
+                </div>
+            </div>
+        </div>
+        <div class="main">
+            <div class="sort">
+                <div class="sort-btn">
+                    <div class="sort-item" :class="{ active: !sort }">综合排序</div>
+                    <div class="sort-item right" :class="{ active: sort.indexOf('time') !== -1 }">
+                        <span>发布时间</span>
+                        <i class="el-icon-caret-top"></i>
+                        <i class="el-icon-caret-bottom"></i>
+                    </div>
+                </div>
+
+                <div class="flex1">
+                    <search-input
+                        size="mini"
+                        v-model="search"
+                        placeholder="搜索..."
+                        @suffixClick="clickInput"
+                        clearable
+                        suffix-icon="el-icon-search"
+                        class="search"
+                    ></search-input>
+
+                    <div class="text">当前结果共1560个数据</div>
+                </div>
+            </div>
+            <div class="list">
+                <slot></slot>
+
+                <div class="empty">
+                    <i class="el-icon-takeaway-box"></i>
+                    <div class="empty-text">暂无数据</div>
+                </div>
+            </div>
+            <div class="footer">
+                <el-pagination layout="prev, pager, next" :total="1000"> </el-pagination>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script>
+import SearchInput from './SearchInput';
+export default {
+    name: 'List',
+    data() {
+        return {
+            sort: '',
+            search: ''
+        };
+    },
+    methods: {
+        clickInput() {
+            console.log('ahggsgd');
+        }
+    },
+    components: {
+        SearchInput
+    }
+};
+</script>
+
+<style lang="less" scoped>
+.container {
+    .flex-col();
+}
+.sort {
+    height: 56px;
+    background-color: #fff;
+    flex-shrink: 0;
+}
+
+.main {
+    background-color: #fff;
+    flex-grow: 1;
+    margin-top: 20px;
+    .flex-col();
+}
+.list {
+    flex-grow: 1;
+}
+.footer {
+    align-self: center;
+    padding: 50px;
+    flex-shrink: 0;
+}
+
+.empty {
+    padding: 300px 0;
+    .flex-col();
+    align-items: center;
+    i {
+        font-size: 100px;
+        color: #939599;
+    }
+
+    .empty-text {
+        font-size: 14px;
+        color: #939599;
+        margin-top: 20px;
+    }
+}
+.sort {
+    .flex();
+}
+.sort-btn {
+    .flex();
+    align-items: stretch;
+    height: 56px;
+    line-height: 56px;
+    .sort-item {
+        padding: 0 10px;
+        color: #818999;
+        font-size: 13px;
+        cursor: pointer;
+
+        &.right {
+            position: relative;
+            padding-right: 20px;
+
+            i {
+                position: absolute;
+                right: 5px;
+                color: #000;
+
+                &.el-icon-caret-top {
+                    bottom: 25px;
+                }
+                &.el-icon-caret-bottom {
+                    top: 25px;
+                }
+            }
+
+            &.desc {
+                .el-icon-caret-top {
+                    color: @prim;
+                }
+            }
+
+            &.asc {
+                .el-icon-caret-bottom {
+                    color: @prim;
+                }
+            }
+        }
+
+        &:hover {
+            color: @prim;
+        }
+
+        &.active {
+            color: @prim;
+        }
+    }
+}
+.flex1 {
+    flex-grow: 1;
+    .flex();
+    padding: 0 20px;
+
+    .text {
+        font-size: 12px;
+        color: #bcc1cc;
+        line-height: 17px;
+        margin-left: 20px;
+    }
+}
+.search {
+    width: 260px;
+    /deep/.el-input__inner {
+        background-color: @bg;
+        border-color: @bg;
+
+        &:focus {
+            border-color: @prim;
+        }
+    }
+}
+
+.filter {
+    background-color: #fff;
+    padding: 20px;
+
+    .filter-item {
+        .flex();
+        align-items: flex-start;
+        .filter-name {
+            flex-shrink: 0;
+            font-size: 13px;
+            color: #939599;
+            line-height: 22px;
+        }
+
+        .filter-content {
+            margin-left: 15px;
+            .flex();
+            flex-wrap: wrap;
+
+            /deep/ .el-tag {
+                cursor: pointer;
+                &.el-tag--plain {
+                    border-width: 0;
+                    color: #313233;
+                    &:hover {
+                        color: @prim;
+                    }
+                }
+                margin-bottom: 10px;
+                margin-right: 15px;
+
+                &.el-tag--mini {
+                    padding: 0 4px;
+                    height: 22px;
+                    border-radius: 2px;
+                }
+            }
+        }
+    }
+}
+</style>

+ 50 - 5
src/main/zhi-rong-web/src/components/PageHeader.vue

@@ -4,12 +4,20 @@
             <div class="left"></div>
 
             <div class="right">
-                <el-input v-model="search" placeholder="搜索..." clearable>
-                    <el-button slot="append" icon="el-icon-search"></el-button>
-                </el-input>
+                <search-input
+                    size="mini"
+                    v-model="search"
+                    class="search"
+                    placeholder="搜索..."
+                    @suffixClick="clickInput"
+                    clearable
+                >
+                    <i slot="append" class="el-icon-search"></i>
+                </search-input>
                 <div class="btn-list">
-                    <el-button type="text">登录</el-button>
-                    <el-button type="text">注册</el-button>
+                    <el-button size="mini" plain type="warning">登录</el-button>
+                    <div class="line"></div>
+                    <el-button size="mini" plain type="warning">注册</el-button>
                 </div>
             </div>
         </div>
@@ -17,12 +25,21 @@
 </template>
 
 <script>
+import SearchInput from './SearchInput';
 export default {
     name: 'Header',
     data() {
         return {
             search: ''
         };
+    },
+    methods: {
+        clickInput() {
+            console.log('aaaa');
+        }
+    },
+    components: {
+        SearchInput
     }
 };
 </script>
@@ -38,4 +55,32 @@ export default {
         width: 240px;
     }
 }
+
+.btn-list {
+    .flex();
+    justify-content: flex-end;
+    margin-top: 24px;
+    margin-right: -15px;
+    .el-button {
+        border-width: 0;
+        background-color: transparent;
+        &:hover {
+            text-decoration: underline;
+        }
+        &:hover,
+        &:focus,
+        &:visited {
+            color: @warn;
+        }
+    }
+    .el-button + .el-button {
+        margin-left: 0;
+    }
+
+    .line {
+        width: 1px;
+        height: 10px;
+        background-color: @warn;
+    }
+}
 </style>

+ 8 - 0
src/main/zhi-rong-web/src/components/SearchInput/index.js

@@ -0,0 +1,8 @@
+import ElInput from './src/input';
+
+/* istanbul ignore next */
+ElInput.install = function(Vue) {
+  Vue.component(ElInput.name, ElInput);
+};
+
+export default ElInput;

+ 104 - 0
src/main/zhi-rong-web/src/components/SearchInput/src/calcTextareaHeight.js

@@ -0,0 +1,104 @@
+let hiddenTextarea;
+
+const HIDDEN_STYLE = `
+  height:0 !important;
+  visibility:hidden !important;
+  overflow:hidden !important;
+  position:absolute !important;
+  z-index:-1000 !important;
+  top:0 !important;
+  right:0 !important
+`;
+
+const CONTEXT_STYLE = [
+  'letter-spacing',
+  'line-height',
+  'padding-top',
+  'padding-bottom',
+  'font-family',
+  'font-weight',
+  'font-size',
+  'text-rendering',
+  'text-transform',
+  'width',
+  'text-indent',
+  'padding-left',
+  'padding-right',
+  'border-width',
+  'box-sizing'
+];
+
+function calculateNodeStyling(targetElement) {
+  const style = window.getComputedStyle(targetElement);
+
+  const boxSizing = style.getPropertyValue('box-sizing');
+
+  const paddingSize = (
+    parseFloat(style.getPropertyValue('padding-bottom')) +
+    parseFloat(style.getPropertyValue('padding-top'))
+  );
+
+  const borderSize = (
+    parseFloat(style.getPropertyValue('border-bottom-width')) +
+    parseFloat(style.getPropertyValue('border-top-width'))
+  );
+
+  const contextStyle = CONTEXT_STYLE
+    .map(name => `${name}:${style.getPropertyValue(name)}`)
+    .join(';');
+
+  return { contextStyle, paddingSize, borderSize, boxSizing };
+}
+
+export default function calcTextareaHeight(
+  targetElement,
+  minRows = 1,
+  maxRows = null
+) {
+  if (!hiddenTextarea) {
+    hiddenTextarea = document.createElement('textarea');
+    document.body.appendChild(hiddenTextarea);
+  }
+
+  let {
+    paddingSize,
+    borderSize,
+    boxSizing,
+    contextStyle
+  } = calculateNodeStyling(targetElement);
+
+  hiddenTextarea.setAttribute('style', `${contextStyle};${HIDDEN_STYLE}`);
+  hiddenTextarea.value = targetElement.value || targetElement.placeholder || '';
+
+  let height = hiddenTextarea.scrollHeight;
+  const result = {};
+
+  if (boxSizing === 'border-box') {
+    height = height + borderSize;
+  } else if (boxSizing === 'content-box') {
+    height = height - paddingSize;
+  }
+
+  hiddenTextarea.value = '';
+  let singleRowHeight = hiddenTextarea.scrollHeight - paddingSize;
+
+  if (minRows !== null) {
+    let minHeight = singleRowHeight * minRows;
+    if (boxSizing === 'border-box') {
+      minHeight = minHeight + paddingSize + borderSize;
+    }
+    height = Math.max(minHeight, height);
+    result.minHeight = `${ minHeight }px`;
+  }
+  if (maxRows !== null) {
+    let maxHeight = singleRowHeight * maxRows;
+    if (boxSizing === 'border-box') {
+      maxHeight = maxHeight + paddingSize + borderSize;
+    }
+    height = Math.min(maxHeight, height);
+  }
+  result.height = `${ height }px`;
+  hiddenTextarea.parentNode && hiddenTextarea.parentNode.removeChild(hiddenTextarea);
+  hiddenTextarea = null;
+  return result;
+};

+ 447 - 0
src/main/zhi-rong-web/src/components/SearchInput/src/input.vue

@@ -0,0 +1,447 @@
+<template>
+    <div
+        :class="[
+            type === 'textarea' ? 'el-textarea' : 'el-input',
+            inputSize ? 'el-input--' + inputSize : '',
+            {
+                'is-disabled': inputDisabled,
+                'is-exceed': inputExceed,
+                'el-input-group': $slots.prepend || $slots.append,
+                'el-input-group--append': $slots.append,
+                'el-input-group--prepend': $slots.prepend,
+                'el-input--prefix': $slots.prefix || prefixIcon,
+                'el-input--suffix': $slots.suffix || suffixIcon || clearable || showPassword
+            }
+        ]"
+        @mouseenter="hovering = true"
+        @mouseleave="hovering = false"
+    >
+        <template v-if="type !== 'textarea'">
+            <!-- 前置元素 -->
+            <div class="el-input-group__prepend" v-if="$slots.prepend">
+                <slot name="prepend"></slot>
+            </div>
+            <input
+                :tabindex="tabindex"
+                v-if="type !== 'textarea'"
+                class="el-input__inner"
+                v-bind="$attrs"
+                :type="showPassword ? (passwordVisible ? 'text' : 'password') : type"
+                :disabled="inputDisabled"
+                :readonly="readonly"
+                :autocomplete="autoComplete || autocomplete"
+                ref="input"
+                @compositionstart="handleCompositionStart"
+                @compositionupdate="handleCompositionUpdate"
+                @compositionend="handleCompositionEnd"
+                @input="handleInput"
+                @focus="handleFocus"
+                @blur="handleBlur"
+                @change="handleChange"
+                :aria-label="label"
+            />
+            <!-- 前置内容 -->
+            <span class="el-input__prefix" v-if="$slots.prefix || prefixIcon">
+                <slot name="prefix"></slot>
+                <i class="el-input__icon" v-if="prefixIcon" :class="prefixIcon"> </i>
+            </span>
+            <!-- 后置内容 -->
+            <span class="el-input__suffix" v-if="getSuffixVisible()">
+                <span class="el-input__suffix-inner">
+                    <template v-if="!showClear || !showPwdVisible || !isWordLimitVisible">
+                        <slot name="suffix"></slot>
+                        <i
+                            class="el-input__icon"
+                            v-if="suffixIcon"
+                            :class="suffixIcon"
+                            @mousedown.prevent
+                            @click="suffixClick"
+                        >
+                        </i>
+                    </template>
+                    <i
+                        v-if="showClear"
+                        class="el-input__icon el-icon-circle-close el-input__clear"
+                        @mousedown.prevent
+                        @click="clear"
+                    ></i>
+                    <i
+                        v-if="showPwdVisible"
+                        class="el-input__icon el-icon-view el-input__clear"
+                        @click="handlePasswordVisible"
+                    ></i>
+                    <span v-if="isWordLimitVisible" class="el-input__count">
+                        <span class="el-input__count-inner"> {{ textLength }}/{{ upperLimit }} </span>
+                    </span>
+                </span>
+                <i class="el-input__icon" v-if="validateState" :class="['el-input__validateIcon', validateIcon]"> </i>
+            </span>
+            <!-- 后置元素 -->
+            <div class="el-input-group__append" v-if="$slots.append">
+                <slot name="append"></slot>
+            </div>
+        </template>
+        <textarea
+            v-else
+            :tabindex="tabindex"
+            class="el-textarea__inner"
+            @compositionstart="handleCompositionStart"
+            @compositionupdate="handleCompositionUpdate"
+            @compositionend="handleCompositionEnd"
+            @input="handleInput"
+            ref="textarea"
+            v-bind="$attrs"
+            :disabled="inputDisabled"
+            :readonly="readonly"
+            :autocomplete="autoComplete || autocomplete"
+            :style="textareaStyle"
+            @focus="handleFocus"
+            @blur="handleBlur"
+            @change="handleChange"
+            :aria-label="label"
+        >
+        </textarea>
+        <span v-if="isWordLimitVisible && type === 'textarea'" class="el-input__count"
+            >{{ textLength }}/{{ upperLimit }}</span
+        >
+    </div>
+</template>
+<script>
+import emitter from 'element-ui/src/mixins/emitter';
+import Migrating from 'element-ui/src/mixins/migrating';
+import calcTextareaHeight from './calcTextareaHeight';
+import merge from 'element-ui/src/utils/merge';
+import { isKorean } from 'element-ui/src/utils/shared';
+
+export default {
+    name: 'ElInput',
+
+    componentName: 'ElInput',
+
+    mixins: [emitter, Migrating],
+
+    inheritAttrs: false,
+
+    inject: {
+        elForm: {
+            default: ''
+        },
+        elFormItem: {
+            default: ''
+        }
+    },
+
+    data() {
+        return {
+            textareaCalcStyle: {},
+            hovering: false,
+            focused: false,
+            isComposing: false,
+            passwordVisible: false
+        };
+    },
+
+    props: {
+        value: [String, Number],
+        size: String,
+        resize: String,
+        form: String,
+        disabled: Boolean,
+        readonly: Boolean,
+        type: {
+            type: String,
+            default: 'text'
+        },
+        autosize: {
+            type: [Boolean, Object],
+            default: false
+        },
+        autocomplete: {
+            type: String,
+            default: 'off'
+        },
+        /** @Deprecated in next major version */
+        autoComplete: {
+            type: String,
+            validator() {
+                process.env.NODE_ENV !== 'production' &&
+                    console.warn(
+                        "[Element Warn][Input]'auto-complete' property will be deprecated in next major version. please use 'autocomplete' instead."
+                    );
+                return true;
+            }
+        },
+        validateEvent: {
+            type: Boolean,
+            default: true
+        },
+        suffixIcon: String,
+        prefixIcon: String,
+        label: String,
+        clearable: {
+            type: Boolean,
+            default: false
+        },
+        showPassword: {
+            type: Boolean,
+            default: false
+        },
+        showWordLimit: {
+            type: Boolean,
+            default: false
+        },
+        tabindex: String
+    },
+
+    computed: {
+        _elFormItemSize() {
+            return (this.elFormItem || {}).elFormItemSize;
+        },
+        validateState() {
+            return this.elFormItem ? this.elFormItem.validateState : '';
+        },
+        needStatusIcon() {
+            return this.elForm ? this.elForm.statusIcon : false;
+        },
+        validateIcon() {
+            return {
+                validating: 'el-icon-loading',
+                success: 'el-icon-circle-check',
+                error: 'el-icon-circle-close'
+            }[this.validateState];
+        },
+        textareaStyle() {
+            return merge({}, this.textareaCalcStyle, { resize: this.resize });
+        },
+        inputSize() {
+            return this.size || this._elFormItemSize || (this.$ELEMENT || {}).size;
+        },
+        inputDisabled() {
+            return this.disabled || (this.elForm || {}).disabled;
+        },
+        nativeInputValue() {
+            return this.value === null || this.value === undefined ? '' : String(this.value);
+        },
+        showClear() {
+            return (
+                this.clearable &&
+                !this.inputDisabled &&
+                !this.readonly &&
+                this.nativeInputValue &&
+                (this.focused || this.hovering)
+            );
+        },
+        showPwdVisible() {
+            return (
+                this.showPassword && !this.inputDisabled && !this.readonly && (!!this.nativeInputValue || this.focused)
+            );
+        },
+        isWordLimitVisible() {
+            return (
+                this.showWordLimit &&
+                this.$attrs.maxlength &&
+                (this.type === 'text' || this.type === 'textarea') &&
+                !this.inputDisabled &&
+                !this.readonly &&
+                !this.showPassword
+            );
+        },
+        upperLimit() {
+            return this.$attrs.maxlength;
+        },
+        textLength() {
+            if (typeof this.value === 'number') {
+                return String(this.value).length;
+            }
+
+            return (this.value || '').length;
+        },
+        inputExceed() {
+            // show exceed style if length of initial value greater then maxlength
+            return this.isWordLimitVisible && this.textLength > this.upperLimit;
+        }
+    },
+
+    watch: {
+        value(val) {
+            this.$nextTick(this.resizeTextarea);
+            if (this.validateEvent) {
+                this.dispatch('ElFormItem', 'el.form.change', [val]);
+            }
+        },
+        // native input value is set explicitly
+        // do not use v-model / :value in template
+        // see: https://github.com/ElemeFE/element/issues/14521
+        nativeInputValue() {
+            this.setNativeInputValue();
+        },
+        // when change between <input> and <textarea>,
+        // update DOM dependent value and styles
+        // https://github.com/ElemeFE/element/issues/14857
+        type() {
+            this.$nextTick(() => {
+                this.setNativeInputValue();
+                this.resizeTextarea();
+                this.updateIconOffset();
+            });
+        }
+    },
+
+    methods: {
+        focus() {
+            this.getInput().focus();
+        },
+        blur() {
+            this.getInput().blur();
+        },
+        getMigratingConfig() {
+            return {
+                props: {
+                    icon: 'icon is removed, use suffix-icon / prefix-icon instead.',
+                    'on-icon-click': 'on-icon-click is removed.'
+                },
+                events: {
+                    click: 'click is removed.'
+                }
+            };
+        },
+        handleBlur(event) {
+            this.focused = false;
+            this.$emit('blur', event);
+            if (this.validateEvent) {
+                this.dispatch('ElFormItem', 'el.form.blur', [this.value]);
+            }
+        },
+        select() {
+            this.getInput().select();
+        },
+        resizeTextarea() {
+            if (this.$isServer) return;
+            const { autosize, type } = this;
+            if (type !== 'textarea') return;
+            if (!autosize) {
+                this.textareaCalcStyle = {
+                    minHeight: calcTextareaHeight(this.$refs.textarea).minHeight
+                };
+                return;
+            }
+            const minRows = autosize.minRows;
+            const maxRows = autosize.maxRows;
+
+            this.textareaCalcStyle = calcTextareaHeight(this.$refs.textarea, minRows, maxRows);
+        },
+        setNativeInputValue() {
+            const input = this.getInput();
+            if (!input) return;
+            if (input.value === this.nativeInputValue) return;
+            input.value = this.nativeInputValue;
+        },
+        handleFocus(event) {
+            this.focused = true;
+            this.$emit('focus', event);
+        },
+        handleCompositionStart() {
+            this.isComposing = true;
+        },
+        handleCompositionUpdate(event) {
+            const text = event.target.value;
+            const lastCharacter = text[text.length - 1] || '';
+            this.isComposing = !isKorean(lastCharacter);
+        },
+        handleCompositionEnd(event) {
+            if (this.isComposing) {
+                this.isComposing = false;
+                this.handleInput(event);
+            }
+        },
+        handleInput(event) {
+            // should not emit input during composition
+            // see: https://github.com/ElemeFE/element/issues/10516
+            if (this.isComposing) return;
+
+            // hack for https://github.com/ElemeFE/element/issues/8548
+            // should remove the following line when we don't support IE
+            if (event.target.value === this.nativeInputValue) return;
+
+            this.$emit('input', event.target.value);
+
+            // ensure native input value is controlled
+            // see: https://github.com/ElemeFE/element/issues/12850
+            this.$nextTick(this.setNativeInputValue);
+        },
+        handleChange(event) {
+            this.$emit('change', event.target.value);
+        },
+        calcIconOffset(place) {
+            let elList = [].slice.call(this.$el.querySelectorAll(`.el-input__${place}`) || []);
+            if (!elList.length) return;
+            let el = null;
+            for (let i = 0; i < elList.length; i++) {
+                if (elList[i].parentNode === this.$el) {
+                    el = elList[i];
+                    break;
+                }
+            }
+            if (!el) return;
+            const pendantMap = {
+                suffix: 'append',
+                prefix: 'prepend'
+            };
+
+            const pendant = pendantMap[place];
+            if (this.$slots[pendant]) {
+                el.style.transform = `translateX(${place === 'suffix' ? '-' : ''}${
+                    this.$el.querySelector(`.el-input-group__${pendant}`).offsetWidth
+                }px)`;
+            } else {
+                el.removeAttribute('style');
+            }
+        },
+        updateIconOffset() {
+            this.calcIconOffset('prefix');
+            this.calcIconOffset('suffix');
+        },
+        suffixClick() {
+            this.$emit('suffixClick');
+        },
+        clear() {
+            this.$emit('input', '');
+            this.$emit('change', '');
+            this.$emit('clear');
+        },
+        handlePasswordVisible() {
+            this.passwordVisible = !this.passwordVisible;
+            this.$nextTick(() => {
+                this.focus();
+            });
+        },
+        getInput() {
+            return this.$refs.input || this.$refs.textarea;
+        },
+        getSuffixVisible() {
+            return (
+                this.$slots.suffix ||
+                this.suffixIcon ||
+                this.showClear ||
+                this.showPassword ||
+                this.isWordLimitVisible ||
+                (this.validateState && this.needStatusIcon)
+            );
+        }
+    },
+
+    created() {
+        this.$on('inputSelect', this.select);
+    },
+
+    mounted() {
+        this.setNativeInputValue();
+        this.resizeTextarea();
+        this.updateIconOffset();
+    },
+
+    updated() {
+        this.$nextTick(this.updateIconOffset);
+    }
+};
+</script>

+ 181 - 0
src/main/zhi-rong-web/src/components/SortList.vue

@@ -0,0 +1,181 @@
+<template>
+    <div class="container">
+        <div class="top">
+            <div class="sort-btn">
+                <div class="sort-item" :class="{ active: !sort }">综合排序</div>
+                <div class="sort-item right" :class="{ active: sort.indexOf('time') !== -1 }">
+                    <span>发布时间</span>
+                    <i class="el-icon-caret-top"></i>
+                    <i class="el-icon-caret-bottom"></i>
+                </div>
+            </div>
+
+            <div class="flex1">
+                <search-input
+                    size="mini"
+                    v-model="search"
+                    placeholder="搜索..."
+                    @suffixClick="clickInput"
+                    clearable
+                    suffix-icon="el-icon-search"
+                    class="search"
+                ></search-input>
+
+                <div class="text">当前结果共1560个数据</div>
+            </div>
+        </div>
+        <div class="main">
+            <div class="list">
+                <slot></slot>
+
+                <div class="empty">
+                    <i class="el-icon-takeaway-box"></i>
+                    <div class="empty-text">暂无数据</div>
+                </div>
+            </div>
+            <div class="footer">
+                <el-pagination layout="prev, pager, next" :total="1000"> </el-pagination>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script>
+import SearchInput from './SearchInput';
+export default {
+    name: 'List',
+    data() {
+        return {
+            sort: '',
+            search: ''
+        };
+    },
+    methods: {
+        clickInput() {
+            console.log('ahggsgd');
+        }
+    },
+    components: {
+        SearchInput
+    }
+};
+</script>
+
+<style lang="less" scoped>
+.container {
+    .flex-col();
+}
+.top {
+    height: 56px;
+    background-color: #fff;
+    flex-shrink: 0;
+}
+
+.main {
+    background-color: #fff;
+    flex-grow: 1;
+    margin-top: 20px;
+    .flex-col();
+}
+.list {
+    flex-grow: 1;
+}
+.footer {
+    align-self: center;
+    padding: 50px;
+    flex-shrink: 0;
+}
+
+.empty {
+    padding: 300px 0;
+    .flex-col();
+    align-items: center;
+    i {
+        font-size: 100px;
+        color: #939599;
+    }
+
+    .empty-text {
+        font-size: 14px;
+        color: #939599;
+        margin-top: 20px;
+    }
+}
+.top {
+    .flex();
+}
+.sort-btn {
+    .flex();
+    align-items: stretch;
+    height: 56px;
+    line-height: 56px;
+    .sort-item {
+        padding: 0 10px;
+        color: #818999;
+        font-size: 13px;
+        cursor: pointer;
+
+        &.right {
+            position: relative;
+            padding-right: 20px;
+
+            i {
+                position: absolute;
+                right: 5px;
+                color: #000;
+
+                &.el-icon-caret-top {
+                    bottom: 25px;
+                }
+                &.el-icon-caret-bottom {
+                    top: 25px;
+                }
+            }
+
+            &.desc {
+                .el-icon-caret-top {
+                    color: @prim;
+                }
+            }
+
+            &.asc {
+                .el-icon-caret-bottom {
+                    color: @prim;
+                }
+            }
+        }
+
+        &:hover {
+            color: @prim;
+        }
+
+        &.active {
+            color: @prim;
+        }
+    }
+}
+.flex1 {
+    flex-grow: 1;
+    .flex();
+    justify-content: flex-end;
+    padding: 0 20px;
+
+    .text {
+        font-size: 12px;
+        color: #bcc1cc;
+        line-height: 17px;
+        margin-left: 20px;
+    }
+}
+.search {
+    width: 260px;
+    /deep/.el-input__inner {
+        background-color: @bg;
+        border-color: @bg;
+
+        &:focus {
+            border-color: @prim;
+        }
+    }
+}
+</style>

+ 1 - 1
src/main/zhi-rong-web/src/components/home/ServiceBox.vue

@@ -47,7 +47,7 @@ export default {};
     right: 0;
     bottom: 0;
     z-index: 2;
-    background-color: rgba(0, 0, 0, 0.1);
+    background-color: rgba(0, 0, 0, 0.2);
     .flex-col();
     color: #fff;
     justify-content: center;

+ 8 - 0
src/main/zhi-rong-web/src/router/index.js

@@ -31,6 +31,14 @@ const routes = [
                         meta: {
                             title: '政策'
                         }
+                    },
+                    {
+                        path:'/statistics',
+                        name:'statistics',
+                        component: () => import('../views/Statistics.vue'),
+                        meta: {
+                            title: '数据'
+                        }
                     }
                 ]
             },

+ 34 - 1
src/main/zhi-rong-web/src/styles/app.less

@@ -38,7 +38,7 @@ body {
     }
 }
 .el-menu {
-    border-right-width: 0px!important;
+    border-right-width: 0px !important;
 }
 
 .popup-menu {
@@ -65,3 +65,36 @@ body {
         }
     }
 }
+
+.search {
+    .el-input__suffix-inner {
+        display: flex;
+        flex-direction: row-reverse;
+
+        .el-icon-search {
+            color: #c0c4cc;
+            font-size: 14;
+            cursor: pointer;
+            transition: color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
+
+            &:hover {
+                color: #909399;
+            }
+        }
+    }
+
+    .el-input-group__append,
+    .el-input-group__prepend {
+        background-color: @warn;
+        padding: 0 10px;
+        color: #fff;
+        border-color: @warn;
+    }
+
+    &.el-input-group--append {
+        .el-input__inner {
+            border-color: @warn;
+            
+        }
+    }
+}

+ 5 - 4
src/main/zhi-rong-web/src/views/Legal.vue

@@ -1,11 +1,12 @@
 <template>
-    <div>
-        
-    </div>
+    <sort-list> </sort-list>
 </template>
 
 <script>
-export default {};
+import SortList from '../components/SortList.vue';
+export default {
+    components: { SortList }
+};
 </script>
 
 <style></style>

+ 12 - 0
src/main/zhi-rong-web/src/views/Statistics.vue

@@ -0,0 +1,12 @@
+<template>
+    <filter-list></filter-list>
+</template>
+
+<script>
+import FilterList from '../components/FilterList.vue';
+export default {
+    components: { FilterList }
+};
+</script>
+
+<style></style>