From aabd8037a6c8c86b9e7d26e4dfdf57e6a6959e1b Mon Sep 17 00:00:00 2001 From: wong <106998207@qq.com> Date: Mon, 5 Jan 2026 10:44:08 +0800 Subject: [PATCH] =?UTF-8?q?=E5=90=8C=E6=AD=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cunkebao/.gitignore | 4 + Server/.gitignore | 7 ++ Server/index.html | 40 --------- ...a_Vv8VOhdcPRmNHh_J_flKMHVwUywOIwT-F9iiA8p4 | 1 - Store_vue/.gitignore | 4 + Touchkebao/.gitignore | 4 +- .../components/MomentPublish.module.scss | 79 ++++++++++++++--- .../components/MomentPublish.tsx | 87 ++++++++++++++----- Touchkebao/vite.config.mts | 2 +- 9 files changed, 151 insertions(+), 77 deletions(-) delete mode 100644 Server/index.html delete mode 100644 Server/public/.well-known/acme-challenge/Pa_Vv8VOhdcPRmNHh_J_flKMHVwUywOIwT-F9iiA8p4 create mode 100644 Store_vue/.gitignore diff --git a/Cunkebao/.gitignore b/Cunkebao/.gitignore index a2bf4a07..25615b99 100644 --- a/Cunkebao/.gitignore +++ b/Cunkebao/.gitignore @@ -5,3 +5,7 @@ yarn.lock .env .DS_Store dist/* +.cursorindexingignore +*.zip +.idea/ +.next/ diff --git a/Server/.gitignore b/Server/.gitignore index a00e9bea..39ab957f 100644 --- a/Server/.gitignore +++ b/Server/.gitignore @@ -9,3 +9,10 @@ vendor /404.html # SpecStory explanation file .specstory/.what-is-this.md +/ +.cursorindexingignore +.user.ini +nginx.htaccess +.cursor/ +thinkphp/ +public/static/ diff --git a/Server/index.html b/Server/index.html deleted file mode 100644 index 40e91ccf..00000000 --- a/Server/index.html +++ /dev/null @@ -1,40 +0,0 @@ - - - - - 恭喜,站点创建成功! - - - -
-

恭喜, 站点创建成功!

-

这是默认index.html,本页面由系统自动生成

- -
- - \ No newline at end of file diff --git a/Server/public/.well-known/acme-challenge/Pa_Vv8VOhdcPRmNHh_J_flKMHVwUywOIwT-F9iiA8p4 b/Server/public/.well-known/acme-challenge/Pa_Vv8VOhdcPRmNHh_J_flKMHVwUywOIwT-F9iiA8p4 deleted file mode 100644 index c8b74e0e..00000000 --- a/Server/public/.well-known/acme-challenge/Pa_Vv8VOhdcPRmNHh_J_flKMHVwUywOIwT-F9iiA8p4 +++ /dev/null @@ -1 +0,0 @@ -Pa_Vv8VOhdcPRmNHh_J_flKMHVwUywOIwT-F9iiA8p4.2wKeISBpPoGcCt72TdgVrBMxtnnieXof2OZkRdHKCJI \ No newline at end of file diff --git a/Store_vue/.gitignore b/Store_vue/.gitignore new file mode 100644 index 00000000..86527281 --- /dev/null +++ b/Store_vue/.gitignore @@ -0,0 +1,4 @@ +.cursorindexingignore +.specstory/ +node_modules/ +unpackage/ diff --git a/Touchkebao/.gitignore b/Touchkebao/.gitignore index dcf55aed..34d25ecb 100644 --- a/Touchkebao/.gitignore +++ b/Touchkebao/.gitignore @@ -3,4 +3,6 @@ dist/ build/ yarn.lock .env -.DS_Store \ No newline at end of file +.DS_Store +.specstory/ +.cursorindexingignore diff --git a/Touchkebao/src/pages/pc/ckbox/powerCenter/content-management/components/MomentPublish.module.scss b/Touchkebao/src/pages/pc/ckbox/powerCenter/content-management/components/MomentPublish.module.scss index 53c6ff14..38199d6e 100644 --- a/Touchkebao/src/pages/pc/ckbox/powerCenter/content-management/components/MomentPublish.module.scss +++ b/Touchkebao/src/pages/pc/ckbox/powerCenter/content-management/components/MomentPublish.module.scss @@ -31,41 +31,86 @@ .accountCard { flex: 1; - min-width: 120px; + max-width: 140px; cursor: pointer; - border: 2px solid #f0f0f0; - border-radius: 8px; + border: 2px solid #e8e8e8; + border-radius: 12px; transition: all 0.3s; position: relative; + background: #fff; - &:hover:not(.disabled) { + &:hover:not(.disabled):not(.selected) { border-color: #d9d9d9; - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); + transform: translateY(-2px); } &.selected { border-color: #1890ff; - box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2); + background: linear-gradient(135deg, #e6f7ff 0%, #f0f8ff 100%); + box-shadow: + 0 0 0 3px rgba(24, 144, 255, 0.15), + 0 4px 12px rgba(24, 144, 255, 0.2); } &.disabled { - opacity: 0.6; + opacity: 0.5; cursor: not-allowed; background-color: #fafafa; + border-color: #f0f0f0; } - :global(.ant-card-body) { - padding: 16px; - } + padding: 20px 16px; .accountInfo { text-align: center; + display: flex; + flex-direction: column; + align-items: center; + + .avatarWrapper { + position: relative; + margin-bottom: 12px; + + .accountAvatar { + border: 3px solid #e8e8e8; + transition: all 0.3s; + } + + .selectedIndicator { + position: absolute; + bottom: -2px; + right: -2px; + width: 24px; + height: 24px; + background: #1890ff; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + border: 3px solid #fff; + box-shadow: 0 2px 8px rgba(24, 144, 255, 0.4); + + .checkIcon { + color: #fff; + font-size: 14px; + font-weight: bold; + line-height: 1; + } + } + } + + .accountCard.selected .avatarWrapper .accountAvatar { + border-color: #1890ff; + box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2); + } .accountName { font-size: 14px; font-weight: 500; color: #262626; margin-bottom: 8px; + transition: color 0.3s; } .usageBadge { @@ -75,6 +120,7 @@ height: 20px; line-height: 18px; border-radius: 10px; + padding: 0 8px; } } @@ -84,6 +130,19 @@ margin-top: 4px; } } + + // 选中状态下的样式增强 + &.selected .accountInfo { + .accountName { + color: #1890ff; + font-weight: 600; + } + + .avatarWrapper .accountAvatar { + border-color: #1890ff; + box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2); + } + } } } diff --git a/Touchkebao/src/pages/pc/ckbox/powerCenter/content-management/components/MomentPublish.tsx b/Touchkebao/src/pages/pc/ckbox/powerCenter/content-management/components/MomentPublish.tsx index e8702e7e..39f95b0d 100644 --- a/Touchkebao/src/pages/pc/ckbox/powerCenter/content-management/components/MomentPublish.tsx +++ b/Touchkebao/src/pages/pc/ckbox/powerCenter/content-management/components/MomentPublish.tsx @@ -1,6 +1,7 @@ import React, { useState, useEffect, useCallback } from "react"; -import { Button, Input, Select, message, Card, Badge } from "antd"; -import { useCkChatStore } from "@/store/module/ckchat/ckchat"; +import { Button, Input, Select, message, Badge, Avatar } from "antd"; +import { useCustomerStore, updateCustomerList } from "@weChatStore/customer"; +import { getCustomerList } from "@apiModule/wechat"; import { addMoment } from "./api"; import styles from "./MomentPublish.module.scss"; import { KfUserListData } from "@/pages/pc/ckbox/data"; @@ -24,44 +25,60 @@ const MomentPublish: React.FC = ({ onPublishSuccess }) => { const [linkUrl, setLinkUrl] = useState(""); const [accounts, setAccounts] = useState([]); const [loading, setLoading] = useState(false); + const [customerListLoading, setCustomerListLoading] = + useState(false); // 从store获取客服列表 - const kfUserList = useCkChatStore(state => state.kfUserList); + const customerList = useCustomerStore(state => state.customerList); + + // 初始化获取客服列表 + useEffect(() => { + const fetchCustomerList = async () => { + setCustomerListLoading(true); + try { + const res = await getCustomerList(); + updateCustomerList(res); + } catch (error) { + console.error("获取客服列表失败:", error); + message.error("获取客服列表失败"); + } finally { + setCustomerListLoading(false); + } + }; + + // 如果客服列表为空,则获取 + if (customerList.length === 0) { + fetchCustomerList(); + } + }, []); // 获取账号使用情况 const fetchAccountUsage = useCallback(async () => { - if (kfUserList.length === 0) return; + if (customerList.length === 0) return; // 直接使用客服列表数据,不需要额外的API调用 - const accountData = kfUserList.map((kf, index) => ({ - ...kf, - name: kf.nickname || `客服${index + 1}`, - isSelected: selectedAccounts.includes(kf.id.toString()), - isDisabled: kf.momentsNum >= kf.momentsMax, + const accountData = customerList.map((customer, index) => ({ + ...customer, + name: customer.nickname || `客服${index + 1}`, + isSelected: selectedAccounts.includes(customer.id.toString()), + isDisabled: customer.momentsNum >= customer.momentsMax, })); setAccounts(accountData); - }, [kfUserList, selectedAccounts]); + }, [customerList, selectedAccounts]); - // 如果没有选中的账号且有可用账号,自动选择第一个可用账号 - useEffect(() => { - if (selectedAccounts.length === 0 && accounts.length > 0) { - const firstAvailable = accounts.find(acc => !acc.isDisabled); - if (firstAvailable) { - setSelectedAccounts([firstAvailable.id.toString()]); - } - } - }, [accounts, selectedAccounts.length]); + // 移除自动选择逻辑,允许用户手动选择或取消选择 // 当客服列表变化时,重新获取使用情况 useEffect(() => { fetchAccountUsage(); - }, [kfUserList, selectedAccounts, fetchAccountUsage]); + }, [customerList, selectedAccounts, fetchAccountUsage]); const handleAccountSelect = (accountId: string) => { const account = accounts.find(acc => acc.id.toString() === accountId); if (!account || account.isDisabled) return; + // 允许取消选择:如果已选中则取消,未选中则选中 setSelectedAccounts(prev => prev.includes(accountId) ? prev.filter(id => id !== accountId) @@ -146,8 +163,13 @@ const MomentPublish: React.FC = ({ onPublishSuccess }) => { setLinkImage(""); setLinkUrl(""); setTimingTime(""); - // 重新获取账号使用情况 - await fetchAccountUsage(); + // 重新获取客服列表以更新使用情况 + try { + const res = await getCustomerList(); + updateCustomerList(res); + } catch (error) { + console.error("刷新客服列表失败:", error); + } // 触发父组件的刷新回调 onPublishSuccess?.(); } catch (error) { @@ -167,7 +189,7 @@ const MomentPublish: React.FC = ({ onPublishSuccess }) => {

选择发布账号

{accounts.map(account => ( - = ({ onPublishSuccess }) => { onClick={() => handleAccountSelect(account.id.toString())} >
+
+ + {!account.avatar && account.name?.charAt(0)} + + {selectedAccounts.includes(account.id.toString()) && ( +
+ +
+ )} +
{account.name}
= ({ onPublishSuccess }) => {
今日已达上限
)}
-
+
))} diff --git a/Touchkebao/vite.config.mts b/Touchkebao/vite.config.mts index 1431a796..9dfeebc9 100644 --- a/Touchkebao/vite.config.mts +++ b/Touchkebao/vite.config.mts @@ -15,7 +15,7 @@ export default defineConfig({ }, server: { open: true, - port: 3000, + port: 8888, host: "0.0.0.0", }, build: {