zory 2 月之前
父节点
当前提交
c4125e5ee8
共有 42 个文件被更改,包括 1782 次插入430 次删除
  1. 33 0
      src/api/model/article.js
  2. 33 0
      src/api/model/category.js
  3. 0 33
      src/api/model/combo.js
  4. 0 26
      src/api/model/mDiscount.js
  5. 0 22
      src/api/model/mMember.js
  6. 0 61
      src/api/model/mOrder.js
  7. 0 26
      src/api/model/mPrice.js
  8. 0 40
      src/api/model/mPrint.js
  9. 0 47
      src/api/model/mQrcode.js
  10. 0 47
      src/api/model/mRenew.js
  11. 0 19
      src/api/model/mShop.js
  12. 0 40
      src/api/model/mStaff.js
  13. 0 26
      src/api/model/mUser.js
  14. 33 0
      src/api/model/page.js
  15. 3 0
      src/views/manage/expert/group/components/form.vue
  16. 61 0
      src/views/manage/expert/group/components/option.vue
  17. 49 0
      src/views/manage/expert/group/components/search.vue
  18. 21 0
      src/views/manage/expert/group/components/table.vue
  19. 47 0
      src/views/manage/expert/group/index.vue
  20. 3 0
      src/views/manage/expert/index/components/form.vue
  21. 61 0
      src/views/manage/expert/index/components/option.vue
  22. 49 0
      src/views/manage/expert/index/components/search.vue
  23. 21 0
      src/views/manage/expert/index/components/table.vue
  24. 43 7
      src/views/manage/expert/index/index.vue
  25. 93 0
      src/views/manage/school/category/components/form.vue
  26. 62 0
      src/views/manage/school/category/components/option.vue
  27. 51 0
      src/views/manage/school/category/components/search.vue
  28. 108 0
      src/views/manage/school/category/components/table.vue
  29. 43 7
      src/views/manage/school/category/index.vue
  30. 153 0
      src/views/manage/school/lists/components/form.vue
  31. 62 0
      src/views/manage/school/lists/components/option.vue
  32. 49 0
      src/views/manage/school/lists/components/search.vue
  33. 127 0
      src/views/manage/school/lists/components/table.vue
  34. 43 7
      src/views/manage/school/lists/index.vue
  35. 0 13
      src/views/manage/setting/basic/index.vue
  36. 112 0
      src/views/manage/setting/page/form.vue
  37. 65 2
      src/views/manage/setting/page/index.vue
  38. 93 0
      src/views/manage/task/category/components/form.vue
  39. 62 0
      src/views/manage/task/category/components/option.vue
  40. 51 0
      src/views/manage/task/category/components/search.vue
  41. 108 0
      src/views/manage/task/category/components/table.vue
  42. 43 7
      src/views/manage/task/category/index.vue

+ 33 - 0
src/api/model/article.js

@@ -0,0 +1,33 @@
+import config from "@/config"
+import http from "@/utils/request"
+
+export default {
+    list: {
+        url: `${config.API_URL}/article/list`,
+        name: "-",
+        get: async function(data={}){
+            return await http.get(this.url, data);
+        }
+    },
+    save: {
+        url: `${config.API_URL}/article/save`,
+        name: "-",
+        post: async function(data={}){
+            return await http.post(this.url, data);
+        }
+    },
+    del: {
+        url: `${config.API_URL}/article/del`,
+        name: "-",
+        post: async function(data={}){
+            return await http.post(this.url, data);
+        }
+    },
+    batch: {
+        url: `${config.API_URL}/article/batch`,
+        name: "-",
+        post: async function(data={}){
+            return await http.post(this.url, data);
+        }
+    },
+}

+ 33 - 0
src/api/model/category.js

@@ -0,0 +1,33 @@
+import config from "@/config"
+import http from "@/utils/request"
+
+export default {
+    list: {
+        url: `${config.API_URL}/category/list`,
+        name: "-",
+        get: async function(data={}){
+            return await http.get(this.url, data);
+        }
+    },
+    save: {
+        url: `${config.API_URL}/category/save`,
+        name: "-",
+        post: async function(data={}){
+            return await http.post(this.url, data);
+        }
+    },
+    batch: {
+        url: `${config.API_URL}/category/batch`,
+        name: "-",
+        post: async function(data={}){
+            return await http.post(this.url, data);
+        }
+    },
+    del: {
+        url: `${config.API_URL}/category/del`,
+        name: "-",
+        post: async function(data={}){
+            return await http.post(this.url, data);
+        }
+    },
+}

+ 0 - 33
src/api/model/combo.js

@@ -1,33 +0,0 @@
-import config from "@/config";
-import http from "@/utils/request";
-
-export default {
-    list: {
-        url: `${config.API_URL}/combo/list`,
-        name: "-",
-        get: async function (data = {}) {
-            return await http.get(this.url, data);
-        },
-    },
-    save: {
-        url: `${config.API_URL}/combo/save`,
-        name: "-",
-        post: async function (data = {}) {
-            return await http.post(this.url, data);
-        },
-    },
-    batch: {
-        url: `${config.API_URL}/combo/batch`,
-        name: "-",
-        post: async function (data = {}) {
-            return await http.post(this.url, data);
-        },
-    },
-    del: {
-        url: `${config.API_URL}/combo/del`,
-        name: "-",
-        post: async function (data = {}) {
-            return await http.post(this.url, data);
-        },
-    },
-}

+ 0 - 26
src/api/model/mDiscount.js

@@ -1,26 +0,0 @@
-import config from "@/config";
-import http from "@/utils/request";
-
-export default {
-    list: {
-        url: `${config.API_URL}/mer/discount/list`,
-        name: "-",
-        get: async function (params) {
-            return await http.get(this.url, params);
-        },
-    },
-    save: {
-        url: `${config.API_URL}/mer/discount/save`,
-        name: "-",
-        post: async function (params) {
-            return await http.post(this.url, params);
-        },
-    },
-    del: {
-        url: `${config.API_URL}/mer/discount/del`,
-        name: "-",
-        post: async function (params) {
-            return await http.post(this.url, params);
-        },
-    },
-}

+ 0 - 22
src/api/model/mMember.js

@@ -1,22 +0,0 @@
-import config from "@/config";
-import http from "@/utils/request";
-
-export default {
-    detail: {
-        url: `${config.API_URL}/mer/renew/detail`,
-        name: "-",
-        get: async function (params) {
-            return await http.get(this.url, params);
-        },
-    },
-    combo:{
-        url: `${config.API_URL}/mer/member/combo`,
-        name: "-",
-        get: async function (params) {
-            return await http.get(this.url, params);
-        },
-        post: async function (params) {
-            return await http.post(this.url, params);
-        },
-    },
-}

+ 0 - 61
src/api/model/mOrder.js

@@ -1,61 +0,0 @@
-import config from "@/config";
-import http from "@/utils/request";
-
-export default {
-    list: {
-        url: `${config.API_URL}/mer/order/list`,
-        name: "-",
-        get: async function (data = {}) {
-            return await http.get(this.url, data);
-        },
-    },
-    total: {
-        url: `${config.API_URL}/mer/order/total`,
-        name: "-",
-        get: async function (data = {}) {
-            return await http.get(this.url, data);
-        },
-    },
-    save: {
-        url: `${config.API_URL}/mer/order/save`,
-        name: "-",
-        post: async function (data = {}) {
-            return await http.post(this.url, data);
-        },
-    },
-    detail: {
-        url: `${config.API_URL}/mer/order/detail`,
-        name: "-",
-        post: async function (data = {}) {
-            return await http.post(this.url, data);
-        },
-    },
-    batch: {
-        url: `${config.API_URL}/mer/order/batch`,
-        name: "-",
-        post: async function (data = {}) {
-            return await http.post(this.url, data);
-        },
-    },
-    del: {
-        url: `${config.API_URL}/mer/order/del`,
-        name: "-",
-        post: async function (data = {}) {
-            return await http.post(this.url, data);
-        },
-    },
-    refund: {
-        url: `${config.API_URL}/mer/order/refund`,
-        name: "-",
-        post: async function (data = {}) {
-            return await http.post(this.url, data);
-        },
-    },
-    fail: {
-        url: `${config.API_URL}/mer/order/fail`,
-        name: "-",
-        post: async function (data = {}) {
-            return await http.post(this.url, data);
-        },
-    },
-}

+ 0 - 26
src/api/model/mPrice.js

@@ -1,26 +0,0 @@
-import config from "@/config";
-import http from "@/utils/request";
-
-export default {
-    list: {
-        url: `${config.API_URL}/mer/price/list`,
-        name: "-",
-        get: async function (params) {
-            return await http.get(this.url, params);
-        },
-    },
-    save: {
-        url: `${config.API_URL}/mer/price/save`,
-        name: "-",
-        post: async function (params) {
-            return await http.post(this.url, params);
-        },
-    },
-    del: {
-        url: `${config.API_URL}/mer/price/del`,
-        name: "-",
-        post: async function (params) {
-            return await http.post(this.url, params);
-        },
-    },
-}

+ 0 - 40
src/api/model/mPrint.js

