Browse Source

#13606, #13608 Site Label and Article Management

vbea 2 years ago
parent
commit
fe3d187932

+ 46 - 38
Strides-Admin/src/api/article.js

@@ -1,41 +1,49 @@
-import request from '@/utils/request'
+import {get, post, put, del} from '../http/http'
+import {uploadImage} from '../http/api/upload'
 
-export function fetchList(query) {
-  return request({
-    url: '/vue-element-admin/article/list',
-    method: 'get',
-    params: query
-  })
+const article = {
+  getArticleTypeOption() {
+    return get("article/article-type-select")
+  },
+  getArticleTypePages(params) {
+    return post("article/article-type-pages", params)
+  },
+  addArticleType(data) {
+    return post("article/article-types", data)
+  },
+  updateArticleType(data) {
+    return put("article/article-types", data)
+  },
+  viewArticleType(articleTypeId) {
+    return get("article/article-types/" + articleTypeId)
+  },
+  deleteArticleType(articleTypeId) {
+    return del("article/article-types/" + articleTypeId)
+  },
+  getArticlePages(params) {
+    return post("article/article-pages", params)
+  },
+  addArticle(data) {
+    return post("article/articles", data)
+  },
+  updateArticle(data) {
+    return put("article/articles", data)
+  },
+  viewArticle(articleId) {
+    return get("article/articles/" + articleId)
+  },
+  deleteArticle(articleId) {
+    return del("article/articles/" + articleId)
+  },
+  deleteArticleImage(imageId) {
+    return del("article/article-images/" + imageId)
+  },
+  deleteArticleLink(linkId) {
+    return del("article/article-links/" + linkId)
+  },
+  uploadImages(data) {
+    return uploadImage(data)
+  }
 }
 
-export function fetchArticle(id) {
-  return request({
-    url: '/vue-element-admin/article/detail',
-    method: 'get',
-    params: { id }
-  })
-}
-
-export function fetchPv(pv) {
-  return request({
-    url: '/vue-element-admin/article/pv',
-    method: 'get',
-    params: { pv }
-  })
-}
-
-export function createArticle(data) {
-  return request({
-    url: '/vue-element-admin/article/create',
-    method: 'post',
-    data
-  })
-}
-
-export function updateArticle(data) {
-  return request({
-    url: '/vue-element-admin/article/update',
-    method: 'post',
-    data
-  })
-}
+export default article;

+ 46 - 0
Strides-Admin/src/api/campaign.js

@@ -0,0 +1,46 @@
+import {get, post, put, del} from '../http/http'
+import {uploadImage} from '../http/api/upload'
+
+const campaign = {
+  getCampaignPages(params) {
+    return post("campaign/campaign-pages", params)
+  },
+  addCampaign(data) {
+    return post("campaign/campaigns", data)
+  },
+  updateCampaign(data) {
+    return put("campaign/campaigns", data)
+  },
+  viewCampaign(campaignId) {
+    return get("campaign/campaigns/" + campaignId)
+  },
+  deleteCampaign(campaignId) {
+    return del("campaign/campaigns/" + campaignId)
+  },
+  deleteCampaignImage(imageId) {
+    return del("campaign/campaigns-images/" + imageId)
+  },
+  deleteCampaignLink(linkId) {
+    return del("campaign/campaigns-links/" + linkId)
+  },
+  deleteCampaignDiscount(linkId) {
+    return del("campaign/campaigns-discounts/" + linkId)
+  },
+  getAssignStatusOptions() {
+    return get("campaign/assignment-statuses")
+  },
+  getCampaignAssignPages(params) {
+    return post("campaign/assign-site-pages", params)
+  },
+  assignSites(data) {
+    return post("campaign/assign-sites", data)
+  },
+  unassignSites(data) {
+    return post("campaign/un-assign-sites", data)
+  },
+  uploadImages(data) {
+    return uploadImage(data)
+  }
+}
+
+export default campaign;

+ 0 - 8
Strides-Admin/src/api/qiniu.js

@@ -1,8 +0,0 @@
-import request from '@/utils/request'
-
-export function getToken() {
-  return request({
-    url: '/qiniu/upload/token', // 假地址 自行替换
-    method: 'get'
-  })
-}

+ 2 - 2
Strides-Admin/src/http/api/provider.js

@@ -1,5 +1,5 @@
 import {get, post} from '../http'
-import {uploadImage} from './upload'
+import {uploadImage, uploadImageOld} from './upload'
 
 const provider = {
   addServiceProvider: (params) => {
@@ -21,7 +21,7 @@ const provider = {
     return get('serviceProvider/getAllServiceProviderList', params)
   },
   uploadLogo: (data) => {
-    return uploadImage(data, "SERVICE_LOGO")
+    return uploadImageOld(data, "SERVICE_LOGO")
   }
 }
 

+ 5 - 1
Strides-Admin/src/http/api/upload.js

@@ -1,5 +1,9 @@
 import {upload} from '../http'
 
-export function uploadImage(form, type) {
+export function uploadImage(form) {
+  return upload('picture/obs-upload', form)
+}
+
+export function uploadImageOld(form, type) {
   return upload('picture/upload', form, {photoSubDir: type})
 }

+ 3 - 0
Strides-Admin/src/icons/svg/marketing-mgmt.svg

@@ -0,0 +1,3 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M19.6 10.8594V13.3906H24V10.8594H19.6ZM17.4 19.2252C18.456 20.1238 19.831 21.3134 20.92 22.25C21.36 21.5792 21.8 20.8958 22.24 20.225C21.151 19.2884 19.776 18.0988 18.72 17.1875C18.28 17.8709 17.84 18.5544 17.4 19.2252ZM22.24 4.025C21.8 3.35422 21.36 2.67078 20.92 2C19.831 2.93656 18.456 4.12625 17.4 5.0375C17.84 5.70828 18.28 6.39172 18.72 7.0625C19.776 6.15125 21.151 4.97422 22.24 4.025ZM4.2 8.32813C2.99 8.32813 2 9.46719 2 10.8594V13.3906C2 14.7828 2.99 15.9219 4.2 15.9219H5.3V20.9844H7.5V15.9219H8.6L14.1 19.7188V4.53125L8.6 8.32813H4.2ZM16.85 12.125C16.85 10.4417 16.212 8.92297 15.2 7.88516V16.3522C16.212 15.327 16.85 13.8083 16.85 12.125Z" fill="black"/>
+</svg>

+ 8 - 0
Strides-Admin/src/main.js

@@ -10,6 +10,7 @@ import './icons' // icon
 import './router/permission' // permission control
 import vueWaves from '@/directive/waves'
 import locale from 'element-ui/lib/locale/lang/en'
+import {baseURL} from './http/http'
 
 Vue.use(ElementUI, { locale })
 Vue.use(vueWaves)
@@ -24,6 +25,13 @@ Vue.prototype.$openRoute = (route, isResult) => {
     window.open(location.origin + location.pathname + sharpe + route);
   }
 }
+Vue.prototype.$imageSrc = (url) => {
+  if (url.indexOf('http') >= 0) {
+    return url;
+  } else {
+    return baseURL + url;
+  }
+}
 
 new Vue({
   el: '#app',

+ 88 - 0
Strides-Admin/src/router/MarketingRouter.js

@@ -0,0 +1,88 @@
+import Layout from '@/layout'
+
+export default {
+  path: '/marketing-management',
+  redirect: '/marketing-management/article',
+  component: Layout,
+  alwaysShow: true,
+  meta: {
+    title: 'Marketing Management',
+    icon: 'marketing-mgmt',
+    activeIcon: 'marketing-mgmt',
+    affix: true
+  },
+  children: [
+    {
+      path: '/marketing-management/article',
+      component: () => import('@/views/article/index'),
+      name: 'article-management',
+      meta: {
+        title: 'Articles',
+        icon: 'sidebar-submenu-item',
+        activeIcon: 'sidebar-submenu-item-active'
+      }
+    },
+    {
+      path: '/marketing-management/article-types',
+      component: () => import('@/views/article/typeList'),
+      name: 'article-types',
+      meta: {
+        title: 'Article Types',
+        icon: 'sidebar-submenu-item',
+        activeIcon: 'sidebar-submenu-item-active'
+      },
+      hidden: true
+    },
+    {
+      path: '/marketing-management/article/create',
+      component: () => import('@/views/article/detail'),
+      name: 'article-management-add',
+      meta: {
+        title: 'Create',
+        activeMenu: '/marketing-management/article'
+      },
+      hidden: true
+    },
+    {
+      path: '/marketing-management/article/update/:id',
+      component: () => import('@/views/article/detail'),
+      name: 'article-management-update',
+      meta: {
+        title: 'Update',
+        activeMenu: '/marketing-management/article'
+      },
+      hidden: true
+    },
+    {
+      path: '/marketing-management/campaign',
+      component: () => import('@/views/campaign/index'),
+      name: 'campaign-management',
+      meta: {
+        title: 'Campaigns',
+        icon: 'sidebar-submenu-item',
+        activeIcon: 'sidebar-submenu-item-active'
+        //activeMenu: '/campaign-management'
+      }
+    },
+    {
+      path: '/marketing-management/campaign/create',
+      component: () => import('@/views/campaign/detail'),
+      name: 'campaign-management-add',
+      meta: {
+        title: 'Create',
+        activeMenu: '/marketing-management/campaign'
+      },
+      hidden: true
+    },
+    {
+      path: '/marketing-management/campaign/update/:id',
+      component: () => import('@/views/campaign/detail'),
+      name: 'campaign-management-update',
+      meta: {
+        title: 'Update',
+        activeMenu: '/marketing-management/campaign'
+      },
+      hidden: true
+    },
+  ]
+}

+ 2 - 0
Strides-Admin/src/router/index.js

@@ -16,6 +16,7 @@ import NotificationRouter from './NotificationRouter'
 import AccessRouter from './AccessRouter'
 import SettingsRouter from './SettingsRouter'
 import additionalRoute from './addition'
+import MarketingRouter from './MarketingRouter'
 
 Vue.use(VueRouter)
 
@@ -112,6 +113,7 @@ const constantRoutes = [
   OCPPRouter,
   ...ReportsRouter,
   NotificationRouter,
+  MarketingRouter,
   PartnershipRouter,
   AccessRouter,
   ...additionalRoute,

+ 10 - 1
Strides-Admin/src/views/access/DialogDetail.vue

@@ -79,7 +79,8 @@
           label="ROLE:">
           <el-select
             v-model="form.roleName"
-            class="flex-item">
+            class="flex-item"
+            @change="changeRole">
             <el-option
               v-for="(item, index) in roleOptions"
               :key="index"
@@ -330,6 +331,14 @@ export default {
         this.initial = false;
       })
     },
+    changeRole() {
+      this.form.providerPk = ""
+      this.form.groupPk = ""
+      this.form.sitePks = []
+      this.$nextTick(() => {
+        this.$refs['acsForm'].clearValidate();
+      })
+    },
     onFormSave() {
       this.$refs['acsForm'].validate((valid) => {
         if (valid) {

+ 557 - 0
Strides-Admin/src/views/article/detail.vue

@@ -0,0 +1,557 @@
+<template>
+  <div class="container" v-loading="loading">
+    <el-form
+      :model="form"
+      :rules="rules"
+      ref="form"
+      label-position="right"
+      label-width="118px">
+      <div class="flexr">
+        <div class="content flex1">
+          <div class="section-title">Article Detail</div>
+          <el-form-item
+            prop="articleTypeId"
+            label="Article Type:">
+            <el-select
+              v-model="form.articleTypeId"
+              class="add-text"
+              placeholder="">
+              <el-option
+                v-for="(item,index) in options.type"
+                :key="index"
+                :label="item.name"
+                :value="item.value"/>
+            </el-select>
+          </el-form-item>
+          <el-form-item
+            prop="articleTitle"
+            label="Article Title:">
+            <el-input
+              v-model="form.articleTitle"
+              class="add-text"
+              placeholder=""
+              maxlength="100"/>
+          </el-form-item>
+          <!-- <el-form-item
+            label="Posted Date:"
+            v-if="isEdit">
+            <el-input
+              v-model="form.createTime"
+              class="add-text"
+              readonly/>
+          </el-form-item> -->
+          <el-form-item
+            prop="articleContent"
+            label=""
+            label-width="0">
+            <label
+              class="el-form-item__label"
+              style="width: 118px;">Article Content:</label>
+            <el-input
+              v-model="form.articleContent"
+              class="area-text"
+              type="textarea"
+              placeholder=""
+              maxlength="5000"
+              :autosize="autoSize"/>
+          </el-form-item>
+        </div>
+        <div class="content flex1">
+          <div class="section-title">Images & Links</div>
+          <el-form-item
+            label=""
+            label-width="0">
+            <label
+              class="el-form-item__label"
+              style="float: none;">Photos (Max 4 photos and 2mb each)</label>
+            <div class="flexcr">
+              <el-upload
+                class="logo-upload"
+                action
+                :limit="1"
+                :show-file-list="false"
+                :file-list="[]"
+                :http-request="file => uploadImages(file, index)"
+                accept=".jpg,.jpeg,.png,.gif,.JPG,.JPEG"
+                v-loading="item.loading"
+                v-for="(item, index) in images">
+                <div class="uploader-image" v-if="item.articleImagePath">
+                  <el-image
+                    :src="$imageSrc(item.articleImagePath)"
+                    title="Click to update image"/>
+                  <i
+                    title="Click to delete image"
+                    class="uploader-del el-icon-delete"
+                    @click.stop="deleteImages(index)"></i>
+                </div>
+                <i v-else
+                  class="el-icon-plus avatar-uploader-icon"
+                  title="Click to select file"/>
+              </el-upload>
+            </div>
+          </el-form-item>
+          <el-form-item
+            label=""
+            label-width="0">
+            <label
+              class="el-form-item__label"
+              style="float: none;">LINKS:</label>
+            <div style="max-width: 600px; display: grid;">
+              <el-table
+                class="article-links-table no-border"
+                :data="form.articleLinks">
+                <el-table-column
+                  label="Name Of Link"
+                  min-width="120px">
+                  <template slot-scope="{row}">
+                    <el-input
+                      v-model="row.articleLinkName"
+                      maxlength="100"/>
+                  </template>
+                </el-table-column>
+                <el-table-column
+                  label="Hyperlink"
+                  min-width="130px">
+                  <template slot-scope="{row}">
+                    <el-input
+                      v-model="row.articleLink"
+                      maxlength="150"/>
+                  </template>
+                </el-table-column>
+                <el-table-column
+                  label=""
+                  width="90px">
+                  <template slot-scope="{row,$index}">
+                    <div class="flexc" v-loading="row.loading">
+                      <i
+                        class="list-item-icon el-icon-remove-outline"
+                        style="color: #ED3F3F;"
+                        @click="onRemoveLink($index)"/>
+                      <i
+                        v-if="$index === form.articleLinks.length - 1"
+                        class="list-item-icon el-icon-circle-plus-outline"
+                        style="color: #82CF08;"
+                        @click="addLinkObj"/>
+                    </div>
+                  </template>
+                </el-table-column>
+              </el-table>
+            </div>
+          </el-form-item>
+        </div>
+      </div>
+      <div class="content flexcr">
+        <div class="buttons">
+          <el-button
+            @click="onClickCancel"
+            type="primary"
+            class="cancel-button">
+            Cancel
+          </el-button>
+          <el-button
+            @click="onClickSave"
+            type="primary">
+            Save
+          </el-button>
+        </div>
+        <div
+          class="update-by"
+          v-if="isEdit">
+          <span
+            class="add-text"
+            :title='"CREATED BY " + form.createdBy + " ON " + form.createdOn'>
+            LAST UPDATED BY {{form.updatedBy}} TIMESTAMP: {{form.updatedOn}}
+          </span>
+        </div>
+      </div>
+    </el-form>
+  </div>
+</template>
+
+<script>
+import api from '../../api/article.js'
+export default {
+  data() {
+    return {
+      loading: false,
+      form: {
+        articleTypeId: "",
+        articleTitle: "",
+        articleContent: "",
+        articleImagePaths: [],
+        articleLinks: [],
+        createTime: ""
+      },
+      options: {
+        type: []
+      },
+      images: [{
+        articleImagePath: "",
+        loading: false
+      }],
+      isEdit: false,
+      rules: {
+        articleTypeId: [{
+          message: "Please select article type",
+          trigger: "change",
+          required: true,
+        }],
+        articleTitle: [{
+          message: "Please input article title",
+          trigger: "blur",
+          required: true,
+        }],
+        articleContent: [{
+          message: "Please input article content",
+          trigger: "blur",
+          required: true,
+        }],
+      },
+      autoSize: {
+        minRows: 20,
+        maxRows: 50
+      }
+    };
+  },
+  created() {
+    this.loading = true;
+    this.addLinkObj();
+    if (this.$route.params.id) {
+      this.isEdit = true;
+    }
+    this.getArticleTypeOptions();
+  },
+  methods: {
+    onClickCancel() {
+      this.$nextTick(() => {
+        this.$router.replace({
+          path: "/marketing-management/article"
+        })
+      })
+    },
+    getArticleTypeOptions() {
+      api.getArticleTypeOption().then(res => {
+        this.options.type = res.data;
+      }).catch(err => {
+        this.$message.error(err);
+      }).finally(() => {
+        if (this.isEdit) {
+          this.getArticleDetail()
+        } else {
+          this.loading = false;
+        }
+      });
+    },
+    getArticleDetail() {
+      api.viewArticle(this.$route.params.id).then(res => {
+        if (res.data) {
+          this.form = res.data
+          this.images = []
+          this.form.articleImagePaths.forEach(item => {
+            this.images.push({
+              ...item,
+              loading: false
+            })
+          })
+          this.addImageObj();
+        }
+      }).catch(err => {
+        this.$message.error(err)
+      }).finally(() => {
+        this.loading = false;
+      })
+    },
+    addImageObj() {
+      if (this.images.length < 4) {
+        this.images.push({
+          articleImagePath: "",
+          loading: false
+        })
+      }
+    },
+    uploadImages(file, index) {
+      this.images[index].loading = true;
+      const formData = new FormData()
+      formData.append('file', file.file)
+      api.uploadImages(formData).then(res => {
+        if (res.data.picturePath) {
+          if (!this.images[index].articleImagePath) {
+            this.addImageObj();
+          }
+          this.images[index].articleImagePath = res.data.picturePath
+        }
+      }).catch(err => {
+        this.$message({
+          message: err,
+          type: 'error'
+        })
+      }).finally(() => {
+        this.images[index].loading = false;
+      })
+    },
+    deleteImages(index) {
+      const item = this.images[index];
+      if (item.articleImageId) {
+        this.$confirm('Confirm delete?', 'Delete', {
+          confirmButtonText: 'Confirm',
+          cancelButtonText: 'Cancel',
+          type: 'warning'
+        }).then(res => {
+          this.deleteImageById(item.articleImageId, index);
+        })
+      } else {
+        this.images.splice(index, 1);
+        this.addImageObj()
+      }
+    },
+    deleteImageById(id, index) {
+      this.images[index].loading = true;
+      api.deleteArticleImage(id).then(res => {
+        this.images.splice(index, 1);
+        this.addImageObj()
+      }).catch(err => {
+        this.$message({
+          message: err,
+          type: 'error'
+        })
+        this.images[index].loading = false;
+      })
+    },
+    addLinkObj() {
+      this.form.articleLinks.push({
+        loading: false,
+        articleLink: "",
+        articleLinkName: ""
+      })
+    },
+    onRemoveLink(index) {
+      const item = this.form.articleLinks[index];
+      if (item.articleLinkId) {
+        this.$confirm('Confirm delete?', 'Delete', {
+          confirmButtonText: 'Confirm',
+          cancelButtonText: 'Cancel',
+          type: 'warning'
+        }).then(res => {
+          this.deleteLinkById(item.articleLinkId, index);
+        })
+      } else {
+        this.form.articleLinks.splice(index, 1);
+        if (this.form.articleLinks.length == 0) {
+          this.addLinkObj()
+        }
+      }
+    },
+    deleteLinkById(id, index) {
+      this.form.articleLinks[index].loading = true;
+      api.deleteArticleLink(id).then(res => {
+        this.form.articleLinks.splice(index, 1);
+        if (this.form.articleLinks.length == 0) {
+          this.addLinkObj()
+        }
+      }).catch(err => {
+        this.$message({
+          message: err,
+          type: 'error'
+        })
+        this.form.articleLinks[index].loading = false;
+      })
+    },
+    onClickSave() {
+      this.$refs['form'].validate((valid) => {
+        if (valid) {
+          const images = this.images.filter(item => item.articleImagePath)
+          if (images.length == 0) {
+            this.$message({
+              message: "Please upload at least one image",
+              type: 'error'
+            })
+            return;
+          }
+          const links = this.form.articleLinks.filter(item => item.articleLinkName);
+          if (links.length == 0) {
+            this.$message({
+              message: "Please add at least one link",
+              type: 'error'
+            })
+            return;
+          }
+          const params = {
+            ...this.form,
+            articleLinks: links,
+            articleImagePaths: images
+          }
+          this.loading = true;
+          this.isEdit ? this.updateArticle(params) : this.addArticle(params);
+        }
+      })
+    },
+    addArticle(params) {
+      api.addArticle(params).then(res => {
+        this.$message({
+          type: 'success',
+          message: "Add successfully"
+        });
+        this.onClickCancel();
+      }).catch(err => {
+        this.loading = false;
+        this.$message({
+          type: 'error',
+          message: err
+        })
+      });
+    },
+    updateArticle(params) {
+      api.updateArticle(params).then(res => {
+        this.$message({
+          type: 'success',
+          message: "Update successfully"
+        });
+        this.onClickCancel();
+      }).catch(err => {
+        this.loading = false;
+        this.$message({
+          type: 'error',
+          message: err
+        })
+      });
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+  @import '../../styles/variables.scss';
+  .container {
+    width: 100%;
+    padding: 20px 60px;
+    min-height: $mainAppMinHeight;
+    background-color: #F0F5FC;
+  }
+  .content {
+    min-width: 400px;
+    margin: 0 8px 16px;
+    padding: 15px 60px;
+    border-radius: 6px;
+    background-color: white;
+  }
+  
+  .section-title {
+    color: #333;
+    margin-top: 20px;
+    margin-bottom: 30px;
+    font-size: 15px;
+    user-select: none;
+    line-height: 24px;
+    font-weight: bold;
+    font-family: sans-serif;
+    text-transform: uppercase;
+  }
+  .add-text {
+    width: 100%;
+    min-width: 200px;
+  }
+  
+  .area-text {
+    width: 100%;
+    min-width: 200px;
+  }
+  
+  .add-text ::v-deep .el-textarea__inner,
+  .area-text ::v-deep .el-textarea__inner {
+    font-family: sans-serif;
+  }
+  
+  .hr {
+    height: 2px;
+    margin: 10px -40px;
+    background-color: #F0F5FC;
+  }
+  .buttons {
+    padding-top: 15px;
+    padding-bottom: 15px;
+  }
+  @media screen and (max-width: 500px) {
+    .container {
+      padding: 0px;
+    }
+    .content {
+      padding: 15px 30px;
+    }
+  }
+  .logo-upload {
+    width: 148px;
+    height: 148px;
+    position: relative;
+    margin-right: 15px;
+    margin-bottom: 15px;
+    ::v-deep .el-image {
+      width: 148px;
+      height: 148px;
+      border-radius: 6px;
+    }
+  }
+  
+  .avatar-uploader-icon {
+    width: 148px;
+    height: 148px;
+    color: #8c939d;
+    cursor: pointer;
+    font-size: 28px;
+    text-align: center;
+    line-height: 148px;
+    border-radius: 6px;
+    border: 1px dashed #d9d9d9;
+  }
+  
+  .uploader-image {
+    width: 148px;
+    height: 148px;
+    text-align: left;
+    position: relative;
+  }
+  
+  .uploader-image ::v-deep img {
+    object-fit: cover;
+  }
+  
+  .uploader-del {
+    right: 4px;
+    bottom: 4px;
+    color: #fff;
+    padding: 5px;
+    display: none;
+    border-radius: 30px;
+    position: absolute;
+    background-color: rgba(1,1,1,.4);
+  }
+  
+  .uploader-image:hover .uploader-del {
+    display: block;
+  }
+  
+  .article-links-table ::v-deep .el-table__header th {
+    color: #606266;
+    border: none;
+    padding: 10px 0 0;
+    font-weight: normal;
+    background: transparent;
+  }
+  .article-links-table ::v-deep td {
+    border: none;
+    padding: 1px 0;
+    background: #fff !important;
+  }
+  .article-links-table ::v-deep .cell {
+    padding: 0px 8px 10px;
+  }
+  .list-item-icon {
+    height: 30px;
+    cursor: pointer;
+    font-size: 26px;
+    font-weight: 500;
+    line-height: 30px;
+  }
+  .list-item-icon + .list-item-icon {
+    margin-left: 15px;
+  }
+</style>

+ 232 - 0
Strides-Admin/src/views/article/index.vue

@@ -0,0 +1,232 @@
+<template>
+  <div class="app-container">
+    <div class="filter-container">
+      <div class="filter-view">
+        <el-select
+          class="filter-input"
+          placeholder="All Status"
+          clearable
+          @change="onClickSearch"
+          v-model="filters.pageVo.dataStatus">
+          <el-option
+            v-for="(item,index) in options.status"
+            :key="index"
+            :label="item.name"
+            :value="item.value"/>
+        </el-select>
+        <el-select
+          class="filter-input"
+          @change="onClickSearch"
+          placeholder="All Article Type"
+          v-model="filters.pageVo.articleTypeId"
+          clearable>
+          <el-option
+            v-for="(item,index) in options.types"
+            :key="index"
+            :label="item.name"
+            :value="item.value"/>
+        </el-select>
+        <div
+          class="filter-flex-button"
+          v-if="!$route.meta.onlyView">
+          <el-button
+            icon="el-icon-plus"
+            type="primary"
+            @click="onClickAdd">
+            Create
+          </el-button>
+        </div>
+      </div>
+    </div>
+    <el-table
+      v-loading="loading"
+      :data="table.list">
+      <el-table-column
+        align="center"
+        label="Article ID"
+        prop="userPk"
+        min-width="120">
+        <template slot-scope="{row}" >
+          <span
+            class="link-type"
+            @click="onClickEdit(row)"
+            v-if="!$route.meta.onlyView">
+            {{ row.articleId }}
+          </span>
+          <span v-else>{{ row.articleId }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column
+        align="center"
+        label="Title"
+        prop="articleTitle"
+        min-width="150"/>
+      <el-table-column
+        align="center"
+        label="Article Type"
+        prop="articleTypeName"
+        min-width="100"/>
+      <el-table-column
+        align="center"
+        label="Posted By"
+        prop="createBy"
+        min-width="120"/>
+      <el-table-column
+        align="center"
+        label="Posted Date"
+        prop="createTime"
+        min-width="120"/>
+      <el-table-column
+        align="center"
+        label="Views"
+        prop="views"
+        min-width="80"/>
+      <el-table-column
+        align="center"
+        label="Status"
+        prop="dataStatus"
+        min-width="80"/>
+      <el-table-column
+        align="center"
+        label="Action"
+        min-width="120"
+        v-if="!$route.meta.onlyView">
+        <template v-slot="{ row }">
+          <TableAction
+            @edit="onClickEdit(row)"
+            @delete="onClickDelete(row)"
+            v-if="row.dataStatus != 'Inactive'"/>
+        </template>
+      </el-table-column>
+    </el-table>
+    <div class="right">
+      <pagination
+        v-show="table.total > 0"
+        :total="table.total"
+        :page.sync="filters.pageNo"
+        :limit.sync="filters.pageSize"
+        @pagination="getTableData" />
+    </div>
+  </div>
+</template>
+
+<script>
+import TableAction from '@/components/TableAction.vue'
+import Pagination from '@/components/Pagination'
+import charge from '../../http/api/charge'
+import api from '../../api/article.js'
+export default {
+  data() {
+    return {
+      loading: false,
+      filters: {
+        pageNo: 1,
+        pageSize: 10,
+        pageVo: {
+          criteria: "",
+          dataStatus: "",
+          articleTypeId: ""
+        }
+      },
+      table: {
+        list: [],
+        total: 0
+      },
+      options: {
+        status: [],
+        types: []
+      }
+    };
+  },
+  components: { Pagination, TableAction },
+  created() {
+    this.getStatusOptions();
+    this.onClickSearch();
+  },
+  methods: {
+    onClickSearch() {
+      this.filters.pageNo = 1
+      this.getTableData()
+    },
+    getStatusOptions() {
+      charge.getStatusOptions().then(res => {
+        this.options.status = res.data;
+      }).catch(err => {
+        this.$message.error(err);
+      }).finally(() => {
+        this.getArticleTypeOptions()
+      });
+    },
+    getArticleTypeOptions() {
+      api.getArticleTypeOption().then(res => {
+        this.options.types = res.data;
+      }).catch(err => {
+        this.$message.error(err);
+      });
+    },
+    getTableData() {
+      this.loading = true;
+      api.getArticlePages(this.filters).then(res => {
+        if (res.data && res.total) {
+          this.table.total = res.total;
+          this.table.list = res.data;
+        } else {
+          this.table.total = 0;
+          this.table.list = [];
+        }
+      }).catch(err => {
+        this.$message({
+          type: 'error',
+          message: err
+        })
+        this.table.total = 0;
+        this.table.list = [];
+      }).finally(() => {
+        this.loading = false;
+      })
+    },
+    onClickAdd() {
+      this.$router.push({
+        path: "/marketing-management/article/create"
+      })
+    },
+    onClickEdit(row) {
+      this.$router.push({
+        path: "/marketing-management/article/update/" + row.articleId
+      })
+    },
+    onClickDelete(row) {
+      this.$confirm('Are you sure you want to delete this article?', 'Delete', {
+        confirmButtonText: 'OK',
+        cancelButtonText: 'Cancel',
+        type: 'warning'
+      }).then(res => {
+        this.onDeleteArticle(row.articleId)
+      })
+    },
+    onDeleteArticle(id) {
+      this.loading = true;
+      api.deleteArticle(id).then(res => {
+        this.$message({
+          type: 'success',
+          message: "Delete success."
+        })
+        this.getTableData()
+      }).catch(err => {
+        this.$message({
+          type: 'error',
+          message: err
+        })
+        this.loading = false;
+      })
+    }
+  }
+}
+</script>
+
+<style scoped>
+.filter-input {
+  min-width: 100px;
+  max-width: 300px;
+}
+</style>

+ 190 - 0
Strides-Admin/src/views/article/typeDetail.vue

@@ -0,0 +1,190 @@
+<template>
+  <el-dialog
+    class="dialog-article-type"
+    :visible="visible"
+    :before-close="e => hideDialog(false)"
+    :title="isEdit ? 'Edit Article Type' : 'Add Article Type'">
+    <el-form
+      ref="attForm"
+      :model="form"
+      :rules="rules"
+      label-position="top"
+      v-loading="initial">
+      <div class="form-row">
+        <el-form-item
+          prop="articleTypeName"
+          class="form-item"
+          label="Type Name:">
+          <el-input
+            v-model="form.articleTypeName"
+            class="flex-item"
+            maxlength="30"/>
+        </el-form-item>
+      </div>
+      <div class="flexcc" style="margin-top: 80px;">
+        <el-button
+          class="button"
+          type="primary"
+          :loading="loading"
+          @click="onFormSave">
+          <span style="padding: 0 20px;">SAVE</span>
+        </el-button>
+      </div>
+    </el-form>
+  </el-dialog>
+</template>
+
+<script>
+import api from '../../api/article.js'
+export default {
+  name: "ArticleTypeDialog",
+  props: {
+    visible: {
+      type: Boolean,
+      default: false
+    },
+    isEdit: {
+      type: Boolean,
+      default: false
+    },
+    id: {
+      type: String|Number,
+      default: ''
+    }
+  },
+  data() {
+    return {
+      initial: false,
+      loading: false,
+      form: {
+        articleTypeName: ""
+      },
+      rules: {
+        articleTypeName: {
+          required: true,
+          message: "Type Name is required",
+          trigger: "blur"
+        }
+      }
+    };
+  },
+  watch: {
+    id(n, o) {
+      if (this.visible && n) {
+        this.$nextTick(() => {
+          this.getTypeDetail();
+        })
+      }
+    }
+  },
+  methods: {
+    init() {
+      this.form = {
+        articleTypeId: "",
+        articleTypeName: ""
+      }
+      this.loading = false;
+      this.$nextTick(() => {
+        if (this.$refs['attForm']) {
+          this.$refs['attForm'].clearValidate();
+        }
+      })
+    },
+    hideDialog(success) {
+      this.init();
+      this.$emit("hide", success || false);
+    },
+    getTypeDetail() {
+      this.initial = true;
+      api.viewArticleType(this.id).then(res => {
+        if (res.data) {
+          this.form = res.data
+        }
+      }).catch(err => {
+        this.$message({
+          type: 'error',
+          message: err
+        })
+      }).finally(() => {
+        this.initial = false;
+      })
+    },
+    onFormSave() {
+      this.$refs['attForm'].validate((valid) => {
+        if (valid) {
+          this.isEdit ? this.updateType() : this.addType();
+        }
+      })
+    },
+    addType() {
+      this.loading = true;
+      api.addArticleType(this.form).then(res => {
+        this.$message({
+          type: 'success',
+          message: "Add successfully"
+        });
+        this.hideDialog(true);
+      }).catch(err => {
+        this.loading = false;
+        this.$message({
+          type: 'error',
+          message: err
+        })
+      });
+    },
+    updateType() {
+      this.loading = true;
+      api.updateArticleType(this.form).then(res => {
+        this.$message({
+          type: 'success',
+          message: "Update successfully"
+        });
+        this.hideDialog(true);
+      }).catch(err => {
+        this.loading = false;
+        this.$message({
+          type: 'error',
+          message: err
+        })
+      });
+    }
+  }
+}
+</script>
+
+<style scoped>
+.dialog-article-type >>> .el-dialog {
+  width: 100%;
+  max-width: 480px;
+}
+.dialog-article-type >>> .el-form {
+  padding-right: 10px;
+}
+.form-row {
+  display: flex;
+  flex-wrap: wrap;
+  padding: 0 0 10px;
+}
+.form-item {
+  flex: 1;
+  margin-left: 10px;
+  margin-bottom: 10px;
+}
+.form-item >>> label {
+  padding: 0;
+}
+.flex-item {
+  min-width: 200px;
+  max-width: 450px;
+}
+.flex-item2 {
+  width: 100%;
+  min-width: 200px;
+}
+@media screen and (max-width: 500px) {
+  .flex-item {
+    width: 100%;
+    max-width: none;
+  }
+}
+</style>

+ 214 - 0
Strides-Admin/src/views/article/typeList.vue

@@ -0,0 +1,214 @@
+<template>
+  <div class="app-container">
+    <div class="filter-container">
+      <div class="filter-view">
+        <el-select
+          class="filter-input"
+          placeholder="All Status"
+          clearable
+          @change="onClickSearch"
+          v-model="filters.pageVo.dataStatus">
+          <el-option
+            v-for="(item,index) in options.status"
+            :key="index"
+            :label="item.name"
+            :value="item.value"/>
+        </el-select>
+        <el-input
+          class="filter-input"
+          v-model="filters.pageVo.criteria"
+          placeholder="Search by Type Name"
+          prefix-icon="el-icon-search"
+          clearable/>
+        <div>
+          <el-button
+            @click="onClickSearch"
+            icon="el-icon-search"
+            type="primary">
+            Search
+          </el-button>
+        </div>
+        <div
+          class="filter-flex-button"
+          v-if="!$route.meta.onlyView">
+          <el-button
+            icon="el-icon-plus"
+            type="primary"
+            @click="onClickAdd">
+            Create
+          </el-button>
+        </div>
+      </div>
+    </div>
+    <el-table
+      v-loading="loading"
+      :data="table.list">
+      <el-table-column
+        align="center"
+        label="Article Type"
+        prop="articleTypeName"
+        min-width="140"/>
+      <el-table-column
+        align="center"
+        label="Related Articles"
+        prop="relatedArticles"
+        min-width="130"/>
+      <el-table-column
+        align="center"
+        label="Created Date"
+        prop="createTime"
+        min-width="120"/>
+      <el-table-column
+        align="center"
+        label="Status"
+        prop="dataStatus"
+        min-width="100"/>
+      <el-table-column
+        align="center"
+        label="Action"
+        min-width="100"
+        v-if="!$route.meta.onlyView">
+        <template v-slot="{ row }">
+          <TableAction
+            @edit="onClickEdit(row)"
+            @delete="onClickDelete(row)"
+            v-if="row.dataStatus != 'Inactive'"/>
+        </template>
+      </el-table-column>
+    </el-table>
+    <div class="right">
+      <pagination
+        v-show="table.total > 0"
+        :total="table.total"
+        :page.sync="filters.pageNo"
+        :limit.sync="filters.pageSize"
+        @pagination="getTableData" />
+    </div>
+    <DialogDetail
+      v-bind="dialogAction"
+      @hide="hideActionDialog"/>
+  </div>
+</template>
+
+<script>
+import TableAction from '@/components/TableAction.vue'
+import Pagination from '@/components/Pagination'
+import DialogDetail from './typeDetail.vue'
+import charge from '../../http/api/charge'
+import api from '../../api/article.js'
+export default {
+  data() {
+    return {
+      loading: false,
+      filters: {
+        pageNo: 1,
+        pageSize: 10,
+        pageVo: {
+          criteria: "",
+          dataStatus: ""
+        }
+      },
+      table: {
+        list: [],
+        total: 0
+      },
+      options: {
+        status: []
+      },
+      dialogAction: {
+        id: "",
+        isEdit: false,
+        visible: false
+      }
+    };
+  },
+  components: { Pagination, TableAction, DialogDetail },
+  created() {
+    this.getStatusOptions();
+    this.onClickSearch();
+  },
+  methods: {
+    onClickSearch() {
+      this.filters.pageNo = 1
+      this.getTableData()
+    },
+    getStatusOptions() {
+      charge.getStatusOptions().then(res => {
+        this.options.status = res.data;
+      }).catch(err => {
+        this.$message.error(err);
+      })
+    },
+    getTableData() {
+      this.loading = true;
+      api.getArticleTypePages(this.filters).then(res => {
+        if (res.data && res.total) {
+          this.table.total = res.total;
+          this.table.list = res.data;
+        } else {
+          this.table.total = 0;
+          this.table.list = [];
+        }
+      }).catch(err => {
+        this.$message({
+          type: 'error',
+          message: err
+        })
+        this.table.total = 0;
+        this.table.list = [];
+      }).finally(() => {
+        this.loading = false;
+      })
+    },
+    onClickAdd() {
+      this.dialogAction.id = "";
+      this.dialogAction.isEdit = false;
+      this.dialogAction.visible = true;
+    },
+    onClickEdit(row) {
+      this.dialogAction.id = row.articleTypeId;
+      this.dialogAction.isEdit = true;
+      this.dialogAction.visible = true;
+    },
+    onClickDelete(row) {
+      this.$confirm('Are you sure you want to delete this article type?', 'Delete', {
+        confirmButtonText: 'OK',
+        cancelButtonText: 'Cancel',
+        type: 'warning'
+      }).then(res => {
+        this.onDeleteType(row.articleTypeId);
+      })
+    },
+    onDeleteType(id) {
+      this.loading = true;
+      api.deleteArticleType(id).then(res => {
+        this.$message({
+          type: 'success',
+          message: "Delete success."
+        })
+        this.getTableData()
+      }).catch(err => {
+        this.$message({
+          type: 'error',
+          message: err
+        })
+        this.loading = false;
+      })
+    },
+    hideActionDialog(e) {
+      this.dialogAction.id = "";
+      this.dialogAction.visible = false;
+      if (e) {
+        this.getTableData();
+      }
+    }
+  }
+}
+</script>
+
+<style scoped>
+.filter-input {
+  min-width: 100px;
+  max-width: 300px;
+}
+</style>

+ 25 - 0
Strides-Admin/src/views/campaign/detail.vue

@@ -0,0 +1,25 @@
+<template>
+  <div>
+    
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      
+    };
+  },
+  created() {
+    
+  },
+  methods: {
+    
+  }
+}
+</script>
+
+<style scoped>
+
+</style>

+ 210 - 0
Strides-Admin/src/views/campaign/index.vue

@@ -0,0 +1,210 @@
+<template>
+  <div class="app-container">
+    <div class="filter-container">
+      <div class="filter-view">
+        <el-select
+          class="filter-input"
+          placeholder="All Status"
+          clearable
+          @change="onClickSearch"
+          v-model="filters.pageVo.dataStatus">
+          <el-option
+            v-for="(item,index) in options.status"
+            :key="index"
+            :label="item.name"
+            :value="item.value"/>
+        </el-select>
+        <div
+          class="filter-flex-button"
+          v-if="!$route.meta.onlyView">
+          <el-button
+            icon="el-icon-plus"
+            type="primary"
+            @click="onClickAdd">
+            Create
+          </el-button>
+        </div>
+      </div>
+    </div>
+    <el-table
+      v-loading="loading"
+      :data="table.list">
+      <el-table-column
+        align="center"
+        label="Campaign ID"
+        prop="userPk"
+        min-width="120">
+        <template slot-scope="{row}" >
+          <span
+            class="link-type"
+            @click="onClickEdit(row)"
+            v-if="!$route.meta.onlyView">
+            {{ row.campaignId }}
+          </span>
+          <span v-else>{{ row.campaignId }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column
+        align="center"
+        label="Campaign Title"
+        prop="campaignTitle"
+        min-width="150"/>
+      <el-table-column
+        align="center"
+        label="Start Date and End Date"
+        prop="campaignDuration"
+        min-width="180"/>
+      <el-table-column
+        align="center"
+        label="Status"
+        prop="dataStatus"
+        min-width="80"/>
+      <el-table-column
+        align="center"
+        label="No. of Sites"
+        prop="assignedSiteCount"
+        min-width="120"/>
+      <el-table-column
+        align="center"
+        label="Created By"
+        prop="createBy"
+        min-width="120"/>
+      <el-table-column
+        align="center"
+        label="Created On"
+        prop="createTime"
+        min-width="120"/>
+      <el-table-column
+        align="center"
+        label="Action"
+        min-width="120"
+        v-if="!$route.meta.onlyView">
+        <template v-slot="{ row }">
+          <TableAction
+            @edit="onClickEdit(row)"
+            @delete="onClickDelete(row)"
+            v-if="row.dataStatus != 'Inactive'"/>
+        </template>
+      </el-table-column>
+    </el-table>
+    <div class="right">
+      <pagination
+        v-show="table.total > 0"
+        :total="table.total"
+        :page.sync="filters.pageNo"
+        :limit.sync="filters.pageSize"
+        @pagination="getTableData" />
+    </div>
+  </div>
+</template>
+
+<script>
+import TableAction from '@/components/TableAction.vue'
+import Pagination from '@/components/Pagination'
+import charge from '../../http/api/charge'
+import api from '../../api/campaign.js'
+export default {
+  data() {
+    return {
+      loading: false,
+      filters: {
+        pageNo: 1,
+        pageSize: 10,
+        pageVo: {
+          criteria: "",
+          dataStatus: ""
+        }
+      },
+      table: {
+        list: [],
+        total: 0
+      },
+      options: {
+        status: [],
+        types: []
+      }
+    };
+  },
+  components: { Pagination, TableAction },
+  created() {
+    this.getStatusOptions();
+    this.onClickSearch();
+  },
+  methods: {
+    onClickSearch() {
+      this.filters.pageNo = 1
+      this.getTableData()
+    },
+    getStatusOptions() {
+      charge.getStatusOptions().then(res => {
+        this.options.status = res.data;
+      }).catch(err => {
+        this.$message.error(err);
+      })
+    },
+    getTableData() {
+      this.loading = true;
+      api.getCampaignPages(this.filters).then(res => {
+        if (res.data && res.total) {
+          this.table.total = res.total;
+          this.table.list = res.data;
+        } else {
+          this.table.total = 0;
+          this.table.list = [];
+        }
+      }).catch(err => {
+        this.$message({
+          type: 'error',
+          message: err
+        })
+        this.table.total = 0;
+        this.table.list = [];
+      }).finally(() => {
+        this.loading = false;
+      })
+    },
+    onClickAdd() {
+      this.$router.push({
+        path: "/marketing-management/campaign/create"
+      })
+    },
+    onClickEdit(row) {
+      this.$router.push({
+        path: "/marketing-management/campaign/update/" + row.campaignId
+      })
+    },
+    onClickDelete(row) {
+      this.$confirm('Are you sure you want to delete this campaign?', 'Delete', {
+        confirmButtonText: 'OK',
+        cancelButtonText: 'Cancel',
+        type: 'warning'
+      }).then(res => {
+        this.onDeleteCampaign(row.campaignId)
+      })
+    },
+    onDeleteCampaign(id) {
+      this.loading = true;
+      api.deleteCampaign(id).then(res => {
+        this.$message({
+          type: 'success',
+          message: "Delete success."
+        })
+        this.getTableData()
+      }).catch(err => {
+        this.$message({
+          type: 'error',
+          message: err
+        })
+        this.loading = false;
+      })
+    }
+  }
+}
+</script>
+
+<style scoped>
+.filter-input {
+  min-width: 100px;
+  max-width: 300px;
+}
+</style>

+ 5 - 6
Strides-Admin/src/views/company/detail.vue

@@ -106,6 +106,7 @@
             action
             :limit="1"
             :show-file-list="false"
+            :file-list="[]"
             :on-remove="file => removeLogo(file)"
             :http-request="file => uploadLogo(file)"
             accept=".jpg,.jpeg,.png,.gif,.JPG,.JPEG"
@@ -153,7 +154,6 @@ import site from '@/http/api/site'
 import api from '@/http/api/group'
 import provider from '../../http/api/provider'
 import setting from '../../settings.js'
-import {baseURL} from '../../http/http'
 import {getCountryList} from '../../utils/index.js'
 export default {
   name: "GroupDetail",
@@ -222,8 +222,7 @@ export default {
             }
           }
         }]
-      },
-      imgAddress: baseURL
+      }
     }
   },
   created() {
@@ -274,7 +273,7 @@ export default {
           if (this.form.groupLogo) {
             this.logos.push({
               path: this.form.groupLogo,
-              url: this.imgAddress + this.form.groupLogo
+              url: this.$imageSrc(this.form.groupLogo)
             });
           }
         }
@@ -350,7 +349,7 @@ export default {
         }
         this.logos[0] = ({
           path: res.data.picturePath,
-          url: this.imgAddress + res.data.picturePath
+          url: this.$imageSrc(res.data.picturePath)
         })
       }).catch(err => {
         this.$message({
@@ -441,4 +440,4 @@ export default {
     border-radius: 6px;
     border: 1px dashed #d9d9d9;
   }
-</style>>
+</style>

+ 1 - 1
Strides-Admin/src/views/driver/DriverDetail.vue

@@ -287,7 +287,7 @@ export default {
   },
   filters: {
     imageSrc(path) {
-      return baseURL + path
+      return this.$imageSrc(path)
     }
   },
   methods: {

+ 2 - 2
Strides-Admin/src/views/group/detail.vue

@@ -282,7 +282,7 @@ export default {
     previewSrcList() {
       const imageSrc = []
       if (this.form.cardFront) {
-        imageSrc.push(baseURL + this.form.cardFront)
+        imageSrc.push(this.$imageSrc(this.form.cardFront))
       }
       return imageSrc
     },
@@ -315,7 +315,7 @@ export default {
       })
     },
     getImageSrc(path) {
-      return baseURL + path
+      return this.$imageSrc(path)
     },
     getCountryOptions() {
       site.getCountryList().then(res => {

+ 3 - 4
Strides-Admin/src/views/provider/detail.vue

@@ -73,6 +73,7 @@
             action
             :limit="1"
             :show-file-list="false"
+            :file-list="[]"
             :on-remove="file => removeLogo(file)"
             :http-request="file => uploadLogo(file)"
             accept=".jpg,.jpeg,.png,.gif,.JPG,.JPEG"
@@ -119,7 +120,6 @@
 <script>
   import { mapState } from 'vuex'
   import site from '@/http/api/site'
-  import {baseURL} from '../../http/http'
   import provider from '../../http/api/provider'
   import setting from '../../settings.js'
   export default {
@@ -149,7 +149,6 @@
           countryCode: setting.defaultCountry
         },
         logos: [],
-        imgAddress: baseURL,
         countryOptions: [],
         isEdit: false
       }
@@ -179,7 +178,7 @@
             if (this.form.providerLogo) {
               this.logos.push({
                 path: this.form.providerLogo,
-                url: this.imgAddress + this.form.providerLogo
+                url: this.$imageSrc(this.form.providerLogo)
               });
             }
           }
@@ -198,7 +197,7 @@
           }
           this.logos[0] = ({
             path: res.data.picturePath,
-            url: this.imgAddress + res.data.picturePath
+            url: this.$imageSrc(res.data.picturePath)
           })
         }).catch(err => {
           this.$message({

+ 1 - 0
Strides-Admin/src/views/site-label/detail.vue

@@ -97,6 +97,7 @@ export default {
       this.$emit("hide", success || false);
     },
     getLabelInfo() {
+      this.initial = true;
       api.viewSiteLabel(this.id).then(res => {
         if (res.data) {
           this.form = res.data

+ 3 - 0
Strides-Admin/src/views/site-label/index.vue

@@ -159,6 +159,9 @@ export default {
         if (res.data && res.total) {
           this.table.total = res.total;
           this.table.list = res.data;
+        } else {
+          this.table.total = 0;
+          this.table.list = [];
         }
       }).catch(err => {
         this.$message({

+ 2 - 2
Strides-Admin/src/views/user/views/ListMember.vue

@@ -180,12 +180,12 @@ export default {
       this.$emit('change', this.itemList);
     },
     getImageSrc(path) {
-      return baseURL + path
+      return this.$imageSrc(path)
     },
     previewSrcList(path) {
       const imageSrc = []
       if (path) {
-        imageSrc.push(baseURL + path)
+        imageSrc.push(this.$imageSrc(path))
       }
       return imageSrc
     },