|
@@ -16,7 +16,7 @@
|
|
|
clearable
|
|
clearable
|
|
|
/>
|
|
/>
|
|
|
<div v-if="filteredTeam.length" class="team-list">
|
|
<div v-if="filteredTeam.length" class="team-list">
|
|
|
- <div v-for="item in filteredTeam" :key="item.id" class="team-item">
|
|
|
|
|
|
|
+ <div v-for="(item, index) in filteredTeam" :key="item.id" class="team-item">
|
|
|
<el-avatar :size="36" :src="item.avatar" class="user-avatar">
|
|
<el-avatar :size="36" :src="item.avatar" class="user-avatar">
|
|
|
<img v-if="item.avatar" :src="item.avatar" />
|
|
<img v-if="item.avatar" :src="item.avatar" />
|
|
|
<el-icon v-else><User /></el-icon>
|
|
<el-icon v-else><User /></el-icon>
|
|
@@ -25,8 +25,8 @@
|
|
|
<div class="user-main">
|
|
<div class="user-main">
|
|
|
<span class="user-name">{{ item.realName || item.userName || '成员' }}</span>
|
|
<span class="user-name">{{ item.realName || item.userName || '成员' }}</span>
|
|
|
<div class="user-tags">
|
|
<div class="user-tags">
|
|
|
- <span v-if="item.izManager === 1" class="leader-tag-simple">负责人</span>
|
|
|
|
|
- <span class="user-role-text">{{ item.roleName || '业务负责人' }}</span>
|
|
|
|
|
|
|
+ <span v-if="item.izManager === 1 || index === 0" class="leader-tag-simple">负责人</span>
|
|
|
|
|
+ <span class="user-role-text">{{ item.roleName }}</span>
|
|
|
<span class="permission-text-simple">{{ item.updateAccredit === 1 ? '修改权限' : '仅查看' }}</span>
|
|
<span class="permission-text-simple">{{ item.updateAccredit === 1 ? '修改权限' : '仅查看' }}</span>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
@@ -57,8 +57,8 @@
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
- <div v-if="recordList.length" class="record-list">
|
|
|
|
|
- <div v-for="(record, index) in recordList" :key="index" class="record-item">
|
|
|
|
|
|
|
+ <div v-if="filteredRecords.length" class="record-list">
|
|
|
|
|
+ <div v-for="(record, index) in filteredRecords" :key="index" class="record-item">
|
|
|
<div class="record-card">
|
|
<div class="record-card">
|
|
|
<div class="record-header">
|
|
<div class="record-header">
|
|
|
<span class="record-user">{{ getRecordUser(record) }}</span>
|
|
<span class="record-user">{{ getRecordUser(record) }}</span>
|
|
@@ -97,15 +97,10 @@
|
|
|
<div v-for="log in logList" :key="log.id" class="log-row">
|
|
<div v-for="log in logList" :key="log.id" class="log-row">
|
|
|
<span class="log-time">{{ log.operTime || log.time }}</span>
|
|
<span class="log-time">{{ log.operTime || log.time }}</span>
|
|
|
<span class="log-user">{{ log.operName || log.userName }}</span>
|
|
<span class="log-user">{{ log.operName || log.userName }}</span>
|
|
|
- <span class="log-content" :class="{ 'link-style': log.isLink }">
|
|
|
|
|
- {{
|
|
|
|
|
- (log.operAction === 1 ? '创建了 ' :
|
|
|
|
|
- log.operAction === 2 ? '编辑了 : ' :
|
|
|
|
|
- log.operAction === 3 ? '删除了 ' : '') +
|
|
|
|
|
- (log.operContent || log.content || '执行了操作')
|
|
|
|
|
- }}
|
|
|
|
|
|
|
+ <span class="log-content">
|
|
|
|
|
+ {{ formatLogContent(log) }}{{ (log.subContent || log.operAction) ? ':' : '' }}
|
|
|
</span>
|
|
</span>
|
|
|
- <span v-if="log.subContent" class="log-sub-content" :class="{ 'link-style': log.subIsLink }">{{ log.subContent }}</span>
|
|
|
|
|
|
|
+ <span v-if="log.subContent" class="log-sub-content blue-style">{{ log.subContent }}</span>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
<div v-else class="empty-status">暂无操作日志</div>
|
|
<div v-else class="empty-status">暂无操作日志</div>
|
|
@@ -294,11 +289,12 @@
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
|
|
|
|
|
<el-form-item label="权限:">
|
|
<el-form-item label="权限:">
|
|
|
- <el-radio-group v-if="isEditMember" v-model="memberForm.updateAccredit">
|
|
|
|
|
- <el-radio :label="0">仅查看</el-radio>
|
|
|
|
|
- <el-radio :label="1">修改权限</el-radio>
|
|
|
|
|
- </el-radio-group>
|
|
|
|
|
- <el-checkbox v-else v-model="memberForm.updateAccredit" :true-value="1" :false-value="0">分配修改权限</el-checkbox>
|
|
|
|
|
|
|
+ <div class="member-form">
|
|
|
|
|
+ <el-radio-group v-model="memberForm.updateAccredit">
|
|
|
|
|
+ <el-radio :label="0">仅查看</el-radio>
|
|
|
|
|
+ <el-radio :label="1">修改权限</el-radio>
|
|
|
|
|
+ </el-radio-group>
|
|
|
|
|
+ </div>
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
</el-form>
|
|
</el-form>
|
|
|
|
|
|
|
@@ -319,7 +315,7 @@ import { listTeamMember, delTeamMember, addTeamMember, updateTeamMember } from "
|
|
|
import { listRecord, addRecord } from "@/api/visit/record";
|
|
import { listRecord, addRecord } from "@/api/visit/record";
|
|
|
import { listOperateLog } from "@/api/visit/operateLog";
|
|
import { listOperateLog } from "@/api/visit/operateLog";
|
|
|
import { listUser } from "@/api/system/user/index";
|
|
import { listUser } from "@/api/system/user/index";
|
|
|
-import { selectStaffOptionList } from "@/api/customer/crmStaff";
|
|
|
|
|
|
|
+import { listComStaff } from "@/api/system/comStaff/index";
|
|
|
import { globalHeaders } from "@/utils/request";
|
|
import { globalHeaders } from "@/utils/request";
|
|
|
|
|
|
|
|
const proxy = getCurrentInstance().proxy;
|
|
const proxy = getCurrentInstance().proxy;
|
|
@@ -389,6 +385,7 @@ const memberForm = reactive({
|
|
|
realName: '',
|
|
realName: '',
|
|
|
roleCode: '',
|
|
roleCode: '',
|
|
|
updateAccredit: 0,
|
|
updateAccredit: 0,
|
|
|
|
|
+ izManager: 0,
|
|
|
objectNo: ''
|
|
objectNo: ''
|
|
|
});
|
|
});
|
|
|
|
|
|
|
@@ -401,6 +398,14 @@ const filteredTeam = computed(() => {
|
|
|
return teamList.value.filter(m => (m.realName || '').includes(memberSearch.value));
|
|
return teamList.value.filter(m => (m.realName || '').includes(memberSearch.value));
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
|
|
+const filteredRecords = computed(() => {
|
|
|
|
|
+ return recordList.value.filter(record => {
|
|
|
|
|
+ const no = String(record.recordsNo || record.scheduleNo || '');
|
|
|
|
|
+ // 如果没有编号,默认显示(可能是脏数据),如果有编号,则要求是纯数字
|
|
|
|
|
+ return !no || /^\d+$/.test(no);
|
|
|
|
|
+ });
|
|
|
|
|
+});
|
|
|
|
|
+
|
|
|
// 统一计算当前业务的数据类型
|
|
// 统一计算当前业务的数据类型
|
|
|
const computedDataType = computed(() => {
|
|
const computedDataType = computed(() => {
|
|
|
const typeMap = {
|
|
const typeMap = {
|
|
@@ -494,8 +499,8 @@ const loadUsers = async () => {
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
const loadStaffs = async () => {
|
|
const loadStaffs = async () => {
|
|
|
- selectStaffOptionList().then(res => {
|
|
|
|
|
- staffOptions.value = res.data || [];
|
|
|
|
|
|
|
+ listComStaff({ pageSize: 1000 }).then(res => {
|
|
|
|
|
+ staffOptions.value = res.rows || res.data || [];
|
|
|
});
|
|
});
|
|
|
};
|
|
};
|
|
|
|
|
|
|
@@ -520,6 +525,7 @@ const handleAddMember = () => {
|
|
|
realName: '',
|
|
realName: '',
|
|
|
roleCode: '',
|
|
roleCode: '',
|
|
|
updateAccredit: 0,
|
|
updateAccredit: 0,
|
|
|
|
|
+ izManager: 0,
|
|
|
objectNo: computedObjectNo.value,
|
|
objectNo: computedObjectNo.value,
|
|
|
dataType: computedDataType.value
|
|
dataType: computedDataType.value
|
|
|
});
|
|
});
|
|
@@ -534,6 +540,7 @@ const handleEditMember = (item) => {
|
|
|
realName: item.realName,
|
|
realName: item.realName,
|
|
|
roleCode: item.roleCode,
|
|
roleCode: item.roleCode,
|
|
|
updateAccredit: item.updateAccredit || 0,
|
|
updateAccredit: item.updateAccredit || 0,
|
|
|
|
|
+ izManager: item.izManager || 0,
|
|
|
objectNo: computedObjectNo.value,
|
|
objectNo: computedObjectNo.value,
|
|
|
dataType: computedDataType.value
|
|
dataType: computedDataType.value
|
|
|
});
|
|
});
|
|
@@ -679,6 +686,47 @@ const getRecordUser = (record) => {
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+// 格式化日志内容,移除“了”字并避免重复
|
|
|
|
|
+const formatLogContent = (log) => {
|
|
|
|
|
+ const actionMap = {
|
|
|
|
|
+ 1: '添加',
|
|
|
|
|
+ 2: '编辑',
|
|
|
|
|
+ 3: '删除'
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ const prefix = actionMap[log.operAction];
|
|
|
|
|
+ let content = (log.operContent || log.content || '执行操作').trim();
|
|
|
|
|
+
|
|
|
|
|
+ // 移除开头可能存在的冒号
|
|
|
|
|
+ content = content.replace(/^[::\s]+/, '');
|
|
|
|
|
+
|
|
|
|
|
+ if (prefix) {
|
|
|
|
|
+ // 定义常见同义词(包含带“了”和不带“了”的情况)
|
|
|
|
|
+ const synonyms = {
|
|
|
|
|
+ '添加': ['创建了', '创建', '新增了', '新增', '添加了', '添加', '录入了', '录入'],
|
|
|
|
|
+ '编辑': ['编辑了', '编辑', '修改了', '修改', '更新了', '更新', '完善了', '完善'],
|
|
|
|
|
+ '删除': ['删除了', '删除', '移除了', '移除']
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ const currentSynonyms = synonyms[prefix] || [prefix];
|
|
|
|
|
+ // 优先匹配长度较长的词(如“修改了”优先于“修改”)
|
|
|
|
|
+ currentSynonyms.sort((a, b) => b.length - a.length);
|
|
|
|
|
+
|
|
|
|
|
+ for (const syn of currentSynonyms) {
|
|
|
|
|
+ if (content.startsWith(syn)) {
|
|
|
|
|
+ const rest = content.substring(syn.length).trim().replace(/^[::\s]+/, '');
|
|
|
|
|
+ return rest ? `${prefix} ${rest}` : prefix;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return `${prefix} ${content}`;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 对于其他没有 action 映射的内容,也尝试移除“了”
|
|
|
|
|
+ return content.replace('了', '');
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
onMounted(() => {
|
|
onMounted(() => {
|
|
|
loadUsers();
|
|
loadUsers();
|
|
|
loadStaffs();
|
|
loadStaffs();
|
|
@@ -842,9 +890,9 @@ onMounted(() => {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
-.log-list-new { .log-row { font-size: 13px; line-height: 2.2; color: #666; display: flex; flex-wrap: wrap; align-items: center; .log-time { color: #999; margin-right: 12px; width: 140px; } .log-user { color: #409eff; margin-right: 8px; cursor: pointer; } .link-style { color: #409eff; cursor: pointer; &:hover { text-decoration: underline; } } } }
|
|
|
|
|
|
|
+.log-list-new { .log-row { font-size: 13px; line-height: 2.2; color: #666; display: flex; flex-wrap: wrap; align-items: center; .log-time { color: #999; margin-right: 15px; width: 140px; } .log-user { color: #409eff; margin-right: 12px; cursor: pointer; } .log-content { color: #666; margin-right: 4px; } .blue-style { color: #409eff; cursor: pointer; } .link-style { color: #409eff; cursor: pointer; &:hover { text-decoration: underline; } } } }
|
|
|
.manage-info-list { padding-top: 10px; .m-item { display: flex; align-items: center; margin-bottom: 20px; font-size: 13px; .m-label { color: #999; width: 80px; } .m-value { color: #333; } } }
|
|
.manage-info-list { padding-top: 10px; .m-item { display: flex; align-items: center; margin-bottom: 20px; font-size: 13px; .m-label { color: #999; width: 80px; } .m-value { color: #333; } } }
|
|
|
.image-uploader { .uploader-icon { font-size: 28px; color: #8c939d; width: 80px; height: 80px; text-align: center; line-height: 80px; border: 1px dashed #d9d9d9; border-radius: 4px; } .uploaded-image { width: 80px; height: 80px; display: block; border-radius: 4px; object-fit: cover; } }
|
|
.image-uploader { .uploader-icon { font-size: 28px; color: #8c939d; width: 80px; height: 80px; text-align: center; line-height: 80px; border: 1px dashed #d9d9d9; border-radius: 4px; } .uploaded-image { width: 80px; height: 80px; display: block; border-radius: 4px; object-fit: cover; } }
|
|
|
-.link-style { color: #409eff; cursor: pointer; }
|
|
|
|
|
|
|
+.link-style, .blue-style { color: #409eff; cursor: pointer; }
|
|
|
.empty-status { text-align: center; color: #999; font-size: 13px; padding: 60px 0; }
|
|
.empty-status { text-align: center; color: #999; font-size: 13px; padding: 60px 0; }
|
|
|
</style>
|
|
</style>
|