فهرست منبع

v1.7.2版本接口调试

yuwenjun1997 2 سال پیش
والد
کامیت
8bdabf9072

+ 36 - 0
src/api/supplier.js

@@ -44,3 +44,39 @@ export function fetchCmSupplierList(params) {
     params
   })
 }
+
+// 修改供应商联系人
+export function updateSupplierLinkMan(data) {
+  return request({
+    url: '/shop/link/man/change',
+    method: 'post',
+    data
+  })
+}
+
+// 修改供应商logo
+export function updateSupplierLogo(data) {
+  return request({
+    url: '/shop/logo/change',
+    method: 'post',
+    data
+  })
+}
+
+// 修改供应商logo
+export function saveSupplierShopInfo(data) {
+  return request({
+    url: '/shop/info/save',
+    method: 'post',
+    data
+  })
+}
+
+// 修改供应商logo
+export function deleteSupplierShopInfo(data) {
+  return request({
+    url: '/shop/info/delete',
+    method: 'post',
+    data
+  })
+}

+ 1 - 1
src/api/system.js

@@ -29,7 +29,7 @@ export function updateUser(id, data) {
 /** 创建用户 */
 export function createUser(data) {
   return request({
-    url: '/sys/user/admin/create',
+    url: '/sys/user/create',
     method: 'post',
     data: data
   })

+ 9 - 0
src/api/user.js

@@ -71,3 +71,12 @@ export function fetchUserVipInfo(params) {
     params
   })
 }
+
+/** 代他操作token生成 */
+export function generateProxyToken(params) {
+  return request({
+    url: '/shop/token/generate',
+    method: 'get',
+    params
+  })
+}

+ 11 - 7
src/layout/components/Navbar.vue

@@ -23,16 +23,16 @@
               <!-- 供应商用户信息卡片 -->
               <user-card />
             </el-dropdown-item>
-            <router-link to="/personal/info">
-              <el-dropdown-item>个人资料</el-dropdown-item>
+            <router-link v-if="hasCompanyPage()" to="/personal/info">
+              <el-dropdown-item>公司信息</el-dropdown-item>
             </router-link>
-            <router-link to="/personal/account">
+            <!-- <router-link to="/personal/account">
               <el-dropdown-item>绑定登录账号</el-dropdown-item>
-            </router-link>
+            </router-link> -->
             <router-link to="/password/edit">
               <el-dropdown-item>修改密码</el-dropdown-item>
             </router-link>
-            <el-dropdown-item v-if="proxyState" divided @click.native="proxyLogout"> 退出代理 </el-dropdown-item>
+            <el-dropdown-item v-if="proxySwitch" divided @click.native="proxyLogout"> 退出代理 </el-dropdown-item>
             <el-dropdown-item v-else divided @click.native="logout">
               <span style="display: block">退出登录</span>
             </el-dropdown-item>
@@ -78,10 +78,10 @@ export default {
     // Search
   },
   computed: {
-    ...mapGetters(['sidebar', 'device', 'userIdentity', 'openSoket', 'proxyState']),
+    ...mapGetters(['sidebar', 'device', 'userIdentity', 'openSoket', 'proxySwitch']),
     // isSupplier
     isSupplier() {
-      return this.userIdentity === 2
+      return this.userIdentity === 2 || this.userIdentity === 3
     }
   },
   methods: {
@@ -106,6 +106,10 @@ export default {
         this.$store.commit('proxy/CLOSE_PROXY')
         this.$router.replace('/proxy')
       }, 500)
+    },
+    // 公司信息路由是否存在
+    hasCompanyPage() {
+      return this.$store.getters.menusList.some((item) => item.name === 'PersonalInfo')
     }
   }
 }

+ 21 - 4
src/mixin/base.js

