Bläddra i källkod

feature: 商户个人信息

ljc 4 månader sedan
förälder
incheckning
55ac731b97

+ 11 - 2
src/i18n/locales/cn.json

@@ -1295,6 +1295,7 @@
   "R-ShopManage-Add": "新增",
   "R-ShopManage-Edit": "编辑",
   "R-ShopManage-Del": "删除",
+  "R-ShopInfo": "商户信息",
   "ActivitiesApply23New": {
     "item1": "申请状态",
     "item2": "转换状态",
@@ -2747,7 +2748,7 @@
     "ToLogin": "拷贝账户",
     "CopyOrder": "拷贝订单号",
     "IpLimit": "是否IP限制",
-    "Merchant": "管理员",
+    "Merchant": "商户管理员",
     "limitIp": "限制IP",
     "excludeCIds": "排除CID",
     "PAMMfee": "PAMM手续费",
@@ -7440,8 +7441,16 @@
     "t1": "商户名称",
     "t2": "邮箱",
     "t3": "手机号码",
+    "t4": "国家",
+    "t5": "地址",
+    "t6": "管理员姓氏",
+    "t7": "管理员名字",
     "p1": "请输入商户名称",
     "p2": "请输入邮箱",
-    "p3": "请输入手机号码"
+    "p3": "请输入手机号码",
+    "p4": "请选择国家",
+    "p5": "请输入地址",
+    "p6": "请输入管理员姓氏",
+    "p7": "请输入管理员名字"
   }
 }

+ 29 - 5
src/i18n/locales/en.json

@@ -296,7 +296,7 @@
     "Female": "Female",
     "NoSuccess": "Unsuccessful"
   },
-  "R-Cooperation":"Cooperation",
+  "R-Cooperation": "Cooperation",
   "R-Cooperation-Search": "List",
   "R-Cooperation-Detailed": "Details",
   "R-Cooperation-Update": "Edit",
@@ -378,7 +378,7 @@
   "R-Popup-Single": "Single",
   "R-Apply": "Application Management",
   "R-VerifiedUser": "Pending User",
-  "R-MonthlyList":"Monthly Gift Activity",
+  "R-MonthlyList": "Monthly Gift Activity",
   "R-UtaskList": "U-coin deposit reward activity",
   "R-surplusList": "Monthly surplus bonus activity",
   "R-surplusList-Search": "List",
@@ -1298,6 +1298,12 @@
   "R-ActivitiesApply23New-status": "Transition Status",
   "R-ActivitiesApply23New-Delete": "Delete",
   "R-ActivitiesApply23New-Export": "Export",
+  "R-ShopManage": "Merchant Management",
+  "R-ShopManage-Page": "List",
+  "R-ShopManage-Add": "Add",
+  "R-ShopManage-Edit": "Edit",
+  "R-ShopManage-Del": "Delete",
+  "R-ShopInfo": "Merchant Information",
   "ActivitiesApply23New": {
     "item1": "Application Status",
     "item2": "Transition Status",
@@ -2729,6 +2735,7 @@
     "ToLogin": "To Login",
     "CopyOrder": "Copy Order",
     "IpLimit": "Ip Limit",
+    "Merchant": "Merchant Administrator",
     "limitIp": "Limit Ip",
     "excludeCIds": "Exclude CID",
     "PAMMfee": "PAMM Fee",
@@ -4514,7 +4521,7 @@
       "deduction4": "Refund Processing",
       "deduction5": "Refund Successful",
       "deduction6": "Refund Failed",
-      "currencyTip":"Estimated Conversion",
+      "currencyTip": "Estimated Conversion",
       "CancelOrder": "Cancel Order",
       "ConfirmCancelOrder": "Are you sure you want to cancel this order?",
       "CancelOrderSuccess": "Order cancelled successfully",
@@ -4666,7 +4673,6 @@
       "v21": "Remittance Order Cancellation",
       "v22": "Submit Additional Information",
       "v23": "Cancel Card"
-
     },
     "Msg": {
       "m1": "Your card application has been submitted, and you will be notified via email after approval!",
@@ -7405,5 +7411,23 @@
     "CopyProfitWithdrawal": "Copy Profit Withdrawal",
     "CreditRevoke": "Credit Revoke",
     "ActivityBonus": "Activity Bonus"
+  },
+  "ShopManage": {
+    "add": "Add Merchant",
+    "edit": "Edit Merchant",
+    "t1": "Merchant Name",
+    "t2": "Email",
+    "t3": "Mobile Number",
+    "t4": "Country",
+    "t5": "Address",
+    "t6": "Admin Last Name",
+    "t7": "Admin First Name",
+    "p1": "Please enter merchant name",
+    "p2": "Please enter email",
+    "p3": "Please enter mobile number",
+    "p4": "Please select country",
+    "p5": "Please enter address",
+    "p6": "Please enter admin last name",
+    "p7": "Please enter admin first name"
   }