@@ -1,40 +0,0 @@
-import config from "@/config";
-import http from "@/utils/request";
-
-export default {
-    list: {
-        url: `${config.API_URL}/mer/prints/list`,
-        name: "-",
-        get: async function (params) {
-            return await http.get(this.url, params);
-        },
-    },
-    save: {
-        url: `${config.API_URL}/mer/prints/save`,
-        name: "-",
-        post: async function (params) {
-            return await http.post(this.url, params);
-        },
-    },
-    single: {
-        url: `${config.API_URL}/mer/prints/single`,
-        name: "-",
-        post: async function (params) {
-            return await http.post(this.url, params);
-        },
-    },
-    qrcode: {
-        url: `${config.API_URL}/mer/prints/qrcode`,
-        name: "-",
-        post: async function (params) {
-            return await http.post(this.url, params);
-        },
-    },
-    price: {
-        url: `${config.API_URL}/mer/prints/price`,
-        name: "-",
-        get: async function (params) {
-            return await http.get(this.url, params);
-        },
-    },
-}

+ 0 - 47
src/api/model/mQrcode.js

@@ -1,47 +0,0 @@
-import config from "@/config";
-import http from "@/utils/request";
-
-export default {
-    list: {
-        url: `${config.API_URL}/mer/qrcode/list`,
-        name: "-",
-        get: async function (data = {}) {
-            return await http.get(this.url, data);
-        },
-    },
-    total: {
-        url: `${config.API_URL}/mer/qrcode/total`,
-        name: "-",
-        get: async function (data = {}) {
-            return await http.get(this.url, data);
-        },
-    },
-    today: {
-        url: `${config.API_URL}/mer/turnover/today`,
-        name: "-",
-        get: async function (data = {}) {
-            return await http.get(this.url, data);
-        },
-    },
-    detail: {
-        url: `${config.API_URL}/mer/order/detail`,
-        name: "-",
-        post: async function (data = {}) {
-            return await http.post(this.url, data);
-        },
-    },
-    batch: {
-        url: `${config.API_URL}/mer/order/batch`,
-        name: "-",
-        post: async function (data = {}) {
-            return await http.post(this.url, data);
-        },
-    },
-    del: {
-        url: `${config.API_URL}/mer/order/del`,
-        name: "-",
-        post: async function (data = {}) {
-            return await http.post(this.url, data);
-        },
-    },
-}

+ 0 - 47
src/api/model/mRenew.js

@@ -1,47 +0,0 @@
-import config from "@/config";
-import http from "@/utils/request";
-
-export default {
-    detail: {
-        url: `${config.API_URL}/mer/renew/detail`,
-        name: "-",
-        get: async function (params) {
-            return await http.get(this.url, params);
-        },
-    },
-    qrcode: {
-        url: `${config.API_URL}/mer/renew/qrcode`,
-        name: "-",
-        post: async function (params) {
-            return await http.post(this.url, params);
-        },
-    },
-    list: {
-        url: `${config.API_URL}/mer/renew/list`,
-        name: "-",
-        get: async function (params) {
-            return await http.get(this.url, params);
-        },
-    },
-    passwd: {
-        url: `${config.API_URL}/mer/staff/passwd`,
-        name: "-",
-        post: async function (params) {
-            return await http.post(this.url, params);
-        },
-    },
-    batch: {
-        url: `${config.API_URL}/mer/staff/batch`,
-        name: "-",
-        post: async function (params) {
-            return await http.post(this.url, params);
-        },
-    },
-    del: {
-        url: `${config.API_URL}/mer/staff/del`,
-        name: "-",
-        post: async function (params) {
-            return await http.post(this.url, params);
-        },
-    },
-}

+ 0 - 19
src/api/model/mShop.js

@@ -1,19 +0,0 @@
-import config from "@/config";
-import http from "@/utils/request";
-
-export default {
-    detail: {
-        url: `${config.API_URL}/mer/shop/detail`,
-        name: "-",
-        get: async function (params) {
-            return await http.get(this.url, params);
-        },
-    },
-    save: {
-        url: `${config.API_URL}/mer/shop/save`,
-        name: "-",
-        post: async function (params) {
-            return await http.post(this.url, params);
-        },
-    },
-}

+ 0 - 40
src/api/model/mStaff.js

@@ -1,40 +0,0 @@
-import config from "@/config";
-import http from "@/utils/request";
-
-export default {
-    list: {
-        url: `${config.API_URL}/mer/staff/list`,
-        name: "-",
-        get: async function (params) {
-            return await http.get(this.url, params);
-        },
-    },
-    save: {
-        url: `${config.API_URL}/mer/staff/save`,
-        name: "-",
-        post: async function (params) {
-            return await http.post(this.url, params);
-        },
-    },
-    passwd: {
-        url: `${config.API_URL}/mer/staff/passwd`,
-        name: "-",
-        post: async function (params) {
-            return await http.post(this.url, params);
-        },
-    },
-    batch: {
-        url: `${config.API_URL}/mer/staff/batch`,
-        name: "-",
-        post: async function (params) {
-            return await http.post(this.url, params);
-        },
-    },
-    del: {
-        url: `${config.API_URL}/mer/staff/del`,
-        name: "-",
-        post: async function (params) {
-            return await http.post(this.url, params);
-        },
-    },
-}

+ 0 - 26
src/api/model/mUser.js

@@ -1,26 +0,0 @@
-import config from "@/config";
-import http from "@/utils/request";
-
-export default {
-    list: {
-        url: `${config.API_URL}/mer/user/list`,
-        name: "-",
-        get: async function (params) {
-            return await http.get(this.url, params);
-        },
-    },
-    log: {
-        url: `${config.API_URL}/mer/userLog/list`,
-        name: "-",
-        get: async function (params) {
-            return await http.get(this.url, params);
-        },
-    },
-    save: {
-        url: `${config.API_URL}/mer/user/save`,
-        name: "-",
-        post: async function (params) {
-            return await http.post(this.url, params);
-        },
-    },
-}

+ 33 - 0
src/api/model/page.js

@@ -0,0 +1,33 @@
+import config from "@/config"
+import http from "@/utils/request"
+
+export default {
+    list: {
+        url: `${config.API_URL}/pages/list`,
+        name: "-",
+        get: async function(data={}){
+            return await http.get(this.url, data);
+        }
+    },
+    save: {
+        url: `${config.API_URL}/pages/save`,
+        name: "-",
+        post: async function(data={}){
+            return await http.post(this.url, data);
+        }
+    },
+    detail: {
+        url: `${config.API_URL}/pages/detail`,
+        name: "-",
+        get: async function(data={}){
+            return await http.get(this.url, data);
+        }
+    },
+    user: {
+        url: `${config.API_URL}/login/profile`,
+        name: "-",
+        get: async function(data={}){
+            return await http.get(this.url, data);
+        }
+    },
+}

+ 3 - 0
src/views/manage/expert/group/components/form.vue

@@ -0,0 +1,3 @@
+<template>
+
+</template>

+ 61 - 0
src/views/manage/expert/group/components/option.vue

@@ -0,0 +1,61 @@
+<template>
+    <fieldset>
+        <legend>
+            <el-tag type="info">按需操作</el-tag>
+        </legend>
+        <div class="op-header">
+            <div class="left-panel">
+                <el-button icon="el-icon-unlock" @click="table_batch_status(1)" :disabled="dataSelect.length>0?false:true">启用</el-button>
+                <el-button icon="el-icon-lock" type="danger" @click="table_batch_status(2)" :disabled="dataSelect.length>0?false:true">禁用</el-button>
+            </div>
+        </div>
+    </fieldset>
+    <formMain ref="formMain" @success="handleSuccess"></formMain>
+</template>
+
+<script>
+import formMain from './form';
+export default {
+    components: {
+        formMain
+    },
+    props: {
+        dataSelect: { type: Array, default: () => [] },
+        dataSelectFull: { type: Array, default: () => [] }
+    },
+    data(){
+        return {
+
+        }
+    },
+    methods: {
+        addData(){
+            this.$nextTick(() => {
+                this.$refs.formMain.open()
+            })
+        },
+        async table_batch_status(status){
+            if (this.dataSelect.length == 0) {
+                return this.$message.error("请选择修改数据")
+            }
+            var loading = this.$loading()
+            let submitData = {"id":this.dataSelect,"value":status,"field":"status","type":"batch"};
+            loading.close()
+            var resp = await this.$API.article.batch.post(submitData);
+            if (resp.code == 0) {
+                return this.$message.error(resp.msg);
+            }
+            this.$message.success(resp.msg);
+            this.$emit("success");
+        },
+        handleSuccess(){
+            this.$emit("success");
+        },
+        table_add(){
+            this.$nextTick(() => {
+                this.$refs.formMain.open("add")
+            })
+        },
+    }
+}
+</script>

+ 49 - 0
src/views/manage/expert/group/components/search.vue

