Browse Source

Changes 修改站点绑定

cyan 4 months ago
parent
commit
e3a025540b

+ 8 - 1
jeecgboot-vue3/src/views/okki/account/OkkiAccount.data.ts

@@ -20,6 +20,11 @@ export const columns: BasicColumn[] = [
     dataIndex: 'password'
   },
   {
+    title: '手机号',
+    align: "center",
+    dataIndex: 'phone'
+  },
+  {
     title: '小二账号id',
     align: "center",
     dataIndex: 'userId'
@@ -27,7 +32,9 @@ export const columns: BasicColumn[] = [
   {
     title: '关联站点',
     align: "center",
-    dataIndex: 'siteIds_dictText'
+    dataIndex: 'siteIds_dictText',
+    slots: { customRender: 'siteTag' },
+    ellipsis: true,
   },
   {
     title: '用户角色',

+ 15 - 4
jeecgboot-vue3/src/views/okki/account/OkkiAccountList.vue

@@ -30,6 +30,17 @@
         <!-- 高级查询 -->
         <super-query :config="superQueryConfig" @search="handleSuperQuery" />
       </template>
+      <template #siteTag="{ text, record }">
+        <!-- 显示每个 text 值 -->
+        <a-space :size="[0, 'small']" wrap v-if="text">
+         <span v-for="(item, index) in text.split(',')" :key="index">
+          <a-tooltip :title="item">
+<!--           <a-tag :color="getRandomColor()">{{ item }}</a-tag>-->
+           <a-tag style="margin-right:5px ">{{ item }}</a-tag>
+          </a-tooltip>
+         </span>
+        </a-space>
+      </template>
       <!--操作栏-->
       <template #action="{ record }">
         <TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)"/>
@@ -210,10 +221,10 @@
         label: '授权角色',
         onClick: handleAuth.bind(null, record),
       },
-      {
-        label: '关联站点',
-        onClick: handleBindSite.bind(null, record),
-      },
+      // {
+      //   label: '关联站点',
+      //   onClick: handleBindSite.bind(null, record),
+      // },
       {
         label: '修改密码',
         onClick: handleResetPwd.bind(null, record),

+ 12 - 3
jeecgboot-vue3/src/views/okki/account/components/OkkiAccountForm.vue

@@ -18,10 +18,15 @@
           </a-form-item>
         </a-col>
         <a-col :span="24">
-          <a-form-item label="关联站点" v-bind="validateInfos.siteIds">
-            <j-vxe-site-select-cell v-model:value="formData.siteIds" :disabled="(disabled||formData.id>0)?true:false"/>
+          <a-form-item label="手机号" v-bind="validateInfos.phone">
+            <a-input v-model:value="formData.phone" placeholder="请输入手机号" :disabled="disabled"></a-input>
           </a-form-item>
         </a-col>
+<!--        <a-col :span="24">-->
+<!--          <a-form-item label="关联站点" v-bind="validateInfos.siteIds">-->
+<!--            <j-vxe-site-select-cell v-model:value="formData.siteIds" :disabled="(disabled||formData.id>0)?true:false"/>-->
+<!--          </a-form-item>-->
+<!--        </a-col>-->
         <a-col :span="24">
           <a-form-item label="用户角色" v-bind="validateInfos.userRole">
             <j-dict-select-tag type='radio' v-model:value="formData.userRole" dictCode="user_role" placeholder="请选择用户角色" :disabled="(disabled||formData.id>0)?true:false"/>
@@ -57,8 +62,10 @@
   const emit = defineEmits(['register', 'ok']);
   const formData = reactive<Record<string, any>>({
     id: '',
+    name:'',
     account: '',   
-    password: '',   
+    password: '',
+    phone:'',
     siteIds: '',   
     sysUserCode: '',
     userRole: undefined,
@@ -69,8 +76,10 @@
   const confirmLoading = ref<boolean>(false);
   //表单验证
   const validatorRules = {
+    name: [{ required: true, message: '请输入名称!'},],
     account: [{ required: true, message: '请输入邮箱账号!'},],
     password: [{ required: true, message: '请输入密码!'},],
+    phone: [{ required: true, message: '请输入手机号!'},],
     userRole: [{ required: true, message: '请选择用户角色!'},],
   };
   const { resetFields, validate, validateInfos } = useForm(formData, validatorRules, { immediate: false });

+ 28 - 0
jeecgboot-vue3/src/views/okki/site/OkkiSite.api.ts

@@ -12,6 +12,9 @@ enum Api {
   deleteBatch = '/site/okkiSite/deleteBatch',
   importExcel = '/site/okkiSite/importExcel',
   exportXls = '/site/okkiSite/exportXls',
+  getOkkiUser = '/account/okkiAccount/user',
+  bindSiteV2 = '/account/okkiAccount/bindSiteV2',
+  siteBindInfo = '/account/okkiAccount/siteBindInfo',
 }
 /**
  * 导出api
@@ -72,3 +75,28 @@ export const saveOrUpdate = (params, isUpdate) => {
   let url = isUpdate ? Api.edit : Api.save;
   return defHttp.post({url: url, params});
 }
+
+/**
+ * 保存站点小二分配
+ * @param params
+ */
+export const saveXiaoErBind = (params) => {
+  console.log("saveXiaoErBind --- params:{}",params)
+  return defHttp.post({url: Api.bindSiteV2, params});
+}
+
+/**
+ * 获取小二账号列表
+ * @param params
+ */
+export const getOkkiAccounts = (params) => {
+  return defHttp.get({url: Api.getOkkiUser, params});
+}
+
+/**
+ * 获取小二账号列表
+ * @param params
+ */
+export const getSiteBindInfo = (params) => {
+  return defHttp.get({url: Api.siteBindInfo, params});
+}

+ 322 - 12
jeecgboot-vue3/src/views/okki/site/OkkiSite.data.ts

@@ -1,5 +1,8 @@
 import {BasicColumn} from '/@/components/Table';
 import {FormSchema} from '/@/components/Table';
+import {getOkkiAccounts, getSiteBindInfo} from "@/views/okki/site/OkkiSite.api";
+import {h} from "vue";
+import {Tag} from "ant-design-vue";
 //列表数据
 export const columns: BasicColumn[] = [
    {
@@ -69,16 +72,89 @@ export const columns: BasicColumn[] = [
     align:"center",
     dataIndex: 'remark'
    },
-   {
-    title: '所属部门',
+   // {
+   //  title: '所属部门',
+   //  align:"center",
+   //  dataIndex: 'sysOrgCode_dictText'
+   // },
+   // {
+   //  title: '所属人员',
+   //  align:"center",
+   //  dataIndex: 'sysUserCode_dictText'
+   // },
+  {
+    title: '服务主管',
     align:"center",
-    dataIndex: 'sysOrgCode_dictText'
-   },
-   {
-    title: '所属人员',
+    // dataIndex: 'serviceManageUser_dictText'
+    dataIndex: 'serviceManageUserStr',
+    // dataIndex: 'serviceManageUser',
+    slots: { customRender: 'xiaoErUserTag' },
+  },
+  {
+    title: '资料专员',
     align:"center",
-    dataIndex: 'sysUserCode_dictText'
-   },
+    // dataIndex: 'dataUser_dictText'
+    dataIndex: 'dataUserStr',
+    slots: { customRender: 'xiaoErUserTag' },
+  },
+  {
+    title: '建站顾问',
+    align:"center",
+    // dataIndex: 'kefuUser_dictText'
+    dataIndex: 'kefuUserStr',
+    slots: { customRender: 'xiaoErUserTag' },
+  },
+  {
+    title: 'SEO专员',
+    align:"center",
+    // dataIndex: 'seoUser_dictText'
+    dataIndex: 'seoUserStr',
+    slots: { customRender: 'xiaoErUserTag' },
+  },
+  {
+    title: 'SEM主管',
+    align:"center",
+    // dataIndex: 'semManageUser_dictText'
+    dataIndex: 'semManageUserStr',
+    slots: { customRender: 'xiaoErUserTag' },
+  },
+  {
+    title: 'SEM专员',
+    align:"center",
+    // dataIndex: 'semUser_dictText'
+    dataIndex: 'semUserStr',
+    slots: { customRender: 'xiaoErUserTag' },
+  },
+  {
+    title: '设计师',
+    align:"center",
+    // dataIndex: 'uiUser_dictText'
+    dataIndex: 'uiUserStr',
+    slots: { customRender: 'xiaoErUserTag' },
+  },
+  {
+    title: '建站专员',
+    align:"center",
+    // dataIndex: 'websiteUser_dictText'
+    dataIndex: 'websiteUserStr',
+    slots: { customRender: 'xiaoErUserTag' },
+  },
+  {
+    title: '社媒专员',
+    align:"center",
+    // dataIndex: 'socialUser_dictText',
+    dataIndex: 'socialUserStr',
+  slots: { customRender: 'xiaoErUserTag' },
+    // fixed: 'right',
+  },
+  {
+    title: '技术',
+    align:"center",
+    // dataIndex: 'socialUser_dictText',
+    dataIndex: 'rdUserStr',
+  slots: { customRender: 'xiaoErUserTag' },
+    // fixed: 'right',
+  },
 ];
 //查询数据
 export const searchFormSchema: FormSchema[] = [
@@ -116,6 +192,235 @@ export const formSchema: FormSchema[] = [
 	},
 ];
 
+const commonTagRender = (color: string) => (curVal) => h(Tag, { color }, () => curVal);
+
+// 小二分配
+// @ts-ignore
+export const xiaoErFormSchema: FormSchema[] = [
+  {
+    label: '服务主管',
+    field: 'serviceManageUser',
+    // component: 'Select',
+    required: true,
+    colProps: {span: 12},
+    component: 'ApiSelect',
+    componentProps: {
+      mode: 'multiple',
+      api: getOkkiAccounts,
+      numberToString: false,
+      labelField: 'name',
+      valueField: 'userId',
+      params: { userRole: 1 },
+      resultField: 'records',
+    },
+  },
+  {
+    label: '资料专员',
+    field: 'dataUser',
+    required: true,
+    colProps: {span: 12},
+    component: 'ApiSelect',
+    componentProps: {
+      mode: 'multiple',
+      api: getOkkiAccounts,
+      //数值转成String
+      numberToString: false,
+      //标题字段
+      labelField: 'name',
+      //值字段
+      valueField: 'userId',
+      //请求参数
+      params: { userRole: 5 },
+      //返回结果字段
+      resultField: 'records',
+    },
+  },
+  {
+    label: '建站顾问',
+    field: 'kefuUser',
+    required: true,
+    colProps: {span: 12},
+    component: 'ApiSelect',
+    componentProps: {
+      //multiple: 多选;不填写为单选
+      mode: 'multiple',
+      api: getOkkiAccounts,
+      //数值转成String
+      numberToString: false,
+      //标题字段
+      labelField: 'name',
+      //值字段
+      valueField: 'userId',
+      //请求参数
+      params: { userRole: 2 },
+      //返回结果字段
+      resultField: 'records',
+    },
+  },
+  {
+    label: 'SEO专员',
+    field: 'seoUser',
+    required: true,
+    colProps: {span: 12},
+    component: 'ApiSelect',
+    componentProps: {
+      mode: 'multiple',
+      api: getOkkiAccounts,
+      //数值转成String
+      numberToString: false,
+      //标题字段
+      labelField: 'name',
+      //值字段
+      valueField: 'userId',
+      //请求参数
+      params: { userRole: 7 },
+      //返回结果字段
+      resultField: 'records',
+    },
+  },
+  {
+    label: 'SEM主管',
+    field: 'semManageUser',
+    required: true,
+    colProps: {span: 12},
+    component: 'ApiSelect',
+    componentProps: {
+      mode: 'multiple',
+      api: getOkkiAccounts,
+      //数值转成String
+      numberToString: false,
+      //标题字段
+      labelField: 'name',
+      //值字段
+      valueField: 'userId',
+      //请求参数
+      params: { userRole: 9 },
+      //返回结果字段
+      resultField: 'records',
+    },
+  },
+  {
+    label: 'SEM专员',
+    field: 'semUser',
+    required: true,
+    colProps: {span: 12},
+    component: 'ApiSelect',
+    componentProps: {
+      mode: 'multiple',
+      api: getOkkiAccounts,
+      //数值转成String
+      numberToString: false,
+      //标题字段
+      labelField: 'name',
+      //值字段
+      valueField: 'userId',
+      //请求参数
+      params: { userRole: 10 },
+      //返回结果字段
+      resultField: 'records',
+    },
+  },
+  {
+    label: '设计师',
+    field: 'uiUser',
+    required: true,
+    colProps: {span: 12},
+    component: 'ApiSelect',
+    componentProps: {
+      mode: 'multiple',
+      api: getOkkiAccounts,
+      //数值转成String
+      numberToString: false,
+      //标题字段
+      labelField: 'name',
+      //值字段
+      valueField: 'userId',
+      //请求参数
+      params: { userRole: 4 },
+      //返回结果字段
+      resultField: 'records',
+    },
+  },
+  {
+    label: '建站专员',
+    field: 'websiteUser',
+    required: true,
+    colProps: {span: 12},
+    component: 'ApiSelect',
+    componentProps: {
+      mode: 'multiple',
+      api: getOkkiAccounts,
+      //数值转成String
+      numberToString: false,
+      //标题字段
+      labelField: 'name',
+      //值字段
+      valueField: 'userId',
+      //请求参数
+      params: { userRole: 11 },
+      //返回结果字段
+      resultField: 'records',
+    },
+  },
+  {
+    label: '社媒专员',
+    field: 'socialUser',
+    required: true,
+    colProps: {span: 12},
+    component: 'ApiSelect',
+    componentProps: {
+      mode: 'multiple',
+      api: getOkkiAccounts,
+      //数值转成String
+      numberToString: false,
+      //标题字段
+      labelField: 'name',
+      //值字段
+      valueField: 'userId',
+      //请求参数
+      params: {userRole: 8},
+      //返回结果字段
+      resultField: 'records',
+    }
+  },
+  {
+    label: '技术',
+    field: 'rdUser',
+    required: true,
+    colProps: {span: 12},
+    component: 'ApiSelect',
+    componentProps: {
+      mode: 'multiple',
+      api: getOkkiAccounts,
+      //数值转成String
+      numberToString: false,
+      //标题字段
+      labelField: 'name',
+      //值字段
+      valueField: 'userId',
+      //请求参数
+      params: { userRole: 12 },
+      //返回结果字段
+      resultField: 'records',
+    },
+  },
+
+  // TODO 主键隐藏字段,目前写死为ID
+  {
+    label: '',
+    field: 'id',
+    component: 'Input',
+    show: false
+  },
+
+  {
+    label: '',
+    field: 'siteId',
+    component: 'Input',
+    show: false
+  },
+];
+
 // 高级查询数据
 export const superQuerySchema = {
   siteId: {title: '站点id',order: 0,view: 'number', type: 'number',},
@@ -136,10 +441,15 @@ export const superQuerySchema = {
 };
 
 /**
-* 流程表单调用这个方法获取formSchema
-* @param param
-*/
-export function getBpmFormSchema(_formData): FormSchema[]{
+ * 流程表单调用这个方法获取formSchema
+ * @param _formData
+ */
+export function getBpmFormSchema(_formData): FormSchema[] {
   // 默认和原始表单保持一致 如果流程中配置了权限数据,这里需要单独处理formSchema
   return formSchema;
 }
+
+export function getXiaoErFormSchema(_formData): FormSchema[] {
+  // 默认和原始表单保持一致 如果流程中配置了权限数据,这里需要单独处理formSchema
+  return xiaoErFormSchema;
+}

+ 49 - 8
jeecgboot-vue3/src/views/okki/site/OkkiSiteList.vue

@@ -23,6 +23,16 @@
         <!-- 高级查询 -->
         <super-query :config="superQueryConfig" @search="handleSuperQuery" />
       </template>
+     <template #xiaoErUserTag="{ text, record }">
+       <!-- 显示每个 text 值 -->
+       <a-space :size="[0, 'small']" wrap v-if="text">
+         <span v-for="(item, index) in text.split(',')" :key="index">
+          <a-tooltip :title="item">
+           <a-tag style="margin-right:5px ">{{ item }}</a-tag>
+          </a-tooltip>
+         </span>
+       </a-space>
+     </template>
        <!--操作栏-->
       <template #action="{ record }">
         <TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)"/>
@@ -33,6 +43,7 @@
     </BasicTable>
     <!-- 表单区域 -->
     <OkkiSiteModal @register="registerModal" @success="handleSuccess"></OkkiSiteModal>
+    <OkkiXiaoErBindModal @register="registerBindSiteModal" @success="handleSuccess"></OkkiXiaoErBindModal>
   </div>
 </template>
 
@@ -42,6 +53,7 @@
   import {useModal} from '/@/components/Modal';
   import { useListPage } from '/@/hooks/system/useListPage'
   import OkkiSiteModal from './components/OkkiSiteModal.vue'
+  import OkkiXiaoErBindModal from './components/OkkiXiaoErBindModal.vue'
   import {columns, searchFormSchema, superQuerySchema} from './OkkiSite.data';
   import {list, updateStatus, deleteOne, batchDelete, getImportUrl,getExportUrl} from './OkkiSite.api';
   import { downloadFile } from '/@/utils/common/renderUtils';
@@ -50,7 +62,11 @@
   const checkedKeys = ref<Array<string | number>>([]);
   const userStore = useUserStore();
   //注册model
-  const [registerModal, {openModal}] = useModal();
+  const [registerModal, { openModal:openModal }] = useModal();
+  const [registerBindSiteModal, { openModal: bindSiteOpenModal }] = useModal();
+
+  // const registerBindSiteModal = ref();
+
   //注册table数据
   const { prefixCls,tableContext,onExportXls,onImportXls } = useListPage({
       tableProps:{
@@ -69,7 +85,7 @@
               ],
             },
            actionColumn: {
-               width: 120,
+               width: 220,
                fixed:'right'
             },
             beforeFetch: (params) => {
@@ -92,6 +108,26 @@
   // 高级查询配置
   const superQueryConfig = reactive(superQuerySchema);
 
+  function getRandomColor() {
+    const letters = '0123456789ABCDEF';
+    let color = '#';
+    for (let i = 0; i < 6; i++) {
+      color += letters[Math.floor(Math.random() * 16)];
+    }
+    return color;
+  }
+
+  /**
+   * 小二分配
+   */
+  function handleXiaoErBind(record: Recordable) {
+    bindSiteOpenModal(true, {
+      record,
+      isUpdate: true,
+      showFooter: true,
+    });
+  }
+
   /**
    * 高级查询事件
    */
@@ -120,6 +156,7 @@
        showFooter: true,
      });
    }
+
    /**
     * 详情
    */
@@ -159,9 +196,13 @@
       */
   function getTableAction(record){
        return [
+         // {
+         //   label: '授权',
+         //   onClick: handleEdit.bind(null, record),
+         // },
          {
-           label: '授权',
-           onClick: handleEdit.bind(null, record),
+           label: '小二分配',
+           onClick: handleXiaoErBind.bind(null, record),
          }
        ]
    }
@@ -202,10 +243,10 @@
           break;
       }
       return [
-        {
-          label: '详情',
-          onClick: handleDetail.bind(null, record),
-        },
+        // {
+        //   label: '详情',
+        //   onClick: handleDetail.bind(null, record),
+        // },
         {
           label: labelText,
           popConfirm: {

+ 1 - 1
jeecgboot-vue3/src/views/okki/site/components/OkkiSiteForm.vue

@@ -67,4 +67,4 @@
             }
         }
     });
-</script>
+</script>

+ 70 - 0
jeecgboot-vue3/src/views/okki/site/components/OkkiXiaoErBindForm.vue

@@ -0,0 +1,70 @@
+<template>
+    <div style="min-height: 400px">
+        <BasicForm @register="registerForm"></BasicForm>
+        <div style="width: 100%;text-align: center" v-if="!formDisabled">
+            <a-button @click="submitForm" pre-icon="ant-design:check" type="primary">提 交</a-button>
+        </div>
+    </div>
+</template>
+
+<script lang="ts">
+    import {BasicForm, useForm} from '/@/components/Form/index';
+    import {computed, defineComponent} from 'vue';
+    import {defHttp} from '/@/utils/http/axios';
+    import { propTypes } from '/@/utils/propTypes';
+    import {getXiaoErFormSchema} from '../OkkiSite.data';
+    import {saveOrUpdate, saveXiaoErBind} from '../OkkiSite.api';
+    
+    export default defineComponent({
+        name: "OkkiSiteForm",
+        components:{
+            BasicForm
+        },
+        props:{
+            formData: propTypes.object.def({}),
+            formBpm: propTypes.bool.def(true),
+        },
+        setup(props){
+            const [registerForm, { setFieldsValue, setProps, getFieldsValue }] = useForm({
+                labelWidth: 150,
+                schemas: getXiaoErFormSchema(props.formData),
+                showActionButtonGroup: false,
+                baseColProps: {span: 24}
+            });
+
+            const formDisabled = computed(()=>{
+                if(props.formData.disabled === false){
+                    return false;
+                }
+                return true;
+            });
+
+            let formData = {};
+            const queryByIdUrl = '/site/okkiSite/queryById';
+            async function initFormData(){
+                let params = {id: props.formData.dataId};
+                const data = await defHttp.get({url: queryByIdUrl, params});
+                formData = {...data}
+                //设置表单的值
+                await setFieldsValue(formData);
+                //默认是禁用
+                await setProps({disabled: formDisabled.value})
+            }
+
+            async function submitForm() {
+                let data = getFieldsValue();
+                let params = Object.assign({}, formData, data);
+                console.log('表单数据', params)
+                await saveXiaoErBind(params)
+            }
+
+            initFormData();
+            
+            return {
+                registerForm,
+                formDisabled,
+                submitForm,
+            }
+        }
+    });
+</script>

+ 67 - 0
jeecgboot-vue3/src/views/okki/site/components/OkkiXiaoErBindModal.vue

@@ -0,0 +1,67 @@
+<template>
+<!--  :height="300"-->
+  <BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="800" @ok="handleSubmit">
+      <BasicForm @register="registerForm"/>
+  </BasicModal>
+</template>
+
+<script lang="ts" setup>
+    import {ref, computed, unref} from 'vue';
+    import {BasicModal, useModalInner} from '/@/components/Modal';
+    import {BasicForm, useForm} from '/@/components/Form/index';
+    import {xiaoErFormSchema} from '../OkkiSite.data';
+    import {saveXiaoErBind} from '../OkkiSite.api';
+    // Emits声明
+    const emit = defineEmits(['register','success']);
+    const isUpdate = ref(true);
+    //表单配置
+    const [registerForm, {setProps,resetFields, setFieldsValue, validate}] = useForm({
+        labelWidth: 120,
+        schemas: xiaoErFormSchema,
+        showActionButtonGroup: false,
+        baseColProps: {span: 24}
+    });
+    //表单赋值
+    const [registerModal, {setModalProps, closeModal}] = useModalInner(async (data) => {
+        //重置表单
+        await resetFields();
+        setModalProps({confirmLoading: false,showCancelBtn:!!data?.showFooter,showOkBtn:!!data?.showFooter});
+        isUpdate.value = !!data?.isUpdate;
+        if (unref(isUpdate)) {
+            //表单赋值
+            await setFieldsValue({
+                ...data.record,
+            });
+        }
+        // 隐藏底部时禁用整个表单
+       setProps({ disabled: !data?.showFooter })
+    });
+    //设置标题
+    const title = computed(() => (!unref(isUpdate) ? '新增' : '小二分配'));
+    //表单提交事件
+    async function handleSubmit(v) {
+        try {
+            let values = await validate();
+            setModalProps({confirmLoading: true});
+            //提交表单
+            await saveXiaoErBind(values);
+            //关闭弹窗
+            closeModal();
+            //刷新列表
+            emit('success');
+        } finally {
+            setModalProps({confirmLoading: false});
+        }
+    }
+</script>
+
+<style lang="less" scoped>
+	/** 时间和数字输入框样式 */
+  :deep(.ant-input-number){
+		width: 100%
+	}
+
+	:deep(.ant-calendar-picker){
+		width: 100%
+	}
+</style>