-}
+}

+ 8 - 0
src/routers/modules/user.ts

@@ -31,6 +31,14 @@ const userRoute = {
       name: 'R-ShopManage',
       component: () => import('@/views/user/ShopManage/index.vue'),
     },
+    {
+      meta: {
+        OnBreadCrumb: true,
+      },
+      path: 'shopInfo',
+      name: 'R-ShopInfo',
+      component: () => import('@/views/user/ShopInfo/index.vue'),
+    },
   ],
 }
 export default userRoute

+ 4 - 4
src/service/user.ts

@@ -155,10 +155,10 @@ class UserService extends Service {
   async shopManageDel(params = {}) {
     return await this.post('/merchant/delete', params)
   }
-  // 商户管理 -list
-  // async getShopManageList(params = {}) {
-  //   return await this.get('/merchant/findSingle', params)
-  // }
+  // 商户管理 -获取单个商户信息
+  async getShopManageInfo(params = {}) {
+    return await this.post('/merchant/findSingle', params)
+  }
   // 商户管理 -list
   async getShopManageList(params = {}) {
     return await this.post('/merchant/getAllMerchant', params)

+ 1 - 0
src/views/card/CardIdTypeConfig/index.vue

@@ -192,6 +192,7 @@
 
   // 使用 inject 获取 session
   const Session = inject('session')
+  const pigeon = inject('pigeon')
 
   // Refs
   const formRef = ref(null)

+ 13 - 1
src/views/home2/Home.vue

@@ -73,7 +73,9 @@
                     </span>
                   </el-dropdown-item>
                   <!--                  商户个人信息,商户管理员可以看到,可以修改-->
-                  <el-dropdown-item @click="beforeLogout"> 个人信息 </el-dropdown-item>
+                  <el-dropdown-item v-if="isShopManager" @click="goShopInfo">
+                    Info
+                  </el-dropdown-item>
                   <el-dropdown-item @click="beforeLogout"> Logout </el-dropdown-item>
                 </el-dropdown-menu>
               </template>
@@ -240,6 +242,10 @@
     const currentRole = attachList.value.find((item) => item.id === currentAttachId.value)
     return currentRole ? currentRole.name : ''
   })
+  const isShopManager = computed(() => {
+    console.log(user.value)
+    return !!user.value.isMerchantAdmin
+  })
 
   // 验证规则
   const rules = reactive({
@@ -337,6 +343,12 @@
       function () {}
     )
   }
