diff --git a/.env.local b/.env.local index ba999c8..7b2e052 100644 --- a/.env.local +++ b/.env.local @@ -4,8 +4,8 @@ NODE_ENV=development VITE_DEV=true # 请求路径 -VITE_BASE_URL='http://192.168.1.174:48080' -# VITE_BASE_URL='http://47.79.98.113:48080' +# VITE_BASE_URL='http://192.168.1.174:48080' +VITE_BASE_URL='http://47.79.98.113:48080' # 文件上传类型:server - 后端上传, client - 前端直连上传,仅支持 S3 服务 VITE_UPLOAD_TYPE=server diff --git a/package-lock.json b/package-lock.json index be62481..fffcd07 100644 --- a/package-lock.json +++ b/package-lock.json @@ -59,6 +59,7 @@ "vue-i18n": "9.10.2", "vue-router": "4.4.5", "vue-types": "^5.1.1", + "vue3-clipboard": "^1.0.0", "vue3-signature": "^0.2.4", "vuedraggable": "^4.1.0", "web-storage-cache": "^1.1.1", @@ -8055,6 +8056,16 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, + "node_modules/clipboard": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.11.tgz", + "integrity": "sha512-C+0bbOqkezLIsmWSvlsXS0Q0bmkugu7jcfMIACB+RDEntIzQIkdr148we28AfSloQLRdZlYL/QYyrq05j/3Faw==", + "dependencies": { + "good-listener": "^1.2.2", + "select": "^1.1.2", + "tiny-emitter": "^2.0.0" + } + }, "node_modules/cliui": { "version": "8.0.1", "resolved": "https://registry.npmmirror.com/cliui/-/cliui-8.0.1.tgz", @@ -9112,6 +9123,11 @@ "node": ">=0.4.0" } }, + "node_modules/delegate": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz", + "integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==" + }, "node_modules/destr": { "version": "2.0.5", "resolved": "https://registry.npmmirror.com/destr/-/destr-2.0.5.tgz", @@ -11065,6 +11081,14 @@ "dev": true, "license": "MIT" }, + "node_modules/good-listener": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz", + "integrity": "sha512-goW1b+d9q/HIwbVYZzZ6SsTr4IgE+WA44A0GmPIQstuOrgsFcT7VEJ48nmr9GaRtNu0XTKacFLGnBPAM6Afouw==", + "dependencies": { + "delegate": "^3.1.2" + } + }, "node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmmirror.com/gopd/-/gopd-1.2.0.tgz", @@ -14856,6 +14880,11 @@ "dev": true, "license": "MIT" }, + "node_modules/select": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz", + "integrity": "sha512-OwpTSOfy6xSs1+pwcNrv0RBMOzI39Lp3qQKUTPVVPRjCdNa5JH/oPRiqsesIskK8TVgmRiHwO4KXlV2Li9dANA==" + }, "node_modules/semver": { "version": "7.7.2", "resolved": "https://registry.npmmirror.com/semver/-/semver-7.7.2.tgz", @@ -15873,6 +15902,11 @@ "dev": true, "license": "MIT" }, + "node_modules/tiny-emitter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", + "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==" + }, "node_modules/tiny-svg": { "version": "3.1.3", "resolved": "https://registry.npmmirror.com/tiny-svg/-/tiny-svg-3.1.3.tgz", @@ -17080,6 +17114,17 @@ "integrity": "sha512-L2RPSAwUFbgZH20etwrXyVyCBu9OxRSi8T/38QsvnkJyvq2LufW2lDCOzm7t/U9C1mkhJGWYfCuFBCmIuNivrg==", "license": "MIT" }, + "node_modules/vue3-clipboard": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/vue3-clipboard/-/vue3-clipboard-1.0.0.tgz", + "integrity": "sha512-GUqKh1oO79xDpq0z+cCv/NDVTpcJGNDzeNgT3PmTdTp/WJh3gcTrDqIYKycKhzMFOtIFJ7hO/+usgyWtT+fNhA==", + "dependencies": { + "clipboard": "^2.0.6" + }, + "peerDependencies": { + "vue": "^3.0.0" + } + }, "node_modules/vue3-signature": { "version": "0.2.4", "resolved": "https://registry.npmmirror.com/vue3-signature/-/vue3-signature-0.2.4.tgz", diff --git a/package.json b/package.json index 420d8d4..c1b4a90 100644 --- a/package.json +++ b/package.json @@ -75,6 +75,7 @@ "vue-i18n": "9.10.2", "vue-router": "4.4.5", "vue-types": "^5.1.1", + "vue3-clipboard": "^1.0.0", "vue3-signature": "^0.2.4", "vuedraggable": "^4.1.0", "web-storage-cache": "^1.1.1", diff --git a/src/api/server/bigbrother/index.ts b/src/api/server/bigbrother/index.ts new file mode 100644 index 0000000..e81a659 --- /dev/null +++ b/src/api/server/bigbrother/index.ts @@ -0,0 +1,57 @@ +import request from '@/config/axios' + +// 大哥数据 VO +export interface BigBrotherVO { + id: number // 主键id + displayId: string // 大哥的display_id + userIdStr: string // 大哥的用户id + nickname: string // 大哥的用户昵称 + level: number // 大哥的等级 + hostcoins: number // 大哥打赏的金币 + followerCount: number // 大哥的粉丝数 + followingCount: number // 大哥的关注数 + region: string // 大哥所在的地区 + historicHighCoins: number // 大哥打赏的历史最高金币 + totalGiftCoins: number // 大哥历史打赏金币总和 + hostDisplayId: string // 大哥所在的直播间的主播display_id + ownerId: string // 该数据所属的账号id +} + +// 大哥数据 API +export const BigBrotherApi = { + // 查询大哥数据分页 + getBigBrotherPage: async (params: any) => { + return await request.get({ url: `/server/big-brother/page`, params }) + }, + + // 查询大哥数据详情 + getBigBrother: async (id: number) => { + return await request.get({ url: `/server/big-brother/get?id=` + id }) + }, + + // 新增大哥数据 + createBigBrother: async (data: BigBrotherVO) => { + return await request.post({ url: `/server/big-brother/create`, data }) + }, + + // 修改大哥数据 + updateBigBrother: async (data: BigBrotherVO) => { + return await request.put({ url: `/server/big-brother/update`, data }) + }, + + + // 分配大哥 + Allocation: async (data: BigBrotherVO[]) => { + return await request.post({ url: `/server/employee-big-brother/allocation`, data }) + }, + + // 删除大哥数据 + deleteBigBrother: async (id: number) => { + return await request.delete({ url: `/server/big-brother/delete?id=` + id }) + }, + + // 导出大哥数据 Excel + exportBigBrother: async (params) => { + return await request.download({ url: `/server/big-brother/export-excel`, params }) + } +} \ No newline at end of file diff --git a/src/api/server/employeebigbrother/index.ts b/src/api/server/employeebigbrother/index.ts new file mode 100644 index 0000000..dd15afb --- /dev/null +++ b/src/api/server/employeebigbrother/index.ts @@ -0,0 +1,60 @@ +import request from '@/config/axios' + +// 大哥数据员工业务 VO +export interface EmployeeBigBrotherVO { + id: number // 主键id + displayId: string // 大哥的display_id + userIdStr: string // 大哥的用户id + nickname: string // 大哥的用户昵称 + level: number // 大哥的等级 + hostcoins: number // 大哥打赏的金币 + followerCount: number // 大哥的粉丝数 + followingCount: number // 大哥的关注数 + region: string // 大哥所在的地区 + historicHighCoins: number // 大哥打赏的历史最高金币 + totalGiftCoins: number // 大哥历史打赏金币总和 + hostDisplayId: string // 大哥所在的直播间的主播display_id + userId: string // 该数据所属的账号id + operationStatus: number // 是否洽谈 +} + +// 大哥数据员工业务 API +export const EmployeeBigBrotherApi = { + // 查询大哥数据员工业务分页 + getMeangeEmployeeBigBrotherPage: async (params: any) => { + return await request.get({ url: `/server/employee-big-brother/page`, params }) + }, + // 查询管理大哥数据员工业务分页 + getEmployeeBigBrotherPage: async (params: any) => { + return await request.get({ url: `/server/employee-big-brother/self_page`, params }) + }, + + // 批量修改大哥数据 + batchUpdateBigBrother: async (data: EmployeeBigBrotherVO[]) => { + return await request.put({ url: `/server/employee-big-brother/batch_update`, data }) + }, + // 查询大哥数据员工业务详情 + getEmployeeBigBrother: async (id: number) => { + return await request.get({ url: `/server/employee-big-brother/get?id=` + id }) + }, + + // 新增大哥数据员工业务 + createEmployeeBigBrother: async (data: EmployeeBigBrotherVO) => { + return await request.post({ url: `/server/employee-big-brother/create`, data }) + }, + + // 修改大哥数据员工业务 + updateEmployeeBigBrother: async (data: EmployeeBigBrotherVO) => { + return await request.put({ url: `/server/employee-big-brother/update`, data }) + }, + + // 删除大哥数据员工业务 + deleteEmployeeBigBrother: async (id: number) => { + return await request.delete({ url: `/server/employee-big-brother/delete?id=` + id }) + }, + + // 导出大哥数据员工业务 Excel + exportEmployeeBigBrother: async (params) => { + return await request.download({ url: `/server/employee-big-brother/export-excel`, params }) + } +} \ No newline at end of file diff --git a/src/api/server/employeehosts/index.ts b/src/api/server/employeehosts/index.ts index ec6fc0c..f8f2b4e 100644 --- a/src/api/server/employeehosts/index.ts +++ b/src/api/server/employeehosts/index.ts @@ -32,6 +32,7 @@ export const EmployeeHostsApi = { getEmployeeHostsPage: async (params: any) => { return await request.get({ url: `/server/employee-hosts/self_page`, params }) }, + // 查询管理员工分配主播分页 getMeangeEmployeeHostsPage: async (params: any) => { return await request.get({ url: `server/employee-hosts/page`, params }) }, @@ -46,7 +47,7 @@ export const EmployeeHostsApi = { }, // 修改员工分配主播 - updateEmployeeHosts: async (data: EmployeeHostsVO) => { + updateEmployeeHosts: async (data) => { return await request.put({ url: `/server/employee-hosts/update`, data }) }, // 批量修改员工分配主播 diff --git a/src/utils/dict.ts b/src/utils/dict.ts index 60688c2..b4e30d0 100644 --- a/src/utils/dict.ts +++ b/src/utils/dict.ts @@ -250,5 +250,7 @@ export enum DICT_TYPE { INT_TRUE_FLASE = 'int_true_false',// 桥梁类型HOST_LEVEL HOST_LEVEL = 'host_level', // 桥梁类型country_group COUNTRY_GROUP = 'country_group', // 桥梁类型 - OPERATION_STATE = 'operational_state' // 桥梁类型operational_state + OPERATION_STATE = 'operational_state', // 桥梁类型operational_state + BIGBIOTHER_NEGOTIATION = 'bigBiother_negotiation' // 是否洽谈 + } diff --git a/src/views/server/bigbrother/BigBrotherForm.vue b/src/views/server/bigbrother/BigBrotherForm.vue new file mode 100644 index 0000000..93f796b --- /dev/null +++ b/src/views/server/bigbrother/BigBrotherForm.vue @@ -0,0 +1,147 @@ + + \ No newline at end of file diff --git a/src/views/server/bigbrother/index.vue b/src/views/server/bigbrother/index.vue new file mode 100644 index 0000000..502c418 --- /dev/null +++ b/src/views/server/bigbrother/index.vue @@ -0,0 +1,339 @@ + + + \ No newline at end of file diff --git a/src/views/server/employeebigbrother/EmployeeBigBrotherForm.vue b/src/views/server/employeebigbrother/EmployeeBigBrotherForm.vue new file mode 100644 index 0000000..d7b542d --- /dev/null +++ b/src/views/server/employeebigbrother/EmployeeBigBrotherForm.vue @@ -0,0 +1,154 @@ + + \ No newline at end of file diff --git a/src/views/server/employeebigbrother/index.vue b/src/views/server/employeebigbrother/index.vue new file mode 100644 index 0000000..1d1ab4a --- /dev/null +++ b/src/views/server/employeebigbrother/index.vue @@ -0,0 +1,317 @@ + + + \ No newline at end of file diff --git a/src/views/server/employeehosts/index.vue b/src/views/server/employeehosts/index.vue index 337e2e7..e972132 100644 --- a/src/views/server/employeehosts/index.vue +++ b/src/views/server/employeehosts/index.vue @@ -105,7 +105,7 @@ - @@ -318,35 +318,35 @@ const handleExport = async () => { exportLoading.value = false } } -/** 查询员工 */ -const getAllocationList = async () => { - loading.value = true - allocationUserList.value = [] - try { - const data = await getAllocation(wsCache.get('user').user.deptId) - console.log('data', data) - data.forEach((item) => { - if (wsCache.get('user').user.id == item.id) { +// /** 查询员工 */ +// const getAllocationList = async () => { +// loading.value = true +// allocationUserList.value = [] +// try { +// const data = await getAllocation(wsCache.get('user').user.deptId) +// console.log('data', data) +// data.forEach((item) => { +// if (wsCache.get('user').user.id == item.id) { - } else { - allocationUserList.value.push({ - label: item.nickname, - value: item.id - }) - } +// } else { +// allocationUserList.value.push({ +// label: item.nickname, +// value: item.id +// }) +// } - }) - console.log(allocationUserList.value) - } finally { - loading.value = false - } -} +// }) +// console.log(allocationUserList.value) +// } finally { +// loading.value = false +// } +// } function openHtml(item, id) { let data = item data.operationStatus = 1 - EmployeeHostsApi.updateEmployeeHosts(data).then(res => { + EmployeeHostsApi.updateEmployeeHosts({ id: data.id, operationStatus: 1 }).then(res => { getList() }) window.open(`https://www.tiktok.com/@${id}`) @@ -376,25 +376,51 @@ const handleSelectionChange = (val) => { } function exportAi() { - if (selectHostList.value.length != 0) { - const data = [] - selectHostList.value.forEach((item) => { - data.push(item.hostsId) - }) - navigator.clipboard.writeText(data.join('\n')) - .then(() => { - ElMessage.success('复制成功' + selectHostList.value.length + '条数据') - }) - .catch(err => { - ElMessage.error('复制失败') - - }) - } else { + if (selectHostList.value.length === 0) { ElMessage.error('请选择主播') + return } + const data = selectHostList.value.map(item => item.hostsId).join('\n') + + const copyToClipboard = async (text) => { + // 优先使用 Clipboard API + if (navigator.clipboard && window.isSecureContext) { + try { + await navigator.clipboard.writeText(text) + ElMessage.success('✅ 复制成功 ' + selectHostList.value.length + ' 条数据') + } catch (err) { + ElMessage.error('❌ 复制失败') + console.error(err) + } + } else { + // fallback 兼容方案 + const textarea = document.createElement('textarea') + textarea.value = text + textarea.style.position = 'fixed' // 避免跳动 + textarea.style.opacity = '0' + document.body.appendChild(textarea) + textarea.select() + try { + const result = document.execCommand('copy') + if (result) { + ElMessage.success('✅(兼容模式)复制成功 ' + selectHostList.value.length + ' 条数据') + } else { + ElMessage.error('❌(兼容模式)复制失败') + } + } catch (err) { + ElMessage.error('❌(兼容模式)复制异常') + console.error(err) + } finally { + document.body.removeChild(textarea) + } + } + } + + copyToClipboard(data) } + function AllocationFun() { console.log(allocationUser.value) console.log(selectHostList.value) @@ -404,7 +430,7 @@ const isMobile = ref(window.innerWidth <= 768) onMounted(() => { getList() - getAllocationList() + // getAllocationList() //实时监听实际还是电脑 window.addEventListener('resize', () => { if ((window.innerWidth <= 768) != isMobile.value) { diff --git a/src/views/server/manageemployeebigbrother/EmployeeBigBrotherForm.vue b/src/views/server/manageemployeebigbrother/EmployeeBigBrotherForm.vue new file mode 100644 index 0000000..2632e90 --- /dev/null +++ b/src/views/server/manageemployeebigbrother/EmployeeBigBrotherForm.vue @@ -0,0 +1,148 @@ + + \ No newline at end of file diff --git a/src/views/server/manageemployeebigbrother/index.vue b/src/views/server/manageemployeebigbrother/index.vue new file mode 100644 index 0000000..ad4b19c --- /dev/null +++ b/src/views/server/manageemployeebigbrother/index.vue @@ -0,0 +1,361 @@ + + + \ No newline at end of file diff --git a/src/views/server/manageemployeehosts/index.vue b/src/views/server/manageemployeehosts/index.vue index f6627df..2484262 100644 --- a/src/views/server/manageemployeehosts/index.vue +++ b/src/views/server/manageemployeehosts/index.vue @@ -104,7 +104,7 @@ - @@ -133,7 +133,7 @@ {{ $t('employee.updateTime') }}:{{ formatTimestamp(item.updateTime) }}
{{ $t('employee.edit') - }} + }}
@@ -361,7 +361,7 @@ const getAllocationList = async () => { function openHtml(item, id) { let data = item data.operationStatus = 1 - EmployeeHostsApi.updateEmployeeHosts(data).then(res => { + EmployeeHostsApi.updateEmployeeHosts({ id: data.id, operationStatus: 1 }).then(res => { getList() }) window.open(`https://www.tiktok.com/@${id}`) @@ -422,6 +422,8 @@ function AllocationFun() { EmployeeHostsApi.updateBatchEmployeeHosts(data).then(res => { console.log(res) + handleQuery() + message.success('分配成功') }) dialogAllocation.value = false diff --git a/src/views/server/newhosts/index.vue b/src/views/server/newhosts/index.vue index acf84ba..83836e7 100644 --- a/src/views/server/newhosts/index.vue +++ b/src/views/server/newhosts/index.vue @@ -143,8 +143,7 @@ - +