@@ -0,0 +1,49 @@
+<template>
+    <fieldset>
+        <legend>
+            <el-tag type="info">条件筛选</el-tag>
+        </legend>
+        <el-form class="lv-form-inline" ref="searchForm" :model="searchKey" label-position="right" label-width="100px">
+            <div class="search-form">
+                <div class="form-left">
+                    <el-row :gutter="10">
+                        <el-col :xs="12" :sm="12" :md="12" :lg="6" :xl="4">
+                            <el-input v-model="searchKey.truename" placeholder="团长姓名" clearable :style="{ width: '100%' }" @keyup.enter="searchForm()">
+                                <template #prepend>团长姓名</template>
+                            </el-input>
+                        </el-col>
+                        <el-col :xs="12" :sm="12" :md="12" :lg="6" :xl="4">
+                            <el-select v-model="searchKey.status" clearable placeholder="请选择状态" @change="searchForm" :style="{width: '100%'}" class="diy-select">
+                                <el-option value="1" label="正常"></el-option>
+                                <el-option value="2" label="禁用"></el-option>
+                                <template #prefix>状态</template>
+                            </el-select>
+                        </el-col>
+                        <el-col :xs="12" :sm="6" :md="6" :lg="6" :xl="4">
+                            <el-date-picker v-model="searchKey.create" :style="{width: '100%'}" placeholder="请选择创建时间" start-placeholder="开始时间" end-placeholder="结束时间" type="daterange" range-separator="至" @change="searchForm" />
+                        </el-col>
+                    </el-row>
+                </div>
+                <div class="form-line"></div>
+                <div class="form-right">
+                    <el-button type="primary" icon="el-icon-search" @click="searchForm">搜索</el-button>
+                </div>
+            </div>
+        </el-form>
+    </fieldset>
+</template>
+
+<script>
+export default {
+    data(){
+        return {
+            searchKey:{}
+        }
+    },
+    methods: {
+        searchForm(){
+            this.$emit("success",this.searchKey);
+        }
+    }
+}
+</script>

+ 21 - 0
src/views/manage/expert/group/components/table.vue

@@ -0,0 +1,21 @@
+<template>
+    <scTable ref="table" :apiObj="list.apiObj" :params="searchKey" @selectionChange="selectionChange" row-key="id">
+        <el-table-column type="selection" width="50" fixed="left"></el-table-column>
+
+    </scTable>
+</template>
+
+<script>
+export default {
+    data(){
+        return {
+            list: {
+                apiObj: this.$API.article.list
+            },
+            dataSelect:[],
+            dataSelectFull:[],
+            searchKey:{}
+        }
+    },
+}
+</script>

+ 47 - 0
src/views/manage/expert/group/index.vue

@@ -0,0 +1,47 @@
+<template>
+    <el-container class="flex-column">
+        <div class="table-search">
+            <search @success="handleSuccess"></search>
+            <optionBtn @success="handleSuccess" :dataSelect="dataSelect" :dataSelectFull="dataSelectFull" type="3"></optionBtn>
+        </div>
+        <el-main class="nopadding">
+            <div class="table-container">
+                <tablePage ref="tablePage" @success="tableHandle" @successFull="tableHandleFull" type="3"></tablePage>
+            </div>
+        </el-main>
+    </el-container>  
+</template>
+
+<script>
+import search from './components/search';
+import optionBtn from './components/option';
+import tablePage from './components/table';
+export default {
+    components: {
+        search,tablePage,optionBtn
+    },
+    data(){
+        return {
+            searchKey:{},
+            dataSelect:[],
+            dataSelectFull:[],
+        }
+    },
+    methods: {
+        tableHandle(data){
+            this.dataSelect = data;
+        },
+        tableHandleFull(data){
+            this.dataSelectFull = data;
+        },
+        handleSuccess(data){
+            this.$refs.tablePage.upData(data)
+        },
+        handleClick(name){
+            this.activeName = name;
+            this.searchKey.type = name;
+            this.$refs.tablePage.upData(this.searchKey)
+        }
+    }
+}
+</script>

+ 3 - 0
src/views/manage/expert/index/components/form.vue

@@ -0,0 +1,3 @@
+<template>
+
+</template>

+ 61 - 0
src/views/manage/expert/index/components/option.vue

@@ -0,0 +1,61 @@
+<template>
+    <fieldset>
+        <legend>
+            <el-tag type="info">按需操作</el-tag>
+        </legend>
+        <div class="op-header">
+            <div class="left-panel">
+                <el-button icon="el-icon-unlock" @click="table_batch_status(1)" :disabled="dataSelect.length>0?false:true">启用</el-button>
+                <el-button icon="el-icon-lock" type="danger" @click="table_batch_status(2)" :disabled="dataSelect.length>0?false:true">禁用</el-button>
+            </div>
+        </div>
+    </fieldset>
+    <formMain ref="formMain" @success="handleSuccess"></formMain>
+</template>
+
+<script>
+import formMain from './form';
+export default {
+    components: {
+        formMain
+    },
+    props: {
+        dataSelect: { type: Array, default: () => [] },
+        dataSelectFull: { type: Array, default: () => [] }
+    },
+    data(){
+        return {
+
+        }
+    },
+    methods: {
+        addData(){
+            this.$nextTick(() => {
+                this.$refs.formMain.open()
+            })
+        },
+        async table_batch_status(status){
+            if (this.dataSelect.length == 0) {
+                return this.$message.error("请选择修改数据")
+            }
+            var loading = this.$loading()
+            let submitData = {"id":this.dataSelect,"value":status,"field":"status","type":"batch"};
+            loading.close()
+            var resp = await this.$API.article.batch.post(submitData);
+            if (resp.code == 0) {
+                return this.$message.error(resp.msg);
+            }
+            this.$message.success(resp.msg);
+            this.$emit("success");
+        },
+        handleSuccess(){
+            this.$emit("success");
+        },
+        table_add(){
+            this.$nextTick(() => {
+                this.$refs.formMain.open("add")
+            })
+        },
+    }
+}
+</script>

+ 49 - 0
src/views/manage/expert/index/components/search.vue

@@ -0,0 +1,49 @@
+<template>
+    <fieldset>
+        <legend>
+            <el-tag type="info">条件筛选</el-tag>
+        </legend>
+        <el-form class="lv-form-inline" ref="searchForm" :model="searchKey" label-position="right" label-width="100px">
+            <div class="search-form">
+                <div class="form-left">
+                    <el-row :gutter="10">
+                        <el-col :xs="12" :sm="12" :md="12" :lg="6" :xl="4">
+                            <el-input v-model="searchKey.truename" placeholder="达人姓名" clearable :style="{ width: '100%' }" @keyup.enter="searchForm()">
+                                <template #prepend>达人姓名</template>
+                            </el-input>
+                        </el-col>
+                        <el-col :xs="12" :sm="12" :md="12" :lg="6" :xl="4">
+                            <el-select v-model="searchKey.status" clearable placeholder="请选择状态" @change="searchForm" :style="{width: '100%'}" class="diy-select">
+                                <el-option value="1" label="正常"></el-option>
+                                <el-option value="2" label="禁用"></el-option>
+                                <template #prefix>状态</template>
+                            </el-select>
+                        </el-col>
+                        <el-col :xs="12" :sm="6" :md="6" :lg="6" :xl="4">
+                            <el-date-picker v-model="searchKey.create" :style="{width: '100%'}" placeholder="请选择创建时间" start-placeholder="开始时间" end-placeholder="结束时间" type="daterange" range-separator="至" @change="searchForm" />
+                        </el-col>
+                    </el-row>
+                </div>
+                <div class="form-line"></div>
+                <div class="form-right">
+                    <el-button type="primary" icon="el-icon-search" @click="searchForm">搜索</el-button>
+                </div>
+            </div>
+        </el-form>
+    </fieldset>
+</template>
+
+<script>
+export default {
+    data(){
+        return {
+            searchKey:{}
+        }
+    },
+    methods: {
+        searchForm(){
+            this.$emit("success",this.searchKey);
+        }
+    }
+}
+</script>

+ 21 - 0
src/views/manage/expert/index/components/table.vue

@@ -0,0 +1,21 @@
+<template>
+    <scTable ref="table" :apiObj="list.apiObj" :params="searchKey" @selectionChange="selectionChange" row-key="id">
+        <el-table-column type="selection" width="50" fixed="left"></el-table-column>
+
+    </scTable>
+</template>
+
+<script>
+export default {
+    data(){
+        return {
+            list: {
+                apiObj: this.$API.article.list
+            },
+            dataSelect:[],
+            dataSelectFull:[],
+            searchKey:{}
+        }
+    },
+}
+</script>

+ 43 - 7
src/views/manage/expert/index/index.vue

@@ -1,11 +1,47 @@
 <template>
-
+    <el-container class="flex-column">
+        <div class="table-search">
+            <search @success="handleSuccess"></search>
+            <optionBtn @success="handleSuccess" :dataSelect="dataSelect" :dataSelectFull="dataSelectFull" type="3"></optionBtn>
+        </div>
+        <el-main class="nopadding">
+            <div class="table-container">
+                <tablePage ref="tablePage" @success="tableHandle" @successFull="tableHandleFull" type="3"></tablePage>
+            </div>
+        </el-main>
+    </el-container>  
 </template>
 
 <script>
-
-</script>
-
-<style>
-
-</style>
+import search from './components/search';
+import optionBtn from './components/option';
+import tablePage from './components/table';
+export default {
+    components: {
+        search,tablePage,optionBtn
+    },
+    data(){
+        return {
+            searchKey:{},
+            dataSelect:[],
+            dataSelectFull:[],
+        }
+    },
+    methods: {
+        tableHandle(data){
+            this.dataSelect = data;
+        },
+        tableHandleFull(data){
+            this.dataSelectFull = data;
+        },
+        handleSuccess(data){
+            this.$refs.tablePage.upData(data)
+        },
+        handleClick(name){
+            this.activeName = name;
+            this.searchKey.type = name;
+            this.$refs.tablePage.upData(this.searchKey)
+        }
+    }
+}
+</script>