+  // 查看商户管理员信息
+  const goShopInfo = () => {
+    router.push({
+      path: '/user/shopInfo',
+    })
+  }
 
   const logout = async () => {
     const res = await Service.Logout({})

+ 254 - 0
src/views/user/ShopInfo/index.vue

@@ -0,0 +1,254 @@
+<template>
+  <div class="content">
+    <el-card class="card">
+      <template #header>
+        <div class="head">
+          <div class="title">
+            {{ t('R-ShopInfo') }}
+          </div>
+          <div class="title-icon">
+            <el-icon @click="edit = true"><Edit /></el-icon>
+          </div>
+        </div>
+      </template>
+      <el-form ref="addFormRef" :model="addForm" :rules="formRules" label-width="120px">
+        <el-form-item :label="`${t('ShopManage.t1')}:`" prop="merchantName">
+          <el-input
+            v-model.trim="addForm.merchantName"
+            disabled
+            :placeholder="t('Placeholder.Input')"
+          >
+          </el-input>
+        </el-form-item>
+        <el-form-item :label="`${t('ShopManage.t7')}:`" prop="firstName">
+          <el-input
+            v-model.trim="addForm.firstName"
+            :disabled="!edit"
+            :placeholder="t('Placeholder.Input')"
+          >
+          </el-input>
+        </el-form-item>
+        <el-form-item :label="`${t('ShopManage.t6')}:`" prop="lastName">
+          <el-input
+            v-model.trim="addForm.lastName"
+            :disabled="!edit"
+            :placeholder="t('Placeholder.Input')"
+          >
+          </el-input>
+        </el-form-item>
+        <el-form-item :label="`${t('ShopManage.t2')}:`" prop="email">
+          <el-input
+            v-model.trim="addForm.email"
+            :disabled="!edit"
+            :placeholder="t('Placeholder.Input')"
+          >
+          </el-input>
+        </el-form-item>
+        <el-form-item :label="`${t('ShopManage.t3')}:`" prop="mobile">
+          <el-input
+            v-model.trim="addForm.mobile"
+            :disabled="!edit"
+            :placeholder="t('Placeholder.Input')"
+          >
+          </el-input>
+        </el-form-item>
+        <el-form-item :label="`${t('ShopManage.t4')}:`" prop="country">
+          <el-select
+            v-model="addForm.country"
+            :placeholder="t('Placeholder.Choose')"
+            clearable
+            filterable
+            :disabled="!edit"
+          >
+            <el-option
+              v-for="(item, index) in country"
+              :key="index"
+              :label="item.enName"
+              :value="item.code"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item :label="`${t('ShopManage.t5')}:`" prop="address">
+          <el-input
+            v-model.trim="addForm.address"
+            :disabled="!edit"
+            :placeholder="t('Placeholder.Input')"
+          >
+          </el-input>
+        </el-form-item>
+      </el-form>
+      <template v-if="edit" #footer>
+        <el-button type="primary" @click="saveInfo" :loading="addLoading">{{
+          t('Btn.Save')
+        }}</el-button>
+      </template>
+    </el-card>
+  </div>
+</template>
+
+<script setup lang="ts">
+  import { computed, inject, onMounted, reactive, ref } from 'vue'
+  import ServiceMarket from '@/service/marketing'
+  import Service from '@/service/user'
+  import Config from '@/config'
+  import { useI18n } from 'vue-i18n'
+
+  const { Code } = Config
+  const formRef = ref(null)
+  const addFormRef = ref(null)
+  const addForm = reactive({})
+  const country = ref(null)
+  const addLoading = ref(false)
+
+  const pigeon = inject('pigeon')
+  const Session = inject('session')
+  const { t } = useI18n()
+  const formRules = computed(() => ({
+    merchantName: [
+      {
+        required: true,
+        message: t('ShopManage.p1'),
+        trigger: 'blur',
+      },
+    ],
+    email: [
+      {
+        required: true,
+        message: t('ShopManage.p2'),
+        trigger: 'blur',
+      },
+    ],
+    mobile: [
+      {
+        required: true,
+        message: t('ShopManage.p3'),
+        trigger: 'blur',
+      },
+    ],
+    country: [
+      {
+        required: true,
+        message: t('ShopManage.p4'),
+        trigger: 'change',
+      },
+    ],
+    address: [
+      {
+        required: true,
+        message: t('ShopManage.p5'),
+        trigger: 'blur',
+      },
+    ],
+    lastName: [
+      {
+        required: true,
+        message: t('ShopManage.p6'),
+        trigger: 'blur',
+      },
+    ],
+    firstName: [
+      {
+        required: true,
+        message: t('ShopManage.p7'),
+        trigger: 'blur',
+      },
+    ],
+  }))
+  const edit = ref(false)
+
+  const user = computed(() => {
+    const userStr = Session.Get('user', true)
+    return userStr ? JSON.parse(userStr) : {}
+  })
+  // 获取国家列表
+  const getCountry = async () => {
+    try {
+      let res = await ServiceMarket.Country({})
+      if (res.code == Code.StatusOK) {
+        country.value = res.data
+      } else {
+        pigeon.MessageError(res.msg || t('Msg.Error'))
+      }
+    } catch (error) {
+      console.error('获取国家列表失败:', error)
+      pigeon.MessageError(t('Msg.NetworkError'))
+    }
+  }
+
+  const getShopInfo = async () => {
+    const params = {
+      id: user.value.merchantId,
+    }
+    const res = await Service.getShopManageInfo(params)
+    console.log(res)
+    if (res.code == Code.StatusOK) {
+      Object.assign(addForm, { ...res.data })
+    }
+  }
+  const saveInfo = async () => {
+    const valid = await addFormRef.value.validate()
+    if (!valid) return
+    addLoading.value = true
+    try {
+      const params = { ...addForm }
+      const res = await Service.shopManageEdit(params)
+
+      if (res.code == Code.StatusOK) {
+        await getShopInfo()
+        edit.value = false
+      } else {
+        pigeon.MessageError(res.msg)
+      }
+      addLoading.value = false
+    } catch (error) {
+      console.error(error)
+    }
+  }
+
+  onMounted(() => {
+    getCountry()
+    getShopInfo()
+  })
+</script>
+
+<style scoped lang="scss">
+  .content {
+    width: 100%;
+    height: 100%;
+    border-radius: 2px;
+    -webkit-box-sizing: border-box;
+    box-sizing: border-box;
+    background-color: #ffffff;
+    overflow: hidden;
+    overflow-y: auto;
+    padding: 50px 0;
+    display: flex;
+    //align-items: center;
+    justify-content: center;
+  }
+  .card {
+    width: 900px;
+    overflow: hidden;
+    overflow-y: auto;
+  }
+  .head {
+    width: 100%;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    position: relative;
+    .title {
+      font-weight: bold;
+      font-size: 16px;
+    }
+    .title-icon {
+      position: absolute;
+      right: 0;
+      display: flex;
+      align-self: flex-end;
+      justify-self: flex-end;
+      font-size: 20px;
+      cursor: pointer;
+    }
+  }
+</style>

+ 106 - 3
src/views/user/ShopManage/index.vue

@@ -45,6 +45,37 @@
           {{ scope.row.merchantName || '--' }}
         </template>
       </el-table-column>
+      <el-table-column prop="name" align="left" :label="t('Label.Name')">
+        <template #default="{ row }">
+          <span v-if="row.firstName">
+            {{ row.firstName + ' ' }}
+          </span>
+          <span v-if="row.lastName">{{ row.lastName }}</span>
+          <span v-if="!row.firstName && !row.lastName">
+            {{ '--' }}
+          </span>
+        </template>
+      </el-table-column>
+      <el-table-column prop="email" align="left" :label="t('ShopManage.t2')">
+        <template #default="scope">
+          {{ scope.row.email || '--' }}
+        </template>
+      </el-table-column>
+      <el-table-column prop="mobile" align="left" :label="t('ShopManage.t3')">
+        <template #default="scope">
+          {{ scope.row.mobile || '--' }}
+        </template>
+      </el-table-column>
+      <el-table-column prop="country" align="left" :label="t('ShopManage.t4')">
+        <template #default="scope">
+          {{ scope.row.country || '--' }}
+        </template>
+      </el-table-column>
+      <el-table-column prop="address" align="left" :label="t('ShopManage.t5')">
+        <template #default="scope">
+          {{ scope.row.address || '--' }}
+        </template>
+      </el-table-column>
       <el-table-column prop="opt" align="center" :label="$t('Label.Action')">
         <template #default="scope">
           <el-dropdown trigger="click" @command="handleCommand">
@@ -91,11 +122,38 @@
           <el-input v-model.trim="addForm.merchantName" :placeholder="t('Placeholder.Input')">
           </el-input>
         </el-form-item>
+        <el-form-item :label="`${t('ShopManage.t7')}:`" prop="firstName">
+          <el-input v-model.trim="addForm.firstName" :placeholder="t('Placeholder.Input')">
+          </el-input>
+        </el-form-item>
+        <el-form-item :label="`${t('ShopManage.t6')}:`" prop="lastName">
+          <el-input v-model.trim="addForm.lastName" :placeholder="t('Placeholder.Input')">
+          </el-input>
+        </el-form-item>
         <el-form-item :label="`${t('ShopManage.t2')}:`" prop="email">
           <el-input v-model.trim="addForm.email" :placeholder="t('Placeholder.Input')"> </el-input>
         </el-form-item>
-        <el-form-item :label="`${t('ShopManage.t3')}:`" prop="phone">
-          <el-input v-model.trim="addForm.phone" :placeholder="t('Placeholder.Input')"> </el-input>
+        <el-form-item :label="`${t('ShopManage.t3')}:`" prop="mobile">
+          <el-input v-model.trim="addForm.mobile" :placeholder="t('Placeholder.Input')"> </el-input>
+        </el-form-item>
+        <el-form-item :label="`${t('ShopManage.t4')}:`" prop="country">
+          <el-select
+            v-model="addForm.country"
+            :placeholder="t('Placeholder.Choose')"
+            clearable
+            filterable
+          >
+            <el-option
+              v-for="(item, index) in country"
+              :key="index"
+              :label="item.enName"
+              :value="item.code"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item :label="`${t('ShopManage.t5')}:`" prop="address">
+          <el-input v-model.trim="addForm.address" :placeholder="t('Placeholder.Input')">
+          </el-input>
         </el-form-item>
       </el-form>
       <template #footer>
@@ -117,6 +175,7 @@
   import { useI18n } from 'vue-i18n'
   import Config from '@/config'
   import { ElMessageBox } from 'element-plus'
+  import ServiceMarket from '@/service/marketing'
 
   const { Code } = Config
   const Session = inject('session')
@@ -129,6 +188,7 @@
   const formRef = ref(null)
   const addFormRef = ref(null)
   const addForm = reactive({})
+  const country = ref(null)
   // reactive 响应式对象
   const search = reactive({
     merchantName: '',
@@ -156,13 +216,41 @@
         trigger: 'blur',
       },
     ],
-    phone: [
+    mobile: [
       {
         required: true,
         message: t('ShopManage.p3'),
         trigger: 'blur',
       },
     ],
+    country: [
+      {
+        required: true,
+        message: t('ShopManage.p4'),
+        trigger: 'change',
+      },
+    ],
+    address: [
+      {
+        required: true,
+        message: t('ShopManage.p5'),
+        trigger: 'blur',
+      },
+    ],
+    lastName: [
+      {
+        required: true,
+        message: t('ShopManage.p6'),
+        trigger: 'blur',
+      },
+    ],
+    firstName: [
+      {
+        required: true,
+        message: t('ShopManage.p7'),
+        trigger: 'blur',
+      },
+    ],
   }))
   const pagerInfo = reactive({
     row: 10,
@@ -212,6 +300,20 @@
     pagerInfo.current = 1
     searchFunc()
   }
+  // 获取国家列表
+  const getCountry = async () => {
+    try {
+      let res = await ServiceMarket.Country({})
+      if (res.code == Code.StatusOK) {
+        country.value = res.data
+      } else {
+        pigeon.MessageError(res.msg || t('Msg.Error'))
+      }
+    } catch (error) {
+      console.error('获取国家列表失败:', error)
+      pigeon.MessageError(t('Msg.NetworkError'))
+    }
+  }
   const handleAdd = () => {
     Object.assign(addForm, {})
     isEdit.value = false
@@ -286,6 +388,7 @@
   // 挂载生命周期
   onMounted(() => {
     searchFunc()
+    getCountry()
   })
 </script>
 

+ 6 - 2
src/views/user/userList/components/UserAdd.vue

@@ -230,9 +230,9 @@
           <el-option :label="$t('State.employmentStatus2')" :value="2"></el-option>
         </el-select>
       </el-form-item>
-      <el-form-item :label="$t('Label.Merchant') + ':'">
+      <el-form-item v-if="!user.merchantId" :label="$t('Label.Merchant') + ':'">
         <el-switch
-          v-model="form.isMerchantRole"
+          v-model="form.isMerchantAdmin"
           class="crm_switch"
           :active-value="1"
           :inactive-value="0"
@@ -288,6 +288,7 @@
   import ServiceMarket from '@/service/marketing'
   import ServiceUser from '@/service/user'
   import Config from '@/config/index'
+  import { safeGetUser } from '@/utils/safeJson'
 
   const { Code } = Config
   const { t } = useI18n()
@@ -342,6 +343,9 @@
   const GetRuleDropdownListComputed = computed(() => {
     return GetRuleDropdown.value.filter((item: any) => item.salesType == form.salesType)
   })
+  const user = computed(() => {
+    return safeGetUser(Session)
+  })
   const role_system = computed(() => {
     const user = JSON.parse(Session.Get('user', true) || '{}')
     return user.departmentId == null && user.roleName == 'ROLE_SYSTEM'