From 634e41ae432cfa49f69577bd2fa95e86257c0205 Mon Sep 17 00:00:00 2001
From: zhangwencui <1064582902@qq.com>
Date: 星期四, 05 三月 2026 13:04:30 +0800
Subject: [PATCH] 客户档案回访提醒
---
src/views/basicData/customerFile/index.vue | 352 ++++++++++++++++++++++++++++++++++++++++++++++++--
src/api/basicData/customerFile.js | 16 ++
2 files changed, 353 insertions(+), 15 deletions(-)
diff --git a/src/api/basicData/customerFile.js b/src/api/basicData/customerFile.js
index 8685664..6a5f049 100644
--- a/src/api/basicData/customerFile.js
+++ b/src/api/basicData/customerFile.js
@@ -74,4 +74,20 @@
url: '/basic/customer-follow/'+id,
method: 'delete',
})
+}
+
+// 鍥炶鎻愰啋-鏂板/鏇存柊
+export function addReturnVisit(data) {
+ return request({
+ url: '/basic/customer-follow/return-visit',
+ method: 'post',
+ data: data
+ })
+}
+// 鑾峰彇鍥炶鎻愰啋璇︽儏
+export function getReturnVisit(id) {
+ return request({
+ url: '/basic/customer-follow/return-visit/' + id,
+ method: 'get'
+ })
}
\ No newline at end of file
diff --git a/src/views/basicData/customerFile/index.vue b/src/views/basicData/customerFile/index.vue
index 1437beb..ad1c5bb 100644
--- a/src/views/basicData/customerFile/index.vue
+++ b/src/views/basicData/customerFile/index.vue
@@ -267,9 +267,9 @@
<el-form-item label="鎻愰啋鏃堕棿锛�"
prop="reminderTime">
<el-date-picker v-model="reminderForm.reminderTime"
- type="date"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
+ type="datetime"
+ value-format="YYYY-MM-DD HH:mm:ss"
+ format="YYYY-MM-DD HH:mm:ss"
placeholder="璇烽�夋嫨鎻愰啋鏃堕棿"
style="width: 100%" />
</el-form-item>
@@ -369,7 +369,7 @@
<!-- 瀹㈡埛璇︽儏瀵硅瘽妗� -->
<el-dialog title="瀹㈡埛璇︽儏"
v-model="detailDialogVisible"
- width="800px"
+ width="1000px"
@close="closeDetailDialog">
<!-- 瀹㈡埛鍩烘湰淇℃伅 -->
<div class="detail-section">
@@ -481,14 +481,29 @@
label="璺熻繘鏂瑰紡"
width="100" />
<el-table-column prop="followUpLevel"
- label="璺熻繘绋嬪害"
- width="120" />
+ label="璺熻繘绋嬪害" />
<el-table-column prop="followerUserName"
label="璺熻繘浜�"
width="100" />
<el-table-column prop="content"
label="鍐呭"
show-overflow-tooltip />
+ <el-table-column label="闄勪欢"
+ width="100"
+ align="center">
+ <template #default="{ row }">
+ <el-button type="info"
+ link
+ size="small"
+ @click="openAttachmentDialog(row)">
+ <el-icon>
+ <Paperclip />
+ </el-icon>
+ 闄勪欢
+ <!-- {{ row.fileList && row.fileList.length > 0 ? row.fileList.length : '涓婁紶' }} -->
+ </el-button>
+ </template>
+ </el-table-column>
<el-table-column label="鎿嶄綔"
width="150"
align="center">
@@ -519,12 +534,90 @@
</div>
</template>
</el-dialog>
+ <!-- 闄勪欢涓婁紶寮圭獥 -->
+ <el-dialog title="闄勪欢绠$悊"
+ v-model="attachmentDialogVisible"
+ width="600px"
+ @close="closeAttachmentDialog">
+ <div class="attachment-section">
+ <div class="upload-area">
+ <el-upload ref="attachmentUploadRef"
+ :action="getAttachmentUploadUrl()"
+ :headers="attachmentUploadHeaders"
+ :file-list="currentAttachmentList"
+ :on-success="handleAttachmentSuccess"
+ :on-error="handleAttachmentError"
+ :on-remove="handleAttachmentRemove"
+ :before-upload="beforeAttachmentUpload"
+ multiple
+ :limit="10"
+ name="files">
+ <el-button type="primary">
+ <el-icon>
+ <Upload />
+ </el-icon>
+ 涓婁紶闄勪欢
+ </el-button>
+ <template #tip>
+ <div class="el-upload__tip">
+ 鏀寔涓婁紶鍥剧墖銆佹枃妗g瓑鏂囦欢锛屽崟涓枃浠朵笉瓒呰繃50MB
+ </div>
+ </template>
+ </el-upload>
+ </div>
+ <div v-if="currentAttachmentList.length > 0"
+ class="attachment-list">
+ <h4>宸蹭笂浼犻檮浠讹細</h4>
+ <el-table :data="currentAttachmentList"
+ border
+ size="small">
+ <el-table-column prop="name"
+ label="鏂囦欢鍚�"
+ show-overflow-tooltip />
+ <el-table-column prop="size"
+ label="澶у皬"
+ width="100">
+ <template #default="{ row }">
+ {{ formatFileSize(row.size) }}
+ </template>
+ </el-table-column>
+ <el-table-column label="鎿嶄綔"
+ width="120"
+ align="center">
+ <template #default="{ row, $index }">
+ <el-button type="primary"
+ link
+ size="small"
+ @click="downloadAttachment(row)">
+ 涓嬭浇
+ </el-button>
+ <el-button type="danger"
+ link
+ size="small"
+ @click="deleteAttachment(row, $index)">
+ 鍒犻櫎
+ </el-button>
+ </template>
+ </el-table-column>
+ </el-table>
+ </div>
+ <div v-else
+ class="no-attachment">
+ 鏆傛棤闄勪欢
+ </div>
+ </div>
+ <template #footer>
+ <div class="dialog-footer">
+ <el-button @click="closeAttachmentDialog">鍏抽棴</el-button>
+ </div>
+ </template>
+ </el-dialog>
</div>
</template>
<script setup>
import { onMounted, ref, reactive, getCurrentInstance, toRefs } from "vue";
- import { Search } from "@element-plus/icons-vue";
+ import { Search, Paperclip, Upload } from "@element-plus/icons-vue";
import {
addCustomer,
delCustomer,
@@ -534,6 +627,8 @@
addCustomerFollow,
updateCustomerFollow,
delCustomerFollow,
+ addReturnVisit,
+ getReturnVisit,
} from "@/api/basicData/customerFile.js";
import { ElMessageBox } from "element-plus";
import { userListNoPage } from "@/api/system/user.js";
@@ -545,6 +640,7 @@
// 鍥炶鎻愰啋鐩稿叧
const reminderDialogVisible = ref(false);
const reminderFormRef = ref();
+ const currentCustomerId = ref();
const reminderForm = reactive({
customerName: "",
reminderSwitch: false,
@@ -602,6 +698,22 @@
maintenanceTime: "",
});
const negotiationRecords = ref([]);
+
+ // 闄勪欢鐩稿叧
+ const attachmentDialogVisible = ref(false);
+ const attachmentUploadRef = ref();
+ const currentAttachmentList = ref([]);
+ const currentFollowRecord = ref({});
+ const attachmentUploadHeaders = { Authorization: "Bearer " + getToken() };
+
+ // 鍔ㄦ�佹瀯寤轰笂浼燯RL
+ const getAttachmentUploadUrl = () => {
+ const baseUrl =
+ import.meta.env.VITE_APP_BASE_API + "/basic/customer-follow/upload";
+ return currentFollowRecord.value.id
+ ? `${baseUrl}/${currentFollowRecord.value.id}`
+ : baseUrl;
+ };
const tableColumn = ref([
{
@@ -1003,10 +1115,25 @@
// 鎵撳紑鍥炶鎻愰啋寮圭獥
const openReminderDialog = row => {
+ currentCustomerId.value = row.id;
reminderForm.customerName = row.customerName;
reminderForm.reminderSwitch = false;
reminderForm.reminderContent = "";
reminderForm.reminderTime = "";
+
+ // 灏濊瘯鑾峰彇宸叉湁鐨勫洖璁挎彁閱�
+ getReturnVisit(row.id)
+ .then(res => {
+ if (res.code === 200 && res.data) {
+ reminderForm.reminderSwitch = res.data.isEnabled === 1;
+ reminderForm.reminderContent = res.data.content;
+ reminderForm.reminderTime = res.data.reminderTime;
+ reminderForm.id = res.data.id;
+ }
+ })
+ .catch(error => {
+ console.error("鑾峰彇鍥炶鎻愰啋澶辫触:", error);
+ });
reminderDialogVisible.value = true;
};
@@ -1016,20 +1143,48 @@
proxy.resetForm("reminderFormRef");
reminderDialogVisible.value = false;
};
+ const submitvalue = ref({});
// 鎻愪氦鍥炶鎻愰啋
const submitReminderForm = () => {
+ console.log("鎻愪氦鍥炶鎻愰啋鏁版嵁:", userStore.id, userStore);
proxy.$refs.reminderFormRef.validate(valid => {
if (valid) {
- // 杩欓噷鍋囪涓�涓帴鍙f潵鎻愪氦鍥炶鎻愰啋鏁版嵁
- // 瀹為檯椤圭洰涓渶瑕佹牴鎹悗绔帴鍙h繘琛岃皟鏁�
- console.log("鎻愪氦鍥炶鎻愰啋鏁版嵁:", reminderForm);
+ if (reminderForm.id) {
+ submitvalue.value = {
+ id: reminderForm.id,
+ customerId: currentCustomerId.value,
+ isEnabled: reminderForm.reminderSwitch ? 1 : 0,
+ content: reminderForm.reminderContent,
+ reminderTime: reminderForm.reminderTime,
+ remindUserId: userStore.id,
+ };
+ } else {
+ submitvalue.value = {
+ customerId: currentCustomerId.value,
+ isEnabled: reminderForm.reminderSwitch ? 1 : 0,
+ content: reminderForm.reminderContent,
+ reminderTime: reminderForm.reminderTime,
+ remindUserId: userStore.id,
+ };
+ }
- // 妯℃嫙鎺ュ彛璋冪敤
- setTimeout(() => {
- proxy.$modal.msgSuccess("鍥炶鎻愰啋璁剧疆鎴愬姛");
- closeReminderDialog();
- }, 1000);
+ console.log("鎻愪氦鍥炶鎻愰啋鏁版嵁:", submitvalue.value);
+
+ // 璋冪敤鎺ュ彛
+ addReturnVisit(submitvalue.value)
+ .then(res => {
+ if (res.code === 200) {
+ proxy.$modal.msgSuccess("鍥炶鎻愰啋璁剧疆鎴愬姛");
+ closeReminderDialog();
+ } else {
+ proxy.$modal.msgError(res.msg || "璁剧疆澶辫触");
+ }
+ })
+ .catch(error => {
+ console.error("璁剧疆鍥炶鎻愰啋澶辫触:", error);
+ proxy.$modal.msgError("璁剧疆澶辫触");
+ });
}
});
};
@@ -1188,6 +1343,143 @@
});
};
+ // 鎵撳紑闄勪欢寮圭獥
+ const openAttachmentDialog = row => {
+ currentFollowRecord.value = row;
+ // 杞崲涓虹鍚圗lement Plus fileList鏍煎紡鐨勬暟缁�
+ currentAttachmentList.value = (row.fileList || []).map((file, index) => ({
+ name: file.fileName,
+ url: file.fileUrl,
+ size: file.fileSize,
+ id: file.id,
+ uid: file.id || index,
+ status: "success",
+ }));
+
+ attachmentDialogVisible.value = true;
+ };
+
+ // 鍏抽棴闄勪欢寮圭獥
+ const closeAttachmentDialog = () => {
+ attachmentDialogVisible.value = false;
+ currentFollowRecord.value = {};
+ currentAttachmentList.value = [];
+ };
+
+ // 闄勪欢涓婁紶鎴愬姛
+ const handleAttachmentSuccess = (response, file, fileList) => {
+ if (response.code === 200) {
+ proxy.$modal.msgSuccess("涓婁紶鎴愬姛");
+ // 鏇存柊褰撳墠璁板綍鐨勯檮浠跺垪琛�
+ currentAttachmentList.value = fileList.map(item => ({
+ name: item.name,
+ size: item.size,
+ url: item.response?.data?.url || item.url,
+ id: item.response?.data?.id,
+ uid: item.uid,
+ status: "success",
+ }));
+ // 鏇存柊鍘熻褰曚腑鐨刦iles瀛楁
+ if (currentFollowRecord.value) {
+ currentFollowRecord.value.files = [...currentAttachmentList.value];
+ }
+ } else {
+ proxy.$modal.msgError(response.msg || "涓婁紶澶辫触");
+ }
+ };
+
+ // 闄勪欢涓婁紶澶辫触
+ const handleAttachmentError = (error, file, fileList) => {
+ console.error("涓婁紶澶辫触:", error);
+ proxy.$modal.msgError("涓婁紶澶辫触");
+ };
+
+ // 闄勪欢绉婚櫎
+ const handleAttachmentRemove = (file, fileList) => {
+ currentAttachmentList.value = fileList;
+ // 鏇存柊鍘熻褰曚腑鐨刦iles瀛楁
+ if (currentFollowRecord.value) {
+ currentFollowRecord.value.files = [...fileList];
+ }
+ };
+
+ // 闄勪欢涓婁紶鍓嶆牎楠�
+ const beforeAttachmentUpload = file => {
+ const maxSize = 50 * 1024 * 1024; // 50MB
+ if (file.size > maxSize) {
+ proxy.$modal.msgError("鏂囦欢澶у皬涓嶈兘瓒呰繃50MB");
+ return false;
+ }
+ return true;
+ };
+
+ // 鏍煎紡鍖栨枃浠跺ぇ灏�
+ const formatFileSize = size => {
+ if (size < 1024) {
+ return size + " B";
+ } else if (size < 1024 * 1024) {
+ return (size / 1024).toFixed(2) + " KB";
+ } else {
+ return (size / (1024 * 1024)).toFixed(2) + " MB";
+ }
+ };
+
+ // 涓嬭浇闄勪欢
+ const downloadAttachment = row => {
+ if (row.url) {
+ // proxy.download(row.url, {}, row.name);
+ proxy.$download.name(row.url);
+ } else {
+ proxy.$modal.msgError("涓嬭浇閾炬帴涓嶅瓨鍦�");
+ }
+ };
+
+ // 鍒犻櫎闄勪欢
+ const deleteAttachment = (row, index) => {
+ ElMessageBox.confirm("纭畾瑕佸垹闄よ繖涓檮浠跺悧锛�", "鍒犻櫎鎻愮ず", {
+ confirmButtonText: "纭畾",
+ cancelButtonText: "鍙栨秷",
+ type: "warning",
+ })
+ .then(() => {
+ // 璋冪敤鍚庣鎺ュ彛鍒犻櫎闄勪欢
+ const deleteUrl =
+ import.meta.env.VITE_APP_BASE_API +
+ "/basic/customer-follow/file/" +
+ row.id;
+ fetch(deleteUrl, {
+ method: "DELETE",
+ headers: {
+ Authorization: "Bearer " + getToken(),
+ "Content-Type": "application/json",
+ },
+ })
+ .then(response => response.json())
+ .then(res => {
+ if (res.code === 200) {
+ // 鍒犻櫎鎴愬姛鍚庢洿鏂版湰鍦版枃浠跺垪琛�
+ currentAttachmentList.value.splice(index, 1);
+ // 鏇存柊鍘熻褰曚腑鐨刦iles瀛楁
+ if (currentFollowRecord.value) {
+ currentFollowRecord.value.files = [
+ ...currentAttachmentList.value,
+ ];
+ }
+ proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+ } else {
+ proxy.$modal.msgError(res.msg || "鍒犻櫎澶辫触");
+ }
+ })
+ .catch(error => {
+ console.error("鍒犻櫎闄勪欢澶辫触:", error);
+ proxy.$modal.msgError("鍒犻櫎澶辫触");
+ });
+ })
+ .catch(() => {
+ proxy.$modal.msg("宸插彇娑堝垹闄�");
+ });
+ };
+
// 鑾峰彇褰撳墠鏃ユ湡骞舵牸寮忓寲涓� YYYY-MM-DD
function getCurrentDate() {
const today = new Date();
@@ -1255,4 +1547,34 @@
color: #999;
font-size: 14px;
}
+
+ .attachment-section {
+ .upload-area {
+ margin-bottom: 20px;
+ padding: 20px;
+ background-color: #f9f9f9;
+ border-radius: 4px;
+ border: 1px dashed #d9d9d9;
+
+ .el-upload__tip {
+ margin-top: 10px;
+ color: #909399;
+ }
+ }
+
+ .attachment-list {
+ h4 {
+ margin: 0 0 10px 0;
+ font-size: 14px;
+ color: #606266;
+ }
+ }
+
+ .no-attachment {
+ text-align: center;
+ padding: 40px;
+ color: #909399;
+ font-size: 14px;
+ }
+ }
</style>
--
Gitblit v1.9.3