+ 93 - 0
src/views/manage/school/category/components/form.vue

@@ -0,0 +1,93 @@
+<template>
+    <el-dialog :title="titleMap[mode]" v-model="visible" :width="600" destroy-on-close @closed="$emit('closed')">
+        <el-form ref="dialogForm" :model="formData" :rules="rules" label-width="100px" label-position="top">
+            <el-form-item label="分类名称" prop="name">
+                <el-input v-model="formData.name" clearable placeholder="请输入"></el-input>
+                <div class="el-form-item-msg"></div>
+            </el-form-item>
+            <el-row :gutter="10">
+                <el-col :span="12">
+                    <el-form-item label="分类图标" prop="icon">
+                        <sc-upload v-model="formData.icon"></sc-upload>
+                        <div class="el-form-item-msg"></div>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="12">
+                    <el-form-item label="分类小图标" prop="small_icon">
+                        <sc-upload v-model="formData.small_icon"></sc-upload>
+                        <div class="el-form-item-msg"></div>
+                    </el-form-item>
+                </el-col>
+            </el-row>
+            <el-form-item label="状态" prop="status">
+                <el-radio-group v-model="formData.status">
+                    <el-radio-button :label="1">正常</el-radio-button>
+                    <el-radio-button :label="2">禁用</el-radio-button>
+                </el-radio-group>
+            </el-form-item>
+        </el-form>
+		<template #footer>
+            <el-button @click="visible=false" size="large">取 消</el-button>
+            <el-button v-if="mode!='show'" size="large" type="primary" :loading="isSaveing" @click="submit()">保 存</el-button>
+		</template>
+    </el-dialog>
+    
+</template>
+
+<script>
+export default {
+    data(){
+        return {
+            loading: false,
+            isSaveing: false,
+            mode:"add",
+            titleMap:{
+                add:"新增分类",
+                edit:"编辑分类"
+            },
+            visible:false,
+            formData:{},
+            rules:{
+                status: [
+                    {required: true, message: '请选择'}
+                ],
+                name: [
+                    {required: true, message: '请输入'}
+                ]
+            }
+        }
+    },
+    methods:{
+        open(mode = 'add'){
+            this.mode = mode;
+            this.visible = true;
+            return this
+        },
+        //表单注入数据
+        setData(data){
+            this.formData = JSON.parse(JSON.stringify(data));
+        },
+        async submit(){
+            var validate = await this.$refs.dialogForm.validate().catch(()=>{});
+            if(!validate){ return false }
+            this.isSaveing = true;
+            let submitData = JSON.parse(JSON.stringify(this.formData));
+            submitData.type = 2;
+            var resp = await this.$API.category.save.post(submitData);
+            this.isSaveing = false;
+            if (resp.code == 0) {
+                return this.$message.error(resp.msg);
+            }
+            this.$message.success(resp.msg);
+            this.visible = false;
+            this.formData = {};
+            this.submitState = false;
+            this.$emit("success");
+        }
+    }
+}
+</script>
+
+<style>
+.text-center{text-align: center;}
+</style>

+ 62 - 0
src/views/manage/school/category/components/option.vue

@@ -0,0 +1,62 @@
+<template>
+    <fieldset>
+        <legend>
+            <el-tag type="info">按需操作</el-tag>
+        </legend>
+        <div class="op-header">
+            <div class="left-panel">
+                <el-button icon="el-icon-plus" type="primary" @click="addData()">新增分类</el-button>
+                <el-button icon="el-icon-unlock" @click="table_batch_status(1)" :disabled="dataSelect.length>0?false:true">启用</el-button>
+                <el-button icon="el-icon-lock" type="danger" @click="table_batch_status(2)" :disabled="dataSelect.length>0?false:true">禁用</el-button>
+            </div>
+        </div>
+    </fieldset>
+    <formMain ref="formMain" @success="handleSuccess"></formMain>
+</template>
+
+<script>
+import formMain from './form';
+export default {
+    components: {
+        formMain
+    },
+    props: {
+        dataSelect: { type: Array, default: () => [] },
+        dataSelectFull: { type: Array, default: () => [] }
+    },
+    data(){
+        return {
+
+        }
+    },
+    methods: {
+        addData(){
+            this.$nextTick(() => {
+                this.$refs.formMain.open()
+            })
+        },
+        async table_batch_status(status){
+            if (this.dataSelect.length == 0) {
+                return this.$message.error("请选择修改数据")
+            }
+            var loading = this.$loading()
+            let submitData = {"id":this.dataSelect,"value":status,"field":"status","type":"batch"};
+            loading.close()
+            var resp = await this.$API.category.batch.post(submitData);
+            if (resp.code == 0) {
+                return this.$message.error(resp.msg);
+            }
+            this.$message.success(resp.msg);
+            this.$emit("success");
+        },
+        handleSuccess(){
+            this.$emit("success");
+        },
+        table_add(){
+            this.$nextTick(() => {
+                this.$refs.formMain.open("add")
+            })
+        },
+    }
+}
+</script>

+ 51 - 0
src/views/manage/school/category/components/search.vue

@@ -0,0 +1,51 @@
+<template>
+    <fieldset>
+        <legend>
+            <el-tag type="info">条件筛选</el-tag>
+        </legend>
+        <el-form class="lv-form-inline" ref="searchForm" :model="searchKey" label-position="right" label-width="100px">
+            <div class="search-form">
+                <div class="form-left">
+                    <el-row :gutter="10">
+                        <el-col :xs="12" :sm="12" :md="12" :lg="6" :xl="4">
+                            <el-input v-model="searchKey.name" placeholder="名称" clearable :style="{ width: '100%' }" @keyup.enter="searchForm()">
+                                <template #prepend>名称</template>
+                            </el-input>
+                        </el-col>
+                        <el-col :xs="12" :sm="12" :md="12" :lg="6" :xl="4">
+                            <el-select v-model="searchKey.status" clearable placeholder="请选择状态" @change="searchForm" :style="{width: '100%'}" class="diy-select">
+                                <el-option value="1" label="正常"></el-option>
+                                <el-option value="2" label="禁用"></el-option>
+                                <template #prefix>状态</template>
+                            </el-select>
+                        </el-col>
+                        <el-col :xs="12" :sm="6" :md="6" :lg="6" :xl="4">
+                            <el-date-picker v-model="searchKey.create" :style="{width: '100%'}" placeholder="请选择创建时间" start-placeholder="开始时间" end-placeholder="结束时间" type="daterange" range-separator="至" @change="searchForm" />
+                        </el-col>
+                    </el-row>
+                </div>
+                <div class="form-line"></div>
+                <div class="form-right">
+                    <el-button type="primary" icon="el-icon-search" @click="searchForm">搜索</el-button>
+                </div>
+            </div>
+        </el-form>
+    </fieldset>
+</template>
+
+<script>
+export default {
+    data(){
+        return {
+            searchKey:{
+                type:2
+            }
+        }
+    },
+    methods: {
+        searchForm(){
+            this.$emit("success",this.searchKey);
+        }
+    }
+}
+</script>

+ 108 - 0
src/views/manage/school/category/components/table.vue

@@ -0,0 +1,108 @@
+<template>
+    <scTable ref="table" :apiObj="list.apiObj" :params="searchKey" @selectionChange="selectionChange" row-key="id" hidePagination>
+        <el-table-column type="selection" width="50" fixed="left"></el-table-column>
+        <el-table-column label="序号" prop="id" width="100"></el-table-column>
+        <el-table-column label="分类名称" prop="name"></el-table-column>
+        <el-table-column label="状态" prop="status" align="center">
+            <template #default="scope">
+                <div class="status-success" v-if="scope.row.status==1"><sc-status-indicator type="success"></sc-status-indicator> 正常</div>
+                <div class="status-danger" v-if="scope.row.status==2"><sc-status-indicator type="danger"></sc-status-indicator> 禁用</div>
+            </template>
+        </el-table-column>
+        <el-table-column label="创建时间" prop="create_at" width="150"></el-table-column>
+        <el-table-column label="操作" width="140" align="left" fixed="right">
+            <template #default="scope">
+                <el-button-group>
+                    <el-button size="small" @click="table_view(scope.row)">编辑</el-button>
+                    <el-button type="danger" size="small" @click="table_del(scope.row)">删除</el-button>
+                </el-button-group>
+            </template>
+        </el-table-column>
+    </scTable>
+    <formMain ref="formMain" @success="handleSuccess"></formMain>
+</template>
+
+<script>
+import formMain from './form';
+export default {
+    components: {
+        formMain
+    },
+    data(){
+        return {
+            list: {
+                apiObj: this.$API.category.list
+            },
+            dataSelect:[],
+            dataSelectFull:[],
+            searchKey:{
+                type:2
+            }
+        }
+    },
+    
+    methods: {
+        table_auth(data){
+            this.$nextTick(() => {
+                this.$refs.comboMain.open("edit").setData(data)
+            })
+        },
+        table_view(data){
+            this.$nextTick(() => {
+                this.$refs.formMain.open("edit").setData(data)
+            })
+        },
+        table_del(data){
+            this.$confirm(`确定要执行删除吗`, '提示', {
+                type: 'warning'
+            }).then(async ()=>{
+                var resp = await this.$API.category.del.post({"id":data.id});
+                if (resp.code == 0) {
+                    return this.$message.error(resp.msg);
+                }
+                this.$message.success(resp.msg);
+                this.refresh()
+            }).catch(()=>{})
+        },
+        refresh(){
+            this.$refs.table.refresh()
+        },
+        upData(data){
+            this.$refs.table.upData(data)
+        },
+        handleSuccess(){
+            this.$refs.table.refresh()
+        },
+        sortChange(event){
+            if (event.order) {
+                var data = {
+                    "field":event.prop,
+                    "order":event.order
+                }
+                this.$refs.table.upData(data)
+            } else {
+                this.$refs.table.reload(this.searchKey)
+            }
+            return ;
+        },
+        selectionChange(event){
+            this.dataSelect = [];
+            var arr = [];
+            var arrCompany = [];
+            event.forEach(function(val,index){
+                arr[index] = val.id;
+                arrCompany[index] = val;
+            });
+            this.dataSelectFull = arrCompany;
+            this.dataSelect = arr;
+            this.$emit("success",this.dataSelect);
+            this.$emit("successFull",this.dataSelectFull);
+        },
+        table_passwd(row){
+            this.$nextTick(() => {
+                this.$refs.userPasswd.open("edit").setData(row)
+            })
+        }
+    }
+}
+</script>

