Jelajahi Sumber

标签管理

wangxy 2 minggu lalu
induk
melakukan
38d09e150d

+ 61 - 0
src/api/company/companyTag.js

@@ -50,4 +50,65 @@ export function exportCompanyTag(query) {
     method: 'get',
     params: query
   })
+}
+
+// 查询销售后台标签管理列表
+export function listTagManage(query) {
+  return request({
+    url: '/company/tagManage/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 新增销售后台标签
+export function addTagManage(data) {
+  return request({
+    url: '/company/tagManage/add',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改销售后台标签状态
+export function updateTagManageStatus(data) {
+  return request({
+    url: '/company/tagManage/status',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除未使用的销售后台标签
+export function delTagManage(tagId) {
+  return request({
+    url: '/company/tagManage/' + tagId,
+    method: 'delete'
+  })
+}
+
+// 下载标签下项目会员
+export function downloadTagManage(tagId) {
+  return request({
+    url: '/company/tagManage/download/' + tagId,
+    method: 'get'
+  })
+}
+
+// 查看标签下项目会员详情
+export function detailTagManage(tagId, query) {
+  return request({
+    url: '/company/tagManage/detail/' + tagId,
+    method: 'get',
+    params: query
+  })
+}
+
+// 导出标签信息
+export function exportTagManage(query) {
+  return request({
+    url: '/company/tagManage/export',
+    method: 'get',
+    params: query
+  })
 }

+ 4 - 3
src/api/user/fsUser.js

@@ -80,10 +80,11 @@ export function exportUser(query) {
 }
 
 // 查询用户标签列表
-export function listUserTags() {
+export function listUserTags(query) {
   return request({
-    url: '/system/tag/list',
-    method: 'get'
+    url: '/user/fsUser/tagList',
+    method: 'get',
+    params: query
   })
 }
 

+ 349 - 0
src/views/company/companyTag/index.vue

@@ -0,0 +1,349 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="90px">
+      <el-form-item label="标签名称" prop="tagName">
+        <el-input
+          v-model="queryParams.tagName"
+          placeholder="请输入标签名称"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="项目名称" prop="projectId">
+        <el-select v-model="queryParams.projectId" placeholder="请选择项目" clearable size="small">
+          <el-option
+            v-for="item in projectOptions"
+            :key="item.dictValue"
+            :label="item.dictLabel"
+            :value="item.dictValue"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="标签状态" prop="status">
+        <el-select v-model="queryParams.status" placeholder="请选择状态" clearable size="small">
+          <el-option label="启用" :value="0" />
+          <el-option label="禁用" :value="1" />
+        </el-select>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="cyan" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          plain
+          type="primary"
+          icon="el-icon-plus"
+          size="mini"
+          @click="handleAdd"
+          v-hasPermi="['company:tagManage:add']"
+        >创建标签</el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+      <el-button
+        type="warning"
+        icon="el-icon-download"
+        size="mini"
+        @click="handleExport"
+        v-hasPermi="['company:tagManage:export']"
+      >导出</el-button>
+    </el-row>
+
+    <el-table v-loading="loading" :data="tagList" border>
+      <el-table-column label="标签名称" align="center" prop="tagName" min-width="160" show-overflow-tooltip />
+      <el-table-column label="标签来源" align="center" prop="tagType" width="120">
+        <template slot-scope="scope">
+          <el-tag :type="scope.row.tagType === 1 ? 'warning' : 'success'">
+            {{ scope.row.tagType === 1 ? '营期标签' : '管理员创建' }}
+          </el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column label="标注人数" align="center" prop="userCount" width="120" />
+      <el-table-column label="使用销售姓名" align="center" prop="companyUserNames" min-width="180" show-overflow-tooltip>
+        <template slot-scope="scope">
+          <span>{{ scope.row.companyUserNames || '-' }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="状态" align="center" prop="status" width="120">
+        <template slot-scope="scope">
+          <el-tag :type="scope.row.status === 0 ? 'success' : 'info'">
+            {{ scope.row.status === 0 ? '启用' : '禁用' }}
+          </el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column label="创建时间" align="center" prop="createTime" width="180">
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.createTime) }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" align="center" width="280" class-name="small-padding fixed-width" fixed="right">
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleStatusChange(scope.row)"
+            v-hasPermi="['company:tagManage:edit']"
+          >修改</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-download"
+            :loading="downloadLoadingId === scope.row.tagId"
+            @click="handleDownload(scope.row)"
+            v-hasPermi="['company:tagManage:export']"
+          >下载</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-view"
+            @click="handleDetail(scope.row)"
+            v-hasPermi="['company:tagManage:list']"
+          >详情</el-button>
+          <el-button
+            v-if="scope.row.canDelete"
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+            v-hasPermi="['company:tagManage:remove']"
+          >删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+      v-show="total > 0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <el-dialog :title="title" :visible.sync="open" width="480px" append-to-body>
+      <el-form ref="form" :model="form" :rules="rules" label-width="90px">
+        <el-form-item label="标签名称" prop="tag">
+          <el-input v-model="form.tag" placeholder="请输入标签名称" maxlength="50" show-word-limit />
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitForm">确 定</el-button>
+        <el-button @click="cancel">取 消</el-button>
+      </div>
+    </el-dialog>
+
+    <el-dialog :title="detailTitle" :visible.sync="detailOpen" width="900px" append-to-body>
+      <el-table v-loading="detailLoading" :data="detailList" border max-height="500">
+        <el-table-column label="昵称" align="center" prop="nickname" min-width="120" show-overflow-tooltip />
+        <el-table-column label="手机号码" align="center" prop="phone" width="130" show-overflow-tooltip />
+        <el-table-column label="项目" align="center" prop="projectId" width="120" show-overflow-tooltip>
+          <template slot-scope="scope">
+            <span>{{ getProjectName(scope.row.projectId) }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="所属员工" align="center" prop="companyUserNickName" width="120" show-overflow-tooltip />
+        <el-table-column label="注册时间" align="center" prop="createTime" width="160">
+          <template slot-scope="scope">
+            <span>{{ parseTime(scope.row.createTime) }}</span>
+          </template>
+        </el-table-column>
+      </el-table>
+      <pagination
+        v-show="detailTotal > 0"
+        :total="detailTotal"
+        :page.sync="detailQueryParams.pageNum"
+        :limit.sync="detailQueryParams.pageSize"
+        @pagination="getDetailList"
+      />
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {
+  listTagManage,
+  addTagManage,
+  updateTagManageStatus,
+  delTagManage,
+  downloadTagManage,
+  detailTagManage,
+  exportTagManage
+} from '@/api/company/companyTag'
+
+export default {
+  name: 'CompanyTagManage',
+  data() {
+    return {
+      loading: false,
+      showSearch: true,
+      total: 0,
+      tagList: [],
+      projectOptions: [],
+      open: false,
+      title: '',
+      downloadLoadingId: null,
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        tagName: null,
+        projectId: null,
+        status: null
+      },
+      form: {},
+      rules: {
+        tag: [
+          { required: true, message: '标签名称不能为空', trigger: 'blur' }
+        ]
+      },
+      detailOpen: false,
+      detailTitle: '',
+      detailLoading: false,
+      detailList: [],
+      detailTotal: 0,
+      detailTagId: null,
+      detailQueryParams: {
+        pageNum: 1,
+        pageSize: 10
+      }
+    }
+  },
+  created() {
+    this.getList()
+    this.getDicts('sys_course_project').then(response => {
+      this.projectOptions = response.data
+    })
+  },
+  methods: {
+    getList() {
+      this.loading = true
+      listTagManage(this.queryParams).then(response => {
+        this.tagList = response.rows || []
+        this.total = response.total || 0
+        this.loading = false
+      }).catch(() => {
+        this.loading = false
+      })
+    },
+    handleQuery() {
+      this.queryParams.pageNum = 1
+      this.getList()
+    },
+    resetQuery() {
+      this.resetForm('queryForm')
+      this.handleQuery()
+    },
+    handleAdd() {
+      this.reset()
+      this.open = true
+      this.title = '创建标签'
+    },
+    reset() {
+      this.form = {
+        tag: null
+      }
+      this.resetForm('form')
+    },
+    cancel() {
+      this.open = false
+      this.reset()
+    },
+    submitForm() {
+      this.$refs.form.validate(valid => {
+        if (!valid) {
+          return
+        }
+        addTagManage(this.form).then(response => {
+          if (response.code === 200) {
+            this.msgSuccess('创建成功')
+            this.open = false
+            this.getList()
+          }
+        })
+      })
+    },
+    handleStatusChange(row) {
+      const nextStatus = row.status === 0 ? 1 : 0
+      const statusText = nextStatus === 0 ? '启用' : '禁用'
+      this.$confirm('是否确认' + statusText + '标签“' + row.tagName + '”?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        return updateTagManageStatus({ tagId: row.tagId, status: nextStatus })
+      }).then(() => {
+        this.msgSuccess(statusText + '成功')
+        this.getList()
+      }).catch(() => {})
+    },
+    handleDelete(row) {
+      this.$confirm('是否确认删除标签"' + row.tagName + '"?', '警告', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        return delTagManage(row.tagId)
+      }).then(() => {
+        this.msgSuccess('删除成功')
+        this.getList()
+      }).catch(() => {})
+    },
+    handleExport() {
+      this.$confirm('是否确认导出所有标签信息?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        return exportTagManage(this.queryParams)
+      }).then(response => {
+        if (response.code === 200) {
+          this.msgSuccess(response.msg)
+          this.download(response.msg)
+        }
+      }).catch(() => {})
+    },
+    handleDownload(row) {
+      this.$confirm('是否确认下载标签"' + row.tagName + '"下的项目会员?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        this.downloadLoadingId = row.tagId
+        return downloadTagManage(row.tagId)
+      }).then(response => {
+        if (response.code === 200) {
+          this.msgSuccess(response.msg)
+          this.download(response.msg)
+        }
+        this.downloadLoadingId = null
+      }).catch(() => {
+        this.downloadLoadingId = null
+      })
+    },
+    handleDetail(row) {
+      this.detailOpen = true
+      this.detailTitle = row.tagName + ' - 项目会员'
+      this.detailTagId = row.tagId
+      this.detailQueryParams.pageNum = 1
+      this.getDetailList()
+    },
+    getDetailList() {
+      this.detailLoading = true
+      detailTagManage(this.detailTagId, this.detailQueryParams).then(response => {
+        this.detailList = response.rows || []
+        this.detailTotal = response.total || 0
+        this.detailLoading = false
+      }).catch(() => {
+        this.detailLoading = false
+      })
+    },
+    getProjectName(projectId) {
+      const item = this.projectOptions.find(o => o.dictValue == projectId)
+      return item ? item.dictLabel : ''
+    }
+  }
+}
+</script>

+ 19 - 25
src/views/member/list.vue

@@ -67,16 +67,16 @@
       <!--          <el-option label="未缺课" value="2" />-->
       <!--        </el-select>-->
       <!--      </el-form-item>-->
-      <!--      <el-form-item label="标签" prop="tagIds">-->
-      <!--        <el-select style="width: 200px" v-model="queryParams.tagIds" placeholder="请选择标签" clearable size="small" multiple>-->
-      <!--          <el-option-->
-      <!--            v-for="item in tagOptions"-->
-      <!--            :key="item.tagId"-->
-      <!--            :label="item.tagName"-->
-      <!--            :value="item.tagId"-->
-      <!--          />-->
-      <!--        </el-select>-->
-      <!--      </el-form-item>-->
+      <el-form-item label="标签" prop="tagIds">
+        <el-select style="width: 200px" v-model="queryParams.tagIds" placeholder="请选择标签" clearable size="small" multiple>
+          <el-option
+            v-for="item in tagOptions"
+            :key="item.tagId"
+            :label="item.tagName"
+            :value="item.tagId"
+          />
+        </el-select>
+      </el-form-item>
       <el-form-item label="绑定时间">
         <el-date-picker
           v-model="dateRange"
@@ -298,8 +298,8 @@
         <el-form-item label="缺课数量" prop="missCourseCount" v-if="form.missCourseCount">
           <el-input v-model="form.missCourseCount" disabled placeholder="缺课数量" />
         </el-form-item>
-        <!-- <el-form-item label="标签" prop="tagIds">
-          <el-select v-model="form.tagIds" disabled placeholder="请选择标签" clearable multiple>
+        <el-form-item label="标签" prop="tagIds">
+          <el-select v-model="form.tagIds" placeholder="请选择标签" clearable multiple>
             <el-option
               v-for="item in tagOptions"
               :key="item.tagId"
@@ -307,10 +307,6 @@
               :value="item.tagId"
             />
           </el-select>
-        </el-form-item> -->
-        <el-form-item label="标签" prop="tag">
-          <el-input v-model="form.tag" disabled  clearable >
-          </el-input>
         </el-form-item>
         <el-form-item label="所属员工" prop="companyUserId">
           <el-select v-model="form.companyUserId" disabled placeholder="请选择所属员工" clearable>
@@ -350,7 +346,7 @@
 </template>
 
 <script>
-import { listUser, getMemberUser, getUser, addUser, updateUser, delUser, exportUser, auditUser,updateMemberUser } from "@/api/user/fsUser";
+import { listUser, getMemberUser, getUser, addUser, updateUser, delUser, exportUser, auditUser, updateMemberUser, listUserTags } from "@/api/user/fsUser";
 import {getUserList} from "@/api/company/companyUser";
 import userDetails from '@/views/store/components/userDetails.vue';
 import { getTask } from '@/api/common'
@@ -535,12 +531,9 @@ export default {
 
     /** 获取标签选项 */
     getTagOptions() {
-      this.tagOptions = [
-        { tagId: "1", tagName: "VIP会员" },
-        { tagId: "2", tagName: "普通会员" },
-        { tagId: "3", tagName: "新用户" },
-        { tagId: "4", tagName: "高频用户" }
-      ];
+      listUserTags().then(response => {
+        this.tagOptions = response.data || [];
+      });
     },
 
     /** 获取销售员工选项 */
@@ -635,7 +628,7 @@ export default {
 
         // 处理标签数据,将字符串转为数组
         if (this.form.tagIds && typeof this.form.tagIds === 'string') {
-          this.form.tagIds = this.form.tagIds.split(',');
+          this.form.tagIds = this.form.tagIds.split(',').filter(Boolean).map(item => Number(item));
         }
 
         this.open = true;
@@ -650,7 +643,8 @@ export default {
           const updateForm={
             id: this.rowInfo.id,
             status: this.form.status,
-            remark: this.form.remark
+            remark: this.form.remark,
+            tagIds: this.form.tagIds || []
           }
           updateMemberUser(updateForm).then(response => {
             if (response.code === 200) {

+ 27 - 27
src/views/member/mylist.vue

@@ -57,16 +57,16 @@
       <!--          <el-option label="未缺课" value="2" />-->
       <!--        </el-select>-->
       <!--      </el-form-item>-->
-      <!--      <el-form-item label="标签" prop="tagIds">-->
-      <!--        <el-select style="width: 200px" v-model="queryParams.tagIds" placeholder="请选择标签" clearable size="small" multiple>-->
-      <!--          <el-option-->
-      <!--            v-for="item in tagOptions"-->
-      <!--            :key="item.tagId"-->
-      <!--            :label="item.tagName"-->
-      <!--            :value="item.tagId"-->
-      <!--          />-->
-      <!--        </el-select>-->
-      <!--      </el-form-item>-->
+      <el-form-item label="标签" prop="tagIds">
+        <el-select style="width: 200px" v-model="queryParams.tagIds" placeholder="请选择标签" clearable size="small" multiple>
+          <el-option
+            v-for="item in tagOptions"
+            :key="item.tagId"
+            :label="item.tagName"
+            :value="item.tagId"
+          />
+        </el-select>
+      </el-form-item>
       <el-form-item label="注册时间">
         <el-date-picker
           v-model="dateRange"
@@ -303,8 +303,8 @@
         <el-form-item label="缺课数量" prop="missCourseCount" v-if="form.missCourseCount">
           <el-input v-model="form.missCourseCount" disabled placeholder="缺课数量" />
         </el-form-item>
-        <!-- <el-form-item label="标签" prop="tagIds">
-          <el-select v-model="form.tagIds" disabled placeholder="请选择标签" clearable multiple>
+        <el-form-item label="标签" prop="tagIds">
+          <el-select v-model="form.tagIds" placeholder="请选择标签" clearable multiple>
             <el-option
               v-for="item in tagOptions"
               :key="item.tagId"
@@ -312,10 +312,6 @@
               :value="item.tagId"
             />
           </el-select>
-        </el-form-item> -->
-        <el-form-item label="标签" prop="tag">
-          <el-input v-model="form.tag" disabled  clearable >
-          </el-input>
         </el-form-item>
         <el-form-item label="所属员工" prop="companyUserId">
           <el-select v-model="form.companyUserId" disabled placeholder="请选择所属员工" clearable>
@@ -376,7 +372,8 @@ import {
   exportUser,
   auditUser,
   myListUser,
-  getSipPhoneNumber
+  getSipPhoneNumber,
+  listUserTags
 } from '@/api/user/fsUser'
 import {transferUser} from "@/api/users/user";
 import {getUserList} from "@/api/company/companyUser";
@@ -587,12 +584,9 @@ export default {
 
     /** 获取标签选项 */
     getTagOptions() {
-      this.tagOptions = [
-        { tagId: "1", tagName: "VIP会员" },
-        { tagId: "2", tagName: "普通会员" },
-        { tagId: "3", tagName: "新用户" },
-        { tagId: "4", tagName: "高频用户" }
-      ];
+      listUserTags().then(response => {
+        this.tagOptions = response.data || [];
+      });
     },
 
     /** 获取销售员工选项 */
@@ -668,8 +662,13 @@ export default {
       this.ids = selection.map(item => item.userId);
       this.single = selection.length !== 1;
       this.multiple = !selection.length;
-      this.companyId = selection[0].companyId;
-      this.companyUserId = selection[0].companyUserId;
+      if (selection.length > 0) {
+        this.companyId = selection[0].companyId;
+        this.companyUserId = selection[0].companyUserId;
+      } else {
+        this.companyId = null;
+        this.companyUserId = null;
+      }
     },
 
     /** 新增按钮操作 */
@@ -689,7 +688,7 @@ export default {
 
         // 处理标签数据,将字符串转为数组
         if (this.form.tagIds && typeof this.form.tagIds === 'string') {
-          this.form.tagIds = this.form.tagIds.split(',');
+          this.form.tagIds = this.form.tagIds.split(',').filter(Boolean).map(item => Number(item));
         }
 
         this.open = true;
@@ -704,7 +703,8 @@ export default {
           const updateForm={
             id: this.rowInfo.id,
             status: this.form.status,
-            remark: this.form.remark
+            remark: this.form.remark,
+            tagIds: this.form.tagIds || []
           }
           updateMemberUser(updateForm).then(response => {
             if (response.code === 200) {