@@ -3,16 +3,33 @@ import Vue from 'vue'
 const option = {
   methods: {
     // 后退
-    navigateBack() {
-      this.$store.dispatch('tagsView/delView', this.$route)
-      this.$router.go(-1)
+    navigateBack(flag = false) {
+      // if (!flag) {
+      //   this.$store.dispatch('tagsView/delView', this.$route)
+      //   this.$router.go(-1)
+      //   return
+      // }
+      this.$confirm('该操作会清空未保存的数据,是否继续?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      })
+        .then(() => {
+          this.$store.dispatch('tagsView/delView', this.$route)
+          this.$router.go(-1)
+        })
+        .catch(() => {
+          this.$message({
+            type: 'info',
+            message: '继续编辑'
+          })
+        })
     },
     // 跳转
     navigationTo(url, params) {
       this.$router.push({ path: url, params })
     }
   }
-
 }
 
 Vue.mixin(option)

+ 2 - 2
src/permission.js

@@ -34,8 +34,8 @@ router.beforeEach(async(to, from, next) => {
       } else {
         try {
           // 代理状态更换时清空全部页面标签
-          console.log('代理状态切换 ', store.getters.isChangeProxy)
-          if (store.getters.isChangeProxy) {
+          console.log('代理状态切换 ', store.getters.proxyRefresh)
+          if (store.getters.proxyRefresh) {
             store.commit('tagsView/CLEAR_ALL_VIEW')
             store.commit('proxy/CHANGE_PROXY_STATE', false)
           }

+ 3 - 2
src/store/getters.js

@@ -17,12 +17,13 @@ const getters = {
   permissions: state => state.user.permissions,
   authUserId: state => state.user.authUserId,
   userIdentity: state => state.user.userIdentity,
+  prefix: state => state.user.prefix,
   permission_routes: state => state.permission.routes,
   routes: state => state.permission.routes,
   errorLogs: state => state.errorLog.logs,
   proxyInfo: state => state.proxy.proxyInfo,
-  proxyState: state => state.proxy.proxyState,
-  isChangeProxy: state => state.proxy.isChangeProxy,
+  proxySwitch: state => state.proxy.proxySwitch,
+  proxyRefresh: state => state.proxy.proxyRefresh,
   shopType: state => state.user.shopType,
   infoId: state => state.user.infoId,
   socketState: state => state.webSocket.socketState,

+ 0 - 64
src/store/modules/permission1.js

@@ -1,64 +0,0 @@
-import { asyncRoutes, constantRoutes } from '@/router'
-
-/**
- * 通过meta.role判断是否与当前用户权限匹配
- * @param roles
- * @param route
- */
-function hasPermission(roles, route) {
-  if (route.meta && route.meta.roles) {
-    return roles.some(role => route.meta.roles.includes(role))
-  } else {
-    return true
-  }
-}
-
-/**
- * 递归过滤异步路由表,返回符合用户角色权限的路由表
- * @param routes asyncRoutes
- * @param roles
- */
-export function filterAsyncRoutes(routes, roles) {
-  const res = []
-
-  routes.forEach(route => {
-    const tmp = { ...route }
-    if (hasPermission(roles, tmp)) {
-      if (tmp.children) {
-        tmp.children = filterAsyncRoutes(tmp.children, roles)
-      }
-      res.push(tmp)
-    }
-  })
-
-  return res
-}
-
-const state = {
-  routes: [],
-  addRoutes: []
-}
-
-const mutations = {
-  SET_ROUTES: (state, routes) => {
-    state.addRoutes = routes
-    state.routes = constantRoutes.concat(routes)
-  }
-}
-
-const actions = {
-  generateRoutes({ commit }, roles) {
-    return new Promise(resolve => {
-      const accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
-      commit('SET_ROUTES', accessedRoutes)
-      resolve(accessedRoutes)
-    })
-  }
-}
-
-export default {
-  namespaced: true,
-  state,
-  mutations,
-  actions
-}

+ 11 - 9
src/store/modules/proxy.js

@@ -1,7 +1,7 @@
 const state = {
   proxyInfo: null,
-  proxyState: false,
-  isChangeProxy: false
+  proxySwitch: false,
+  proxyRefresh: false
 }
 
 const mutations = {
@@ -14,20 +14,22 @@ const mutations = {
       shopStatus: proxy.shopStatus ? 1 : 0,
       shopType: proxy.shopType,
       userIdentity: 2, // 开启代理
-      mobile: proxy.mobile
+      mobile: proxy.mobile,
+      token: proxy.token,
+      prefix: proxy.prefix
     }
-    state.proxyState = true // 用于判断是否需要更新路由 ture:需要更新, false:不需要更新
-    state.isChangeProxy = true // 大理状态是否改变 根据改状态开重置路由和路由列表
+    state.proxySwitch = true // 用于判断是否需要更新路由 ture:需要更新, false:不需要更新
+    state.proxyRefresh = true // 代理状态是否改变 根据改状态开重置路由和路由列表
   },
   // 关闭供应商代理
-  CLOSE_PROXY: state => {
+  CLOSE_PROXY: (state) => {
     state.proxyInfo = null
-    state.proxyState = false
-    state.isChangeProxy = true
+    state.proxySwitch = false
+    state.proxyRefresh = true
   },
   // 更改代理状态
   CHANGE_PROXY_STATE: (state, status) => {
-    state.isChangeProxy = status
+    state.proxyRefresh = status
   }
 }
 

+ 9 - 3
src/store/modules/user.js

@@ -18,7 +18,8 @@ const state = {
   roles: [],
   menusList: [],
   permissions: [],
-  vipInfo: {}
+  vipInfo: {},
+  prefix: '' // 供应商前缀标识符
 }
 
 const mutations = {
@@ -34,6 +35,7 @@ const mutations = {
     state.loginAccount = userInfo.loginAccount || ''
     state.mobile = userInfo.mobile || ''
     state.vipStatus = userInfo.vipStatus || ''
+    state.prefix = userInfo.prefix || ''
   },
   // 设置token
   SET_TOKEN: (state, token) => {
@@ -76,7 +78,7 @@ const actions = {
 
   // 获取用户菜单列表
   fetchUserInfo({ commit, state }) {
-    return fetchUserInfo({ authUserId: state.authUserId }).then(res => {
+    return fetchUserInfo({ authUserId: state.authUserId }).then((res) => {
       console.log(res)
       commit('SET_ROLES', res.data.roles)
       commit('SET_MENUS', res.data.menus)
@@ -87,7 +89,7 @@ const actions = {
   // 获取用户会员信息
   fetchUserVipInfo({ commit, state }) {
     if (state.userIdentity === 1) return
-    fetchUserVipInfo({ authUserId: state.authUserId }).then(res => {
+    fetchUserVipInfo({ authUserId: state.authUserId }).then((res) => {
       commit('SET_VIPINFO', res.data)
     })
   },
@@ -106,6 +108,9 @@ const actions = {
   proxyLogin({ commit, rootGetters }) {
     commit('SET_ROLES', [])
     commit('SAVE_USER_INOF', rootGetters.proxyInfo)
+    if (rootGetters.proxyInfo.token) {
+      commit('SET_TOKEN', rootGetters.proxyInfo.token)
+    }
   },
 
   // 代理登出
@@ -113,6 +118,7 @@ const actions = {
     commit('SET_ROLES', [])
     commit('SAVE_USER_INOF', getUserInfo())
     commit('SET_VIPINFO', {})
+    commit('SET_TOKEN', getToken())
   }
 }
 

+ 10 - 23
src/utils/request.js

@@ -1,23 +1,20 @@
 import axios from 'axios'
 import { Message } from 'element-ui'
 import store from '@/store'
-import { getToken } from '@/utils/auth'
 import router from '@/router'
-import NProgress from 'nprogress' // progress bar
-import 'nprogress/nprogress.css' // progress bar style
+import NProgress from 'nprogress'
+import 'nprogress/nprogress.css'
 
-NProgress.configure({ showSpinner: false }) // NProgress Configuration
+NProgress.configure({ showSpinner: false })
 
-// create an axios instance
 const service = axios.create({
-  baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
-  // withCredentials: true, // send cookies when cross-domain requests
-  timeout: 60000 // request timeout
+  baseURL: process.env.VUE_APP_BASE_API,
+  timeout: 60000
 })
 
 // 请求拦截
 service.interceptors.request.use(
-  config => {
+  (config) => {
     NProgress.start()
     // 默认以application/json 格式传递参数
     config.headers['Content-Type'] = config.headers['Content-Type'] || 'application/json'
@@ -25,13 +22,13 @@ service.interceptors.request.use(
     if (config.headers['Content-Type'] === 'application/json') {
       config.data = JSON.stringify(config.data)
     }
-    const token = getToken()
+    const token = store.getters.token
     if (token) {
       config.headers['X-Token'] = token
     }
     return config
   },
-  error => {
+  (error) => {
     NProgress.done()
     return Promise.reject(error)
   }
@@ -39,17 +36,7 @@ service.interceptors.request.use(
 
 // 响应拦截
 service.interceptors.response.use(
-  /**
-   * If you want to get http information such as headers or status
-   * Please return  response => response
-   */
-
-  /**
-   * Determine the request status by custom code
-   * Here is just an example
-   * You can also judge the status by HTTP Status Code
-   */
-  response => {
+  (response) => {
     const res = response.data
     // token失效时
     if (res.code === -99) {
@@ -75,7 +62,7 @@ service.interceptors.response.use(
       return res
     }
   },
-  error => {
+  (error) => {
     console.log('错误:' + error) // for debug
     Message({
       message: error.message,

+ 28 - 2
src/views/admin/supplier/edit.vue

@@ -4,6 +4,15 @@
       <el-form-item label="供应商名称:" prop="shopName">
         <el-input v-model="formData.shopName" placeholder="请输入供应商名称" maxlength="50" show-word-limit />
       </el-form-item>
+      <el-form-item label="标识符:" prop="prefix">
+        <el-input
+          v-model="formData.prefix"
+          placeholder="供应商唯一标识符(不可更改)"
+          maxlength="10"
+          show-word-limit
+          :disabled="prefixDisabled"
+        />
+      </el-form-item>
       <el-form-item label="供应商类型:" prop="shopType">
         <el-select v-model="formData.shopType" placeholder="请选择供应商类型">
           <el-option label="品牌方" :value="1" />
@@ -105,7 +114,7 @@
 import UploadImage from '@/components/UploadImage'
 import { BrandEditForm } from '@/views/components'
 import { deepClone } from '@/utils'
-import { isMobile } from '@/utils/validate'
+import { isMobile, validLowerCase } from '@/utils/validate'
 import { fetchCmSupplierList, createSupplier, getSupplierById } from '@/api/supplier'
 import { mapGetters } from 'vuex'
 
@@ -129,13 +138,21 @@ export default {
       }
       return callback()
     }
+    const prefixValidate = (rule, value, callback) => {
+      if (!validLowerCase(value)) {
+        return callback(new Error('标识符只能是小写字母'))
+      }
+      return callback()
+    }
     return {
       isLoading: false,
       type: 'add',
       brandEditVisible: false,
       brandEditType: 'add',
       brandEditIndex: 0,
+      prefix: '',
       formData: {
+        prefix: '', // 供应商标记
         authUserId: '',
         createBy: '',
         shopName: '', // 供应商名称
@@ -158,6 +175,10 @@ export default {
           { validator: validMobile, trigger: ['blur'] }
         ],
         linkMan: [{ required: true, message: '请输入联系人', trigger: ['blur'] }],
+        prefix: [
+          { required: true, message: '请输入供应商标识符', trigger: ['blur'] },
+          { validator: prefixValidate, trigger: ['blur'] }
+        ],
         logo: [{ required: true, message: '请上传供应商logo', trigger: ['change'] }],
         shopInfo: [{ required: true, type: 'array', message: '请至少添加一个品牌', trigger: ['change'] }],
         shopStatus: [{ required: true, message: '请选择供应商状态', trigger: ['change'] }],
@@ -170,7 +191,10 @@ export default {
     }
   },
   computed: {
-    ...mapGetters(['authUserId'])
+    ...mapGetters(['authUserId']),
+    prefixDisabled() {
+      return this.type === 'edit' && this.prefix && this.prefix.length > 0
+    }
   },
   created() {
     this.fetchCmSupplierList()
@@ -219,6 +243,8 @@ export default {
       if (this.formData.logo) {
         this.logoImageList = [{ url: this.formData.logo, name: '供应商logo' }]
       }
+
+      this.prefix = data.prefix
       this.$nextTick(() => (this.isLoading = false))
     },
 

+ 12 - 7
src/views/admin/supplier/index.vue

@@ -115,7 +115,7 @@
 
 <script>
 import { fetchSupplierList, supplierStatusChange } from '@/api/supplier'
-import { resetPassword } from '@/api/user'
+import { generateProxyToken, resetPassword } from '@/api/user'
 
 export default {
   name: 'ComplexTable',
@@ -217,13 +217,18 @@ export default {
         this.$message.warning('当前供应商未启用')
         return
       }
-
-      console.log(item)
-      // 要执行的操作
-      this.$store.commit('proxy/OPEN_PROXY', item)
-      this.$store.dispatch('user/proxyLogin')
-      this.$router.push('/proxy')
+      try {
+        const res = await generateProxyToken({ authUserId: item.authUserId })
+        const userInfo = { ...item, token: res.data }
+        // 要执行的操作
+        this.$store.commit('proxy/OPEN_PROXY', userInfo)
+        this.$store.dispatch('user/proxyLogin')
+        this.$router.push('/proxy')
+      } catch (error) {
+        console.log(error)
+      }
     },
+
     // 过滤列表
     handleFilter() {
       this.listQuery.page = 1

+ 2 - 2
src/views/common/proxy/index.vue

@@ -5,10 +5,10 @@
 import { mapGetters } from 'vuex'
 export default {
   computed: {
-    ...mapGetters(['proxyState'])
+    ...mapGetters(['proxySwitch'])
   },
   created() {
-    const path = this.proxyState ? '/club' : '/supplier'
+    const path = this.proxySwitch ? '/club' : '/supplier'
     this.$router.replace(path)
   }
 }

+ 10 - 3
src/views/components/DeviceDetail/index.vue

@@ -2,7 +2,7 @@
   <div>
     <div class="row">
       <div class="col">认证方式:</div>
-      <div class="col">新设备认证 | 关联已认证设备</div>
+      <div class="col">{{ productInfo.relationId === 1 ? '新设备认证' : '关联已认证设备' }}</div>
     </div>
     <div class="row">
       <div class="col">设备名称:</div>
@@ -37,7 +37,10 @@
     <div class="row">
       <div class="col">审核状态:</div>
       <div class="col">
-        <audit-status :status="productInfo.shopAuditStatus || productInfo.auditStatus" :reason="productInfo.invalidReason" />
+        <audit-status
+          :status="productInfo.shopAuditStatus || productInfo.auditStatus"
+          :reason="productInfo.invalidReason"
+        />
       </div>
     </div>
   </div>
@@ -51,6 +54,10 @@ export default {
     productId: {
       type: String,
       default: ''
+    },
+    relationId: {
+      type: String,
+      default: ''
     }
   },
   data() {
@@ -75,7 +82,7 @@ export default {
     // 获取商品详情
     getDetail() {
       this.isLoading = true
-      getProductById({ productId: this.productId })
+      getProductById({ productId: this.productId, relationId: this.relationId })
         .then((res) => {
           this.productInfo = { ...this.productInfo, ...res.data }
         })

+ 1 - 1
src/views/normal/audit/club/components/device-list.vue

@@ -118,7 +118,7 @@ export default {
     },
     onClick(row, type) {
       this.$router.push(
-        `/supplier-audit/club/device-detail?productId=${row.productId}&authId=${this.listQuery.authId}&type=${type}`
+        `/supplier-audit/club/device-detail?relationId=${row.relationId}&productId=${row.productId}&authId=${this.listQuery.authId}&type=${type}`
       )
     },
     indexMethod(index) {

+ 5 - 2
src/views/normal/audit/club/device/review.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="page-form-container">
-    <device-detail :product-id="productId" />
+    <device-detail :product-id="productId" :relation-id="relationId" />
     <template v-if="type === 'audit'">
       <el-form ref="auditForm" label-width="112px" :model="auditForm" :rules="rules">
         <el-form-item label="审核:">
@@ -33,12 +33,14 @@ export default {
     return {
       type: 'review',
       productId: '',
+      relationId: '',
       auditForm: {
         productId: '',
         auditBy: '', // 审核人id
         authId: '', // 机构id
         auditStatus: 1, // 审核状态
-        invalidReason: '' // 审核信息
+        invalidReason: '', // 审核信息
+        source: 2
       },
       rules: {
         invalidReason: { required: true, message: '不通过原因不能为空', tigger: 'blur' }
@@ -51,6 +53,7 @@ export default {
   created() {
     this.authId = this.$route.query.authId
     this.productId = this.$route.query.productId
+    this.relationId = this.$route.query.relationId
     this.type = this.$route.query.type
   },
   methods: {

+ 43 - 32
src/views/normal/club/device/edit.vue

@@ -41,7 +41,7 @@
 
       <template v-if="formData.authType === 1 || (formData.authType === 2 && formData.snCode)">
         <!-- **************** 新方法配置授权牌 START ******************* -->
-        <el-form-item label="授权牌:">
+        <el-form-item label="授权牌:" prop="certificateImage">
           <el-radio-group v-model="formData.certificateImageType" size="mini" @change="onCertificateImageTypeChange">
             <el-radio :label="1" border>模板库生成</el-radio>
             <el-radio :label="2" border>自定义上传</el-radio>
@@ -63,11 +63,11 @@
           </div>
         </el-form-item>
 
-        <el-form-item label="购买渠道:">
+        <el-form-item label="购买渠道:" prop="purchaseWay">
           <el-input v-model="formData.purchaseWay" placeholder="请输入购买渠道" />
         </el-form-item>
 
-        <el-form-item label="发票:">
+        <el-form-item label="发票:" prop="invoiceImage">
           <upload-image
             tip="建议图片分辨率:242px*242px"
             :limit="1"
@@ -99,6 +99,23 @@ import {
 import { mapGetters } from 'vuex'
 import { isSnCode } from '@/utils/validate'
 import { getStorage } from '@/utils/storage'
+
+const resetFormData = () => ({
+  authId: '', //	授权id
+  relationId: '',
+  authType: 1,
+  authUserId: '',
+  createBy: '', //	创建人id
+  certificateImage: '', //	授权牌照
+  // 	设备参数列表
+  productId: '', //	授权设备id
+  snCode: '', //	设备SN码
+  certificateImageType: 1,
+  productTypeId: '',
+  purchaseWay: '', // 购买渠道
+  invoiceImage: '' // 发票
+})
+
 export default {
   components: { UploadImage },
   data() {
@@ -115,23 +132,9 @@ export default {
       brandList: [],
       deviceList: [], // 设备列表
       firstAuthType: '',
-      formData: {
-        authId: '', //	授权id
-        relationId: '',
-        authType: 1,
-        authUserId: '',
-        createBy: '', //	创建人id
-        certificateImage: '', //	授权牌照
-        // 	设备参数列表
-        productId: '', //	授权设备id
-        snCode: '', //	设备SN码
-        certificateImageType: 1,
-        productTypeId: '',
-        purchaseWay: '', // 购买渠道
-        invoiceImage: '' // 发票
-      },
+      formData: resetFormData(),
       rules: {
-        certificateImage: [{ required: true, message: '授权牌照不能为空' }],
+        certificateImage: [{ required: true, message: '授权牌照不能为空', trigger: 'change' }],
         snCode: [{ required: true, message: 'SN码不能为空' }, { validator: valideSNcode }],
         productTypeId: [{ required: true, message: '设备名称不能为空', trigger: 'change' }]
       },
@@ -147,23 +150,28 @@ export default {
     ...mapGetters(['authUserId', 'proxyInfo', 'shopType', 'infoId'])
   },
   created() {
-    this.editType = this.$route.query.type || 'add'
-    this.formData.relationId = this.$route.query.relationId
-    this.formData.productId = this.$route.query.id
-    // this.formData.authUserId = this.proxyInfo?.authUserId || this.authUserId
-    // 获取当前设备所属机构的id
-    this.formData.authId = getStorage('device-setting-authId')
-    this.fetchDeviceList()
-    this.fetchProductSnList()
-    if (this.editType === 'edit') {
-      this.fetchProductDetail()
-    }
+    this.init()
   },
   methods: {
+    init() {
+      this.editType = this.$route.query.type || 'add'
+      this.formData.relationId = this.$route.query.relationId
+      this.formData.productId = this.$route.query.id
+      // this.formData.authUserId = this.proxyInfo?.authUserId || this.authUserId
+      // 获取当前设备所属机构的id
+      this.formData.authId = getStorage('device-setting-authId')
+      this.fetchDeviceList()
+      this.fetchProductSnList()
+      if (this.editType === 'edit') {
+        this.fetchProductDetail()
+      }
+    },
+
     // 授权牌类型变化
-    onCertificateImageTypeChange() {
+    onCertificateImageTypeChange(value) {
       this.certificateImageList = []
       this.formData.certificateImage = ''
+      this.$refs.addFormRef.clearValidate('certificateImage')
     },
 
     // 设备sn码变化
@@ -190,7 +198,10 @@ export default {
 
     // 设备认证类型变化
     onAuthTypeChange(authType) {
-      if (authType === 1) return
+      this.certificateImageList = []
+      this.invoiceImageList = []
+      this.productSnList = []
+      this.$refs.addFormRef.resetFields()
     },
 
     // 获取设备sn码列表

+ 2 - 3
src/views/normal/club/edit.vue

@@ -179,7 +179,7 @@
     <!-- 表单提交 返回 -->
     <div class="control-box">
       <el-button type="primary" @click="submit">保存</el-button>
-      <el-button type="warning" @click="navigateBack()">返回</el-button>
+      <el-button type="warning" @click="navigateBack">返回</el-button>
     </div>
 
     <!-- 地图坐标拾取 -->
@@ -254,7 +254,6 @@ export default {
 
       authId: '',
       disabled: false,
-
       area: '',
       formData: {
         relationId: '',
@@ -394,7 +393,7 @@ export default {
         this.formData.mobile = res.data.mobile
         this.formData.logo = res.data.logo
         this.formData.banner = res.data.bannerList.length || ''
-        this.formatDate.relationId = res.data.relationId
+        this.formData.relationId = res.data.relationId
 
         this.formData.customFlag = res.data.customFlag
         this.formData.remarks = res.data.remarks

+ 0 - 13
src/views/normal/club/index.vue

@@ -267,19 +267,6 @@ export default {
       )
     },
 
-    // cotyClubLink($event, row) {
-    //   // http://192.168.2.92:8888/114/app/record/club/detail
-    //   let name = 'app'
-    //   if (this.authUserId === 12) {
-    //     name = 'ross'
-    //   }
-    //   handleClipboard(
-    //     `${process.env.VUE_APP_WWW_HOST}/${this.authUserId}/${name}/form/link-register?type=link&authId=${row.authId}`,
-    //     '链接已复制到粘贴板',
-    //     $event
-    //   )
-    // },
-
     // 上传文件
     submitUpload() {
       this.$refs.dialogForm.validate((valid) => {

+ 75 - 20
src/views/normal/personal/index.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="app-container personal-info">
-    <div class="title">个人资料</div>
+    <div class="title">公司信息</div>
     <el-divider />
     <el-row>
       <el-col :span="5">公司名称:</el-col>
@@ -22,7 +22,7 @@
     <el-divider />
     <el-row>
       <el-col :span="5">联系人:</el-col>
-      <el-col :span="8">{{ supplierInfo.mobile }}</el-col>
+      <el-col :span="8">{{ supplierInfo.linkMan }}</el-col>
       <el-col :span="8">
         <el-link icon="el-icon-edit" type="primary" @click="onEditContactName">修改联系人</el-link>
       </el-col>
@@ -31,7 +31,7 @@
     <el-row>
       <el-col :span="5">公司logo:</el-col>
       <el-col :span="8">
-        <preview-image />
+        <preview-image :src="supplierInfo.logo" />
         <div style="margin-top: 12px">
           <el-link icon="el-icon-upload" type="primary" @click="onEditLogo">修改</el-link>
         </div>
@@ -58,7 +58,7 @@
                 effect="dark"
                 size="small"
                 type="success"
-                @close="onRemoveBrand(index)"
+                @close="onRemoveBrand(item, index)"
                 @click="onEditBrand('edit', item, index)"
               >
                 <span>{{ item.brandName }}</span>
@@ -130,15 +130,22 @@
 </template>
 
 <script>
-import { getSupplierById } from '@/api/supplier'
+import {
+  getSupplierById,
+  updateSupplierLinkMan,
+  updateSupplierLogo,
+  saveSupplierShopInfo,
+  deleteSupplierShopInfo
+} from '@/api/supplier'
 import UploadImage from '@/components/UploadImage'
 import { BrandEditForm } from '@/views/components'
 import { deepClone } from '@/utils'
 
 const generateBrandInfo = () => ({
+  infoId: '',
   brandName: '',
-  brandAuthLogo: '',
-  country: '',
+  brandLogo: '',
+  producePlace: '',
   manufacturer: ''
 })
 
@@ -182,6 +189,7 @@ export default {
       getSupplierById({ authUserId: this.$store.getters.authUserId }).then((res) => {
         console.log(res)
         this.supplierInfo = res.data
+        this.brandList = res.data.shopInfo
       })
     },
     // 品牌信息变化
@@ -196,37 +204,80 @@ export default {
       this.brandModel = type === 'add' ? generateBrandInfo() : row
       this.editVisible = true
     },
-    // 删除品牌
-    onRemoveBrand(index) {
-      this.brandList.splice(index, 1)
+    // 删除品牌操作
+    async onRemoveBrand(item, index) {
+      // 判断品牌是否可删除
+      let existInfoIds = this.formData.existProductInfoIds
+      existInfoIds = existInfoIds ? existInfoIds.split(',') : []
+      const exist = existInfoIds.indexOf(item.infoId.toString()) > -1
+      if (exist) {
+        this.$alert('对不起,该品牌已绑定设备认证,暂时无法删除!', '提示', {
+          confirmButtonText: '确定',
+          type: 'warning'
+        }).then(() => {})
+        return
+      }
+      try {
+        await this.$confirm('确认删除该品牌信息?', '提示', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning'
+        })
+        await this.removeBrand(item, index)
+      } catch (error) {
+        console.log(error)
+        this.$message.info('已取消操作')
+      }
+    },
+    async removeBrand(item, index) {
+      try {
+        await deleteSupplierShopInfo({ infoId: item.infoId })
+        this.$message.success('成功删除品牌')
+        this.brandList.splice(index, 1)
+      } catch (error) {
+        console.log(error)
+      }
     },
     // 品牌信息确认提交
     async onBrandSubmit() {
       try {
         await this.$refs.brandEditForm.validate()
-        if (this.brandEditType === 'add') {
-          this.brandList.push(deepClone(this.brandModel))
-        } else {
-          this.brandList.splice(this.brandEditIndex, 1, deepClone(this.brandModel))
-        }
-        this.editVisible = false
+        await this.onBrandSave()
       } catch (error) {
         console.log(error)
       }
     },
+
+    async onBrandSave() {
+      try {
+        await saveSupplierShopInfo(deepClone(this.brandModel))
+        this.$message.success('品牌信息已保存')
+      } catch (error) {
+        console.log(error)
+      }
+    },
+
     // 编辑取消
     onCancel() {
       this.editVisible = false
     },
     // 编辑提交
-    onSubmit() {
+    async onSubmit() {
       const action = {
         0: this.onBrandSubmit,
         1: this.onBrandSubmit,
         2: this.onLogoSubmit,
         3: this.onContactSubmit
       }
-      action[this.editType]()
+      try {
+        await this.$refs.submitForm?.validate()
+        await action[this.editType]()
+      } catch (error) {
+        console.log(error)
+      } finally {
+        this.fetchSupplierInfo()
+        this.editVisible = false
+      }
     },
     // logo编辑
     onEditLogo() {
@@ -236,9 +287,12 @@ export default {
     // logo编辑提交
     async onLogoSubmit() {
       try {
-        await this.$refs.submitForm.validate()
+        await updateSupplierLogo({ logo: this.formData.logo })
+        this.$message.success('修改logo成功')
       } catch (error) {
         console.log(error)
+      } finally {
+        this.logoImageList = []
       }
     },
     // 编辑联系人
@@ -249,7 +303,8 @@ export default {
     // 联系人编辑提交
     async onContactSubmit() {
       try {
-        await this.$refs.submitForm.validate()
+        await updateSupplierLinkMan({ linkMan: this.formData.linkMan })
+        this.$message.success('修改联系人成功')
       } catch (error) {
         console.log(error)
       }

+ 57 - 20
src/views/normal/settings/accounts/edit.vue

@@ -6,16 +6,24 @@
         <upload-image tip="建议尺寸:60 * 60px" />
       </el-form-item> -->
       <el-form-item label="登录名:" prop="username">
-        <el-input v-model="userInfo.username" placeholder="登录名" />
+        <el-input v-model="userInfo.username" :placeholder="`通过登录名登录时请加上前缀,例如:${prefix}_test`">
+          <template slot="prepend">{{ prefix }}_</template>
+        </el-input>
       </el-form-item>
       <el-form-item v-if="!userInfo.id" label="密码:" prop="password">
-        <el-input v-model="userInfo.password" placeholder="密码" />
+        <el-input v-model="userInfo.password" placeholder="请输入密码" type="password" />
       </el-form-item>
-      <el-form-item label="联系人:">
-        <el-input v-model="userInfo.linkMan" placeholder="联系人" />
+      <el-form-item label="联系人:" prop="linkMan">
+        <el-input v-model="userInfo.linkMan" placeholder="请输入联系人" />
       </el-form-item>
       <el-form-item label="手机号:" prop="mobile">
-        <el-input v-model="userInfo.mobile" placeholder="手机号" />
+        <el-input
+          v-model="userInfo.mobile"
+          placeholder="请输入手机号"
+          maxlength="11"
+          show-word-limit
+          @input="onMobileInput"
+        />
       </el-form-item>
       <el-form-item label="状态:">
         <el-radio-group v-model="userInfo.status">
@@ -42,6 +50,8 @@
 <script>
 import { fetchRoleList, createUser, getUser, updateUser } from '@/api/system'
 import { isMobile } from '@/utils/validate'
+import { mapGetters } from 'vuex'
+import { deepClone } from '@/utils'
 
 export default {
   data() {
@@ -59,7 +69,7 @@ export default {
     }
     // 校验手机号
     const validateMobile = (rule, value, callback) => {
-      if (value && isMobile(value)) {
+      if (isMobile(value)) {
         callback()
       } else {
         callback(new Error('请输入合法的手机号'))
@@ -80,15 +90,22 @@ export default {
       roleList: [],
       rules: {
         username: [
-          { required: true, message: '请输入登录名', trigger: 'blur' },
+          { required: true, message: '登录名不能为空', trigger: 'blur' },
           { min: 2, max: 15, message: '长度在 2 到 15 个字符', trigger: 'blur' }
         ],
-        mobile: [{ validator: validateMobile, trigger: 'blur' }],
-        password: [{ required: true, message: '请输入密码', trigger: 'blur' }],
+        linkMan: [{ required: true, message: '联系人不能为空', trigger: 'blur' }],
+        mobile: [
+          { required: true, message: '手机号不能为空', trigger: 'blur' },
+          { validator: validateMobile, trigger: 'blur' }
+        ],
+        password: [{ required: true, message: '密码不能为空', trigger: 'blur' }],
         roleList: [{ required: true, validator: validateRoleList, trigger: 'change' }]
       }
     }
   },
+  computed: {
+    ...mapGetters(['prefix'])
+  },
   created() {
     this.editType = this.$route.query.type
     this.fetchRoleList()
@@ -100,14 +117,16 @@ export default {
   methods: {
     // 获取角色列表
     fetchRoleList() {
-      fetchRoleList().then(res => {
+      fetchRoleList().then((res) => {
         this.roleList = [...this.roleList, ...res.data.list]
       })
     },
     // 修改保存用户信息
     updateUserInfo() {
-      this.userInfo.roleIds = this.userInfo.roleList.join(',')
-      updateUser(this.userInfo.id, this.userInfo).then(res => {
+      const userInfo = deepClone(this.userInfo)
+      userInfo.roleIds = userInfo.roleList.join(',')
+      userInfo.username = `${this.prefix}_${userInfo.username}`
+      updateUser(userInfo.id, userInfo).then((res) => {
         this.$message.success('修改用户成功')
         this.$store.dispatch('tagsView/delView', this.$route)
         this.$router.back()
@@ -115,8 +134,10 @@ export default {
     },
     // 保存用户信息
     createUserInfo() {
-      this.userInfo.roleIds = this.userInfo.roleList.join(',')
-      createUser(this.userInfo).then(res => {
+      const userInfo = deepClone(this.userInfo)
+      userInfo.roleIds = userInfo.roleList.join(',')
+      userInfo.username = `${this.prefix}_${userInfo.username}`
+      createUser(userInfo).then((res) => {
         this.$message.success('添加用户成功')
         this.$store.dispatch('tagsView/delView', this.$route)
         this.$router.back()
@@ -124,7 +145,7 @@ export default {
     },
     // 提交表单
     onSubmit() {
-      this.$refs.userInfoFormRef.validate(valide => {
+      this.$refs.userInfoFormRef.validate((valide) => {
         if (!valide) return
         if (this.editType === 'add') {
           this.createUserInfo()
@@ -135,19 +156,28 @@ export default {
     },
     // 获取用户信息
     fetchUserInfo() {
-      getUser(this.userInfo.id).then(res => {
+      getUser(this.userInfo.id).then((res) => {
         this.setUserInfo(res.data)
       })
     },
     // 设置用户信息
     setUserInfo(data) {
-      console.log(data)
-      for (const key in this.userInfo) {
-        if (Object.hasOwnProperty.call(data, key)) {
+      for (const key in data) {
+        if (Object.hasOwnProperty.call(this.userInfo, key)) {
           this.userInfo[key] = data[key]
         }
       }
-      this.userInfo.roleList = data.roleIds.split(',').map(item => parseInt(item))
+      const prefix = this.prefix + '_'
+      const prefixLen = prefix.length
+      if (this.userInfo.username.startsWith(prefix)) {
+        this.userInfo.username = this.userInfo.username.substring(prefixLen)
+      }
+      this.userInfo.roleList = data.roleIds.split(',').map((item) => parseInt(item))
+    },
+
+    // 输入手机号时
+    onMobileInput() {
+      this.userInfo.mobile = this.userInfo.mobile.replace(/[^\w\.\/]/gi, '')
     }
   }
 }
@@ -158,5 +188,12 @@ export default {
   width: 600px;
   margin: 0 auto;
   margin-top: 100px;
+
+  ::v-deep {
+    .el-input-group__prepend {
+      background: transparent;
+      padding: 0 10px 0 15px;
+    }
+  }
 }
 </style>

+ 1 - 1
src/views/normal/settings/roles/edit.vue

@@ -72,7 +72,7 @@ export default {
     },
     // 获取菜单权限列表
     getMenuTree() {
-      sysMenuTree({ menuType: 1 }).then(res => {
+      sysMenuTree({ menuType: 2 }).then(res => {
         this.menuTree = res.data
       })
     },