+ 43 - 7
src/views/manage/school/category/index.vue

@@ -1,11 +1,47 @@
 <template>
-
+    <el-container class="flex-column">
+        <div class="table-search">
+            <search @success="handleSuccess"></search>
+            <optionBtn @success="handleSuccess" :dataSelect="dataSelect" :dataSelectFull="dataSelectFull" type="3"></optionBtn>
+        </div>
+        <el-main class="nopadding">
+            <div class="table-container">
+                <tablePage ref="tablePage" @success="tableHandle" @successFull="tableHandleFull" type="3"></tablePage>
+            </div>
+        </el-main>
+    </el-container>  
 </template>
 
 <script>
-
-</script>
-
-<style>
-
-</style>
+import search from './components/search';
+import optionBtn from './components/option';
+import tablePage from './components/table';
+export default {
+    components: {
+        search,tablePage,optionBtn
+    },
+    data(){
+        return {
+            searchKey:{},
+            dataSelect:[],
+            dataSelectFull:[],
+        }
+    },
+    methods: {
+        tableHandle(data){
+            this.dataSelect = data;
+        },
+        tableHandleFull(data){
+            this.dataSelectFull = data;
+        },
+        handleSuccess(data){
+            this.$refs.tablePage.upData(data)
+        },
+        handleClick(name){
+            this.activeName = name;
+            this.searchKey.type = name;
+            this.$refs.tablePage.upData(this.searchKey)
+        }
+    }
+}
+</script>

+ 153 - 0
src/views/manage/school/lists/components/form.vue

@@ -0,0 +1,153 @@
+<template>
+    <el-drawer :title="titleMap[mode]" :append-to-body="true" v-model="visible" :size="1000" destroy-on-close :close-on-click-modal="false" @closed="$emit('closed')" :with-header="false">
+        <el-container class="flex-column" v-loading="loading">
+            <div class="drawer-detail-main">
+                <div class="drawer-detail-header">
+                    <div class="drawer-detail-header-body">
+                        <div class="drawer-detail-header-left">{{ titleMap[mode] }}</div>
+                        <div class="drawer-detail-header-left">
+                            <el-button type="default" icon="el-icon-close" @click="visible=false"></el-button>
+                        </div>
+                    </div>
+                </div>
+            </div>
+            <el-main>
+                <el-form ref="dialogForm" :model="formData" :rules="rules" label-width="100px" label-position="top">
+                    <el-form-item label="文档标题" prop="title">
+                        <el-input v-model="formData.title" clearable placeholder="文档标题"></el-input>
+                        <div class="el-form-item-msg"></div>
+                    </el-form-item>
+                    <el-form-item label="副标题" prop="sub_title">
+                        <el-input v-model="formData.sub_title" clearable placeholder="副标题"></el-input>
+                        <div class="el-form-item-msg"></div>
+                    </el-form-item>
+                    <el-form-item label="栏目分类" prop="category_path">
+                        <el-cascader v-model="formData.category_path" :options="categoryData" :props="deptsProps" clearable style="width: 50%;" />
+                        <div class="el-form-item-msg"></div>
+                    </el-form-item>
+                    <el-form-item label="封面图片" prop="cover">
+                        <sc-upload v-model="formData.cover"></sc-upload>
+                        <div class="el-form-item-msg"></div>
+                    </el-form-item>
+                    <el-form-item label="文档属性" prop="attribute">
+                        <el-checkbox-group v-model="formData.attribute">
+                            <el-checkbox border :value="item.key" :label="item.key" v-for="(item,indx) in channelData" :key="indx">{{ item.name }}</el-checkbox>
+                        </el-checkbox-group>
+                        <div class="el-form-item-msg"></div>
+                    </el-form-item>
+                    <el-row :gutter="10">
+                        <el-col :span="8">
+                            <el-form-item label="浏览数" prop="view">
+                                <el-input v-model="formData.view" clearable placeholder="浏览数">
+                                    <template #append>次</template>
+                                </el-input>
+                                <div class="el-form-item-msg"></div>
+                            </el-form-item>
+                        </el-col>
+                        <el-col :span="8">
+                            <el-form-item label="作者" prop="author">
+                                <el-input v-model="formData.author" clearable placeholder="作者"></el-input>
+                                <div class="el-form-item-msg"></div>
+                            </el-form-item>
+                        </el-col>
+                        <el-col :span="8">
+                            <el-form-item label="来源" prop="source">
+                                <el-input v-model="formData.source" clearable placeholder="来源"></el-input>
+                                <div class="el-form-item-msg"></div>
+                            </el-form-item>
+                        </el-col>
+                    </el-row>
+                    <el-form-item label="内容" prop="content" class="label-item">
+                        <sc-editor v-model="formData.content" placeholder="请输入" :height="600" style="width: 100%;"></sc-editor>
+                        <div class="el-form-item-msg"></div>
+                    </el-form-item>
+                    
+                </el-form>
+            </el-main>
+            <el-footer style="text-align: right;">
+                <el-button @click="visible=false" >取 消</el-button>
+                <el-button v-if="mode!='show'" type="primary" :loading="isSaveing" @click="submit()">保 存</el-button>
+            </el-footer>
+        </el-container>
+    </el-drawer>
+</template>
+
+<script>
+import { defineAsyncComponent } from 'vue';
+const scEditor = defineAsyncComponent(() => import('@/components/scEditor'));
+export default {
+    components: {
+        scEditor
+    },
+    data() {
+        return {
+            categoryData:[],
+            deptsProps:{
+                value: "id",
+                label: "name"
+            },
+            channelData:[{key:1,name:"头条"},{key:2,name:"推荐"},{key:3,name:"加推"},{key:4,name:"标粗"},{key:5,name:"有图"}],
+            loading: false,
+            mode:"add",
+            visible: false,
+            isSaveing: false,
+            titleMap:{
+                add:"新增文章",
+                edit:"编辑文章"
+            },
+            rules:{
+                title: [
+                    {required: true, message: '请输入'}
+                ],
+                category_path: [
+                    {required: true, message: '请选择'}
+                ],
+                content: [
+                    {required: true, message: '请输入'}
+                ],
+            },
+            formData:{}
+        }
+    },
+    methods: {
+        open(mode = 'add'){
+            this.mode = mode;
+            this.visible = true;
+            this.getCategory()
+            if (mode == 'add') {
+                this.formData = {
+                    view:0,
+                    author:"小编",
+                    source:"网络"
+                };
+            }
+            return this
+        },
+        //表单注入数据
+        setData(data){
+            this.formData = JSON.parse(JSON.stringify(data));
+        },
+        async getCategory(){
+            var resp = await this.$API.category.list.get({"type":2});
+            if (resp.code == 0) {
+                return this.$message.error(resp.msg)
+            }
+            this.categoryData = resp.data;
+        },
+        async submit(){
+            var validate = await this.$refs.dialogForm.validate().catch(()=>{});
+            if(!validate){ return false }
+            this.isSaveing = true;
+            var resp = await this.$API.article.save.post(this.formData);
+            this.isSaveing = false;
+            if (resp.code == 0) {
+                return this.$message.error(resp.msg);
+            }
+            this.$message.success(resp.msg);
+            this.visible = false;
+            this.formData = {};
+            this.$emit("success");
+        }
+    }
+}
+</script>

+ 62 - 0
src/views/manage/school/lists/components/option.vue

@@ -0,0 +1,62 @@
+<template>
+    <fieldset>
+        <legend>
+            <el-tag type="info">按需操作</el-tag>
+        </legend>
+        <div class="op-header">
+            <div class="left-panel">
+                <el-button icon="el-icon-plus" type="primary" @click="addData()">新增文章</el-button>
+                <el-button icon="el-icon-unlock" @click="table_batch_status(1)" :disabled="dataSelect.length>0?false:true">启用</el-button>
+                <el-button icon="el-icon-lock" type="danger" @click="table_batch_status(2)" :disabled="dataSelect.length>0?false:true">禁用</el-button>
+            </div>
+        </div>
+    </fieldset>
+    <formMain ref="formMain" @success="handleSuccess"></formMain>
+</template>
+
+<script>
+import formMain from './form';
+export default {
+    components: {
+        formMain
+    },
+    props: {
+        dataSelect: { type: Array, default: () => [] },
+        dataSelectFull: { type: Array, default: () => [] }
+    },
+    data(){
+        return {
+
+        }
+    },
+    methods: {
+        addData(){
+            this.$nextTick(() => {
+                this.$refs.formMain.open()
+            })
+        },
+        async table_batch_status(status){
+            if (this.dataSelect.length == 0) {
+                return this.$message.error("请选择修改数据")
+            }
+            var loading = this.$loading()
+            let submitData = {"id":this.dataSelect,"value":status,"field":"status","type":"batch"};
+            loading.close()
+            var resp = await this.$API.article.batch.post(submitData);
+            if (resp.code == 0) {
+                return this.$message.error(resp.msg);
+            }
+            this.$message.success(resp.msg);
+            this.$emit("success");
+        },
+        handleSuccess(){
+            this.$emit("success");
+        },
+        table_add(){
+            this.$nextTick(() => {
+                this.$refs.formMain.open("add")
+            })
+        },
+    }
+}
+</script>

+ 49 - 0
src/views/manage/school/lists/components/search.vue

@@ -0,0 +1,49 @@
+<template>
+    <fieldset>
+        <legend>
+            <el-tag type="info">条件筛选</el-tag>
+        </legend>
+        <el-form class="lv-form-inline" ref="searchForm" :model="searchKey" label-position="right" label-width="100px">
+            <div class="search-form">
+                <div class="form-left">
+                    <el-row :gutter="10">
+                        <el-col :xs="12" :sm="12" :md="12" :lg="6" :xl="4">
+                            <el-input v-model="searchKey.title" placeholder="标题" clearable :style="{ width: '100%' }" @keyup.enter="searchForm()">
+                                <template #prepend>标题</template>
+                            </el-input>
+                        </el-col>
+                        <el-col :xs="12" :sm="12" :md="12" :lg="6" :xl="4">
+                            <el-select v-model="searchKey.status" clearable placeholder="请选择状态" @change="searchForm" :style="{width: '100%'}" class="diy-select">
+                                <el-option value="1" label="正常"></el-option>
+                                <el-option value="2" label="禁用"></el-option>
+                                <template #prefix>状态</template>
+                            </el-select>
+                        </el-col>
+                        <el-col :xs="12" :sm="6" :md="6" :lg="6" :xl="4">
+                            <el-date-picker v-model="searchKey.create" :style="{width: '100%'}" placeholder="请选择创建时间" start-placeholder="开始时间" end-placeholder="结束时间" type="daterange" range-separator="至" @change="searchForm" />
+                        </el-col>
+                    </el-row>
+                </div>
+                <div class="form-line"></div>
+                <div class="form-right">
+                    <el-button type="primary" icon="el-icon-search" @click="searchForm">搜索</el-button>
+                </div>
+            </div>
+        </el-form>
+    </fieldset>
+</template>
+
+<script>
+export default {
+    data(){
+        return {
+            searchKey:{}
+        }
+    },
+    methods: {
+        searchForm(){
+            this.$emit("success",this.searchKey);
+        }
+    }
+}
+</script>

+ 127 - 0
src/views/manage/school/lists/components/table.vue

@@ -0,0 +1,127 @@
+<template>
+    <scTable ref="table" :apiObj="list.apiObj" :params="searchKey" @selectionChange="selectionChange" row-key="id">
+        <el-table-column type="selection" width="50" fixed="left"></el-table-column>
+        <el-table-column label="ID" prop="id" width="100"></el-table-column>
+        <el-table-column label="标题" prop="title"></el-table-column>
+        <el-table-column label="栏目" prop="cate_name" width="160">
+            <template #default="scope">
+                <span v-if="scope.row.categoryJoin">{{ scope.row.categoryJoin.name }}</span>
+                <span v-else>-</span>
+            </template>
+        </el-table-column>
+        <el-table-column label="阅读" prop="view" width="120">
+            <template #default="scope">
+                {{ scope.row.view }}次
+            </template>
+        </el-table-column>
+        <el-table-column label="评论" prop="comment" width="120">
+            <template #default="scope">
+                {{ scope.row.comment }}条
+            </template>
+        </el-table-column>
+        <el-table-column label="点赞" prop="zan" width="120">
+            <template #default="scope">
+                {{ scope.row.zan }}次
+            </template>
+        </el-table-column>
+        <el-table-column label="状态" prop="status" width="120" align="center">
+            <template #default="scope">
+                <div class="status-success" v-if="scope.row.status==1"><sc-status-indicator type="success"></sc-status-indicator> 正常</div>
+                <div class="status-danger" v-if="scope.row.status==2"><sc-status-indicator type="danger"></sc-status-indicator> 禁用</div>
+            </template>
+        </el-table-column>
+        <el-table-column label="创建时间" prop="create_at" width="160"></el-table-column>
+        <el-table-column label="操作" width="140" align="left" fixed="right">
+            <template #default="scope">
+                <el-button-group>
+                    <el-button size="small" @click="table_view(scope.row)">编辑</el-button>
+                    <el-button type="danger" size="small" @click="table_del(scope.row)">删除</el-button>
+                </el-button-group>
+            </template>
+        </el-table-column>
+    </scTable>
+    <formMain ref="formMain" @success="handleSuccess"></formMain>
+</template>
+
+<script>
+import formMain from './form';
+export default {
+    components: {
+        formMain
+    },
+    data(){
+        return {
+            list: {
+                apiObj: this.$API.article.list
+            },
+            dataSelect:[],
+            dataSelectFull:[],
+            searchKey:{}
+        }
+    },
+    
+    methods: {
+        table_auth(data){
+            this.$nextTick(() => {
+                this.$refs.comboMain.open("edit").setData(data)
+            })
+        },
+        table_view(data){
+            this.$nextTick(() => {
+                this.$refs.formMain.open("edit").setData(data)
+            })
+        },
+        table_del(data){
+            this.$confirm(`确定要执行删除吗`, '提示', {
+                type: 'warning'
+            }).then(async ()=>{
+                var resp = await this.$API.article.del.post({"id":data.id});
+                if (resp.code == 0) {
+                    return this.$message.error(resp.msg);
+                }
+                this.$message.success(resp.msg);
+                this.refresh()
+            }).catch(()=>{})
+        },
+        refresh(){
+            this.$refs.table.refresh()
+        },
+        upData(data){
+            this.$refs.table.upData(data)
+        },
+        handleSuccess(){
+            this.$refs.table.refresh()
+        },
+        sortChange(event){
+            if (event.order) {
+                var data = {
+                    "field":event.prop,
+                    "order":event.order
+                }
+                this.$refs.table.upData(data)
+            } else {
+                this.$refs.table.reload(this.searchKey)
+            }
+            return ;
+        },
+        selectionChange(event){
+            this.dataSelect = [];
+            var arr = [];
+            var arrCompany = [];
+            event.forEach(function(val,index){
+                arr[index] = val.id;
+                arrCompany[index] = val;
+            });
+            this.dataSelectFull = arrCompany;
+            this.dataSelect = arr;
+            this.$emit("success",this.dataSelect);
+            this.$emit("successFull",this.dataSelectFull);
+        },
+        table_passwd(row){
+            this.$nextTick(() => {
+                this.$refs.userPasswd.open("edit").setData(row)
+            })
+        }
+    }
+}
+</script>

+ 43 - 7
src/views/manage/school/lists/index.vue

@@ -1,11 +1,47 @@
 <template>
-
+    <el-container class="flex-column">
+        <div class="table-search">
+            <search @success="handleSuccess"></search>
+            <optionBtn @success="handleSuccess" :dataSelect="dataSelect" :dataSelectFull="dataSelectFull" type="3"></optionBtn>
+        </div>
+        <el-main class="nopadding">
+            <div class="table-container">
+                <tablePage ref="tablePage" @success="tableHandle" @successFull="tableHandleFull" type="3"></tablePage>
+            </div>
+        </el-main>
+    </el-container>  
 </template>
 
 <script>
-
-</script>
-
-<style>
-
-</style>
+import search from './components/search';
+import optionBtn from './components/option';
+import tablePage from './components/table';
+export default {
+    components: {
+        search,tablePage,optionBtn
+    },
+    data(){
+        return {
+            searchKey:{},
+            dataSelect:[],
+            dataSelectFull:[],
+        }
+    },
+    methods: {
+        tableHandle(data){
+            this.dataSelect = data;
+        },
+        tableHandleFull(data){
+            this.dataSelectFull = data;
+        },
+        handleSuccess(data){
+            this.$refs.tablePage.upData(data)
+        },
+        handleClick(name){
+            this.activeName = name;
+            this.searchKey.type = name;
+            this.$refs.tablePage.upData(this.searchKey)
+        }
+    }
+}
+</script>

+ 0 - 13
src/views/manage/setting/basic/index.vue

@@ -24,14 +24,6 @@
                                 <el-input v-model="sys.copyright" placeholder="请输入" clearable />
                                 <div class="el-form-item-msg"></div>
                             </el-form-item>
-                            <el-form-item label="隐私协议" prop="privacy" class="label-item">
-                                <sc-editor v-model="sys.privacy" placeholder="请输入" :height="400"></sc-editor>
-                                <div class="el-form-item-msg"></div>
-                            </el-form-item>
-                            <el-form-item label="服务协议" prop="agreements" class="label-item">
-                                <sc-editor v-model="sys.agreements" placeholder="请输入" :height="400"></sc-editor>
-                                <div class="el-form-item-msg"></div>
-                            </el-form-item>
                         </el-form>
                     </el-tab-pane>
                     <el-tab-pane label="微信设置" name="wechat" v-loading="isLoading">
@@ -88,12 +80,7 @@
     </el-container>
 </template>
 <script>
-import { defineAsyncComponent } from 'vue';
-const scEditor = defineAsyncComponent(() => import('@/components/scEditor'));
 export default {
-    components: {
-        scEditor
-    },
     data(){
         return {
             activeName:"service",

+ 112 - 0
src/views/manage/setting/page/form.vue

@@ -0,0 +1,112 @@
+<template>
+    <el-drawer :title="titleMap[mode]" :append-to-body="true" v-model="visible" :size="1000" destroy-on-close :close-on-click-modal="false" @closed="$emit('closed')" :with-header="false">
+        <el-container class="flex-column" v-loading="loading">
+            <div class="drawer-detail-main">
+                <div class="drawer-detail-header">
+                    <div class="drawer-detail-header-body">
+                        <div class="drawer-detail-header-left">{{ titleMap[mode] }}</div>
+                        <div class="drawer-detail-header-left">
+                            <el-button type="default" icon="el-icon-close" @click="visible=false"></el-button>
+                        </div>
+                    </div>
+                </div>
+            </div>
+            <el-main>
+                <el-form ref="dialogForm" :model="formData" :rules="rules" label-width="100px" label-position="top">
+                    <template v-if="mode=='add'">
+                        <el-form-item label="单页名称" prop="desc">
+                            <el-input v-model="formData.desc" clearable placeholder="单页名称"></el-input>
+                            <div class="el-form-item-msg"></div>
+                        </el-form-item>
+                        <el-form-item label="单页标识" prop="name">
+                            <el-input v-model="formData.name" clearable placeholder="单页名称"></el-input>
+                            <div class="el-form-item-msg"></div>
+                        </el-form-item>
+                    </template>
+                    <template v-if="mode=='edit'">
+                        <el-form-item label="单页名称" prop="desc">
+                            <el-input v-model="formData.desc" readonly placeholder="单页名称"></el-input>
+                            <div class="el-form-item-msg"></div>
+                        </el-form-item>
+                    </template>
+                    <el-form-item label="单页内容" prop="value" class="label-item">
+                        <sc-editor v-model="formData.value" placeholder="请输入" :height="500" style="width: 100%;"></sc-editor>
+                        <div class="el-form-item-msg"></div>
+                    </el-form-item>
+                    
+                </el-form>
+            </el-main>
+            <el-footer style="text-align: right;">
+                <el-button @click="visible=false" >取 消</el-button>
+                <el-button v-if="mode!='show'" type="primary" :loading="isSaveing" @click="submit()">保 存</el-button>
+            </el-footer>
+        </el-container>
+    </el-drawer>
+</template>
+
+<script>
+import { defineAsyncComponent } from 'vue';
+const scEditor = defineAsyncComponent(() => import('@/components/scEditor'));
+export default {
+    components: {
+        scEditor
+    },
+    data() {
+        return {
+            loading: false,
+            mode:"add",
+            visible: false,
+            isSaveing: false,
+            titleMap:{
+                add:"新增单页",
+                edit:"编辑单页"
+            },
+            rules:{
+                name: [
+                    {required: true, message: '请输入'}
+                ],
+                desc: [
+                    {required: true, message: '请输入'}
+                ],
+                value: [
+                    {required: true, message: '请输入'}
+                ],
+            },
+            formData:{}
+        }
+    },
+    methods: {
+        open(mode = 'add'){
+            this.mode = mode;
+            this.visible = true;
+            return this
+        },
+        //表单注入数据
+        setData(data){
+            this.formData = JSON.parse(JSON.stringify(data));
+            this.getPageDetail();
+        },
+        async getPageDetail(){
+            var resp = await this.$API.page.detail.get({"name":this.formData.name});
+            if (resp.code == 0) {
+                return this.$message.error(resp.msg)
+            }
+            this.formData = resp.data;
+        },
+        async submit(){
+            var validate = await this.$refs.dialogForm.validate().catch(()=>{});
+            if(!validate){ return false }
+            this.isSaveing = true;
+            var resp = await this.$API.page.save.post(this.formData);
+            this.isSaveing = false;
+            if (resp.code == 0) {
+                return this.$message.error(resp.msg);
+            }
+            this.$message.success(resp.msg);
+            this.visible = false;
+            this.formData = {};
+            this.$emit("success");
+        }
+    }
+}
+</script>

+ 65 - 2
src/views/manage/setting/page/index.vue

@@ -1,13 +1,76 @@
 <template>
-    
+    <el-container v-loading="pageLoad">
+        <el-main>
+            <el-row :gutter="10">
+                <el-col :span="6" v-for="(item,index) in dataList" :key="index">
+                    <el-card shadow="never">
+                        <div class="card-body">
+                            <div class="card-name">{{ item.desc }}</div>
+                            <div class="card-edit" @click="editPage(item)">
+                                <el-button size="small" text>编辑</el-button>
+                            </div>
+                        </div>
+                    </el-card>
+                </el-col>
+                <el-col :span="6">
+                    <el-card shadow="never">
+                        <div class="card-body">
+                            <div class="card-add" @click="addPage">
+                                <el-icon size="36"><el-icon-plus /></el-icon>
+                            </div>
+                        </div>
+                    </el-card>
+                </el-col>
+            </el-row>
+        </el-main>
+    </el-container>
+    <formBody ref="formBody" @success="handleSuccess"></formBody>
 </template>
 
 <script>
+import formBody from './form'
 export default {
+    components: {
+        formBody
+    },
     data() {
         return {
+            pageLoad:false,
+            dataList:[]
+        }
+    },
+    mounted(){
+        this.getPage()
+    },
+    methods: {
+        handleSuccess(){
 
+        },
+        editPage(data){
+            this.$nextTick(() => {
+                this.$refs.formBody.open("edit").setData(data);
+            })
+        },
+        addPage(){
+            this.$nextTick(() => {
+                this.$refs.formBody.open("add")
+            })
+        },
+        async getPage(){
+            this.pageLoad = true;
+            var resp = await this.$API.page.list.get();
+            this.pageLoad = false;
+            if (resp.code == 0) {
+                return this.$message.error(resp.msg)
+            }
+            this.dataList = resp.data;
         }
     }
 }
-</script>
+</script>
+
+<style>
+.card-body{height: 120px;}
+.card-name{font-size: 18px;font-weight: bold;min-height: 100px;}
+.card-add{display: flex;align-items: center;justify-content: center;flex: 1;height: 100%;}
+</style>

+ 93 - 0
src/views/manage/task/category/components/form.vue

@@ -0,0 +1,93 @@
+<template>
+    <el-dialog :title="titleMap[mode]" v-model="visible" :width="600" destroy-on-close @closed="$emit('closed')">
+        <el-form ref="dialogForm" :model="formData" :rules="rules" label-width="100px" label-position="top">
+            <el-form-item label="分类名称" prop="name">
+                <el-input v-model="formData.name" clearable placeholder="请输入"></el-input>
+                <div class="el-form-item-msg"></div>
+            </el-form-item>
+            <el-row :gutter="10">
+                <el-col :span="12">
+                    <el-form-item label="分类图标" prop="icon">
+                        <sc-upload v-model="formData.icon"></sc-upload>
+                        <div class="el-form-item-msg"></div>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="12">
+                    <el-form-item label="分类小图标" prop="small_icon">
+                        <sc-upload v-model="formData.small_icon"></sc-upload>
+                        <div class="el-form-item-msg"></div>
+                    </el-form-item>
+                </el-col>
+            </el-row>
+            <el-form-item label="状态" prop="status">
+                <el-radio-group v-model="formData.status">
+                    <el-radio-button :label="1">正常</el-radio-button>
+                    <el-radio-button :label="2">禁用</el-radio-button>
+                </el-radio-group>
+            </el-form-item>
+        </el-form>
+		<template #footer>
+            <el-button @click="visible=false" size="large">取 消</el-button>
+            <el-button v-if="mode!='show'" size="large" type="primary" :loading="isSaveing" @click="submit()">保 存</el-button>
+		</template>
+    </el-dialog>
+    
+</template>
+
+<script>
+export default {
+    data(){
+        return {
+            loading: false,
+            isSaveing: false,
+            mode:"add",
+            titleMap:{
+                add:"新增分类",
+                edit:"编辑分类"
+            },
+            visible:false,
+            formData:{},
+            rules:{
+                status: [
+                    {required: true, message: '请选择'}
+                ],
+                name: [
+                    {required: true, message: '请输入'}
+                ]
+            }
+        }
+    },
+    methods:{
+        open(mode = 'add'){
+            this.mode = mode;
+            this.visible = true;
+            return this
+        },
+        //表单注入数据
+        setData(data){
+            this.formData = JSON.parse(JSON.stringify(data));
+        },
+        async submit(){
+            var validate = await this.$refs.dialogForm.validate().catch(()=>{});
+            if(!validate){ return false }
+            this.isSaveing = true;
+            let submitData = JSON.parse(JSON.stringify(this.formData));
+            submitData.type = 1;
+            var resp = await this.$API.category.save.post(submitData);
+            this.isSaveing = false;
+            if (resp.code == 0) {
+                return this.$message.error(resp.msg);
+            }
+            this.$message.success(resp.msg);
+            this.visible = false;
+            this.formData = {};
+            this.submitState = false;
+            this.$emit("success");
+        }
+    }
+}
+</script>
+
+<style>
+.text-center{text-align: center;}
+</style>

+ 62 - 0
src/views/manage/task/category/components/option.vue

@@ -0,0 +1,62 @@
+<template>
+    <fieldset>
+        <legend>
+            <el-tag type="info">按需操作</el-tag>
+        </legend>
+        <div class="op-header">
+            <div class="left-panel">
+                <el-button icon="el-icon-plus" type="primary" @click="addData()">新增分类</el-button>
+                <el-button icon="el-icon-unlock" @click="table_batch_status(1)" :disabled="dataSelect.length>0?false:true">启用</el-button>
+                <el-button icon="el-icon-lock" type="danger" @click="table_batch_status(2)" :disabled="dataSelect.length>0?false:true">禁用</el-button>
+            </div>
+        </div>
+    </fieldset>
+    <formMain ref="formMain" @success="handleSuccess"></formMain>
+</template>
+
+<script>
+import formMain from './form';
+export default {
+    components: {
+        formMain
+    },
+    props: {
+        dataSelect: { type: Array, default: () => [] },
+        dataSelectFull: { type: Array, default: () => [] }
+    },
+    data(){
+        return {
+
+        }
+    },
+    methods: {
+        addData(){
+            this.$nextTick(() => {
+                this.$refs.formMain.open()
+            })
+        },
+        async table_batch_status(status){
+            if (this.dataSelect.length == 0) {
+                return this.$message.error("请选择修改数据")
+            }
+            var loading = this.$loading()
+            let submitData = {"id":this.dataSelect,"value":status,"field":"status","type":"batch"};
+            loading.close()
+            var resp = await this.$API.category.batch.post(submitData);
+            if (resp.code == 0) {
+                return this.$message.error(resp.msg);
+            }
+            this.$message.success(resp.msg);
+            this.$emit("success");
+        },
+        handleSuccess(){
+            this.$emit("success");
+        },
+        table_add(){
+            this.$nextTick(() => {
+                this.$refs.formMain.open("add")
+            })
+        },
+    }
+}
+</script>

+ 51 - 0
src/views/manage/task/category/components/search.vue

@@ -0,0 +1,51 @@
+<template>
+    <fieldset>
+        <legend>
+            <el-tag type="info">条件筛选</el-tag>
+        </legend>
+        <el-form class="lv-form-inline" ref="searchForm" :model="searchKey" label-position="right" label-width="100px">
+            <div class="search-form">
+                <div class="form-left">
+                    <el-row :gutter="10">
+                        <el-col :xs="12" :sm="12" :md="12" :lg="6" :xl="4">
+                            <el-input v-model="searchKey.name" placeholder="名称" clearable :style="{ width: '100%' }" @keyup.enter="searchForm()">
+                                <template #prepend>名称</template>
+                            </el-input>
+                        </el-col>
+                        <el-col :xs="12" :sm="12" :md="12" :lg="6" :xl="4">
+                            <el-select v-model="searchKey.status" clearable placeholder="请选择状态" @change="searchForm" :style="{width: '100%'}" class="diy-select">
+                                <el-option value="1" label="正常"></el-option>
+                                <el-option value="2" label="禁用"></el-option>
+                                <template #prefix>状态</template>
+                            </el-select>
+                        </el-col>
+                        <el-col :xs="12" :sm="6" :md="6" :lg="6" :xl="4">
+                            <el-date-picker v-model="searchKey.create" :style="{width: '100%'}" placeholder="请选择创建时间" start-placeholder="开始时间" end-placeholder="结束时间" type="daterange" range-separator="至" @change="searchForm" />
+                        </el-col>
+                    </el-row>
+                </div>
+                <div class="form-line"></div>
+                <div class="form-right">
+                    <el-button type="primary" icon="el-icon-search" @click="searchForm">搜索</el-button>
+                </div>
+            </div>
+        </el-form>
+    </fieldset>
+</template>
+
+<script>
+export default {
+    data(){
+        return {
+            searchKey:{
+                type:1
+            }
+        }
+    },
+    methods: {
+        searchForm(){
+            this.$emit("success",this.searchKey);
+        }
+    }
+}
+</script>

+ 108 - 0
src/views/manage/task/category/components/table.vue

@@ -0,0 +1,108 @@
+<template>
+    <scTable ref="table" :apiObj="list.apiObj" :params="searchKey" @selectionChange="selectionChange" row-key="id" hidePagination>
+        <el-table-column type="selection" width="50" fixed="left"></el-table-column>
+        <el-table-column label="序号" prop="id" width="100"></el-table-column>
+        <el-table-column label="分类名称" prop="name"></el-table-column>
+        <el-table-column label="状态" prop="status" align="center">
+            <template #default="scope">
+                <div class="status-success" v-if="scope.row.status==1"><sc-status-indicator type="success"></sc-status-indicator> 正常</div>
+                <div class="status-danger" v-if="scope.row.status==2"><sc-status-indicator type="danger"></sc-status-indicator> 禁用</div>
+            </template>
+        </el-table-column>
+        <el-table-column label="创建时间" prop="create_at" width="150"></el-table-column>
+        <el-table-column label="操作" width="140" align="left" fixed="right">
+            <template #default="scope">
+                <el-button-group>
+                    <el-button size="small" @click="table_view(scope.row)">编辑</el-button>
+                    <el-button type="danger" size="small" @click="table_del(scope.row)">删除</el-button>
+                </el-button-group>
+            </template>
+        </el-table-column>
+    </scTable>
+    <formMain ref="formMain" @success="handleSuccess"></formMain>
+</template>
+
+<script>
+import formMain from './form';
+export default {
+    components: {
+        formMain
+    },
+    data(){
+        return {
+            list: {
+                apiObj: this.$API.category.list
+            },
+            dataSelect:[],
+            dataSelectFull:[],
+            searchKey:{
+                type:1
+            }
+        }
+    },
+    
+    methods: {
+        table_auth(data){
+            this.$nextTick(() => {
+                this.$refs.comboMain.open("edit").setData(data)
+            })
+        },
+        table_view(data){
+            this.$nextTick(() => {
+                this.$refs.formMain.open("edit").setData(data)
+            })
+        },
+        table_del(data){
+            this.$confirm(`确定要执行删除吗`, '提示', {
+                type: 'warning'
+            }).then(async ()=>{
+                var resp = await this.$API.category.del.post({"id":data.id});
+                if (resp.code == 0) {
+                    return this.$message.error(resp.msg);
+                }
+                this.$message.success(resp.msg);
+                this.$emit("success");
+            }).catch(()=>{})
+        },
+        refresh(){
+            this.$refs.table.refresh()
+        },
+        upData(data){
+            this.$refs.table.upData(data)
+        },
+        handleSuccess(){
+            this.$refs.table.refresh()
+        },
+        sortChange(event){
+            if (event.order) {
+                var data = {
+                    "field":event.prop,
+                    "order":event.order
+                }
+                this.$refs.table.upData(data)
+            } else {
+                this.$refs.table.reload(this.searchKey)
+            }
+            return ;
+        },
+        selectionChange(event){
+            this.dataSelect = [];
+            var arr = [];
+            var arrCompany = [];
+            event.forEach(function(val,index){
+                arr[index] = val.id;
+                arrCompany[index] = val;
+            });
+            this.dataSelectFull = arrCompany;
+            this.dataSelect = arr;
+            this.$emit("success",this.dataSelect);
+            this.$emit("successFull",this.dataSelectFull);
+        },
+        table_passwd(row){
+            this.$nextTick(() => {
+                this.$refs.userPasswd.open("edit").setData(row)
+            })
+        }
+    }
+}
+</script>

+ 43 - 7
src/views/manage/task/category/index.vue

@@ -1,11 +1,47 @@
 <template>
-
+    <el-container class="flex-column">
+        <div class="table-search">
+            <search @success="handleSuccess"></search>
+            <optionBtn @success="handleSuccess" :dataSelect="dataSelect" :dataSelectFull="dataSelectFull" type="3"></optionBtn>
+        </div>
+        <el-main class="nopadding">
+            <div class="table-container">
+                <tablePage ref="tablePage" @success="tableHandle" @successFull="tableHandleFull" type="3"></tablePage>
+            </div>
+        </el-main>
+    </el-container>  
 </template>
 
 <script>
-
-</script>
-
-<style>
-
-</style>
+import search from './components/search';
+import optionBtn from './components/option';
+import tablePage from './components/table';
+export default {
+    components: {
+        search,tablePage,optionBtn
+    },
+    data(){
+        return {
+            searchKey:{},
+            dataSelect:[],
+            dataSelectFull:[],
+        }
+    },
+    methods: {
+        tableHandle(data){
+            this.dataSelect = data;
+        },
+        tableHandleFull(data){
+            this.dataSelectFull = data;
+        },
+        handleSuccess(data){
+            this.$refs.tablePage.upData(data)
+        },
+        handleClick(name){
+            this.activeName = name;
+            this.searchKey.type = name;
+            this.$refs.tablePage.upData(this.searchKey)
+        }
+    }
+}
+</script>