任务管理
This commit is contained in:
24
src/api/all/assignment-management.ts
Normal file
24
src/api/all/assignment-management.ts
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import Http from '@/api';
|
||||||
|
|
||||||
|
// 任务管理-分页
|
||||||
|
export const getTaskSchedules = (params = {}) => {
|
||||||
|
return Http.get('/v1/media-accounts/task-schedules', params);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 任务管理-删除
|
||||||
|
export const delTaskSchedules = (id: string) => {
|
||||||
|
console.log('id', id);
|
||||||
|
return Http.delete(`/v1/task-schedules/${id}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 任务管理-修改
|
||||||
|
export const editTaskSchedules = (id: string, params = {}) => {
|
||||||
|
console.log('id', id);
|
||||||
|
return Http.put(`/v1/task-schedules/${id}`,params);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 任务管理-详情
|
||||||
|
export const getTaskSchedulesDetail = (id: string) => {
|
||||||
|
console.log('id', id);
|
||||||
|
return Http.get(`/v1/task-schedules/${id}`);
|
||||||
|
};
|
||||||
@ -14,7 +14,10 @@
|
|||||||
@change="handleChange"
|
@change="handleChange"
|
||||||
>
|
>
|
||||||
<a-option v-for="(item, index) in options" :key="index" :value="item.id" :label="item.name">
|
<a-option v-for="(item, index) in options" :key="index" :value="item.id" :label="item.name">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<img v-if="item.icon" :src="item.icon" class="w-16px h-16px mr-8px rounded-4px" />
|
||||||
{{ item.name }}
|
{{ item.name }}
|
||||||
|
</div>
|
||||||
</a-option>
|
</a-option>
|
||||||
</a-select>
|
</a-select>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -101,10 +101,11 @@ export const MENU_LIST = <Record<string, typeMenuItem[]>>{
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'ModTaskManage',
|
key: 'assignmentManagement',
|
||||||
label: '任务管理',
|
label: '任务管理',
|
||||||
icon: ['svg-taskManage', 'svg-taskManage-active'],
|
icon: ['svg-taskManage', 'svg-taskManage-active'],
|
||||||
routeName: 'TaskManagement',
|
routeName: 'AssignmentManagement',
|
||||||
|
activeMatch: ['AssignmentManagement'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
[GROUP_WRITER_NAME]: [
|
[GROUP_WRITER_NAME]: [
|
||||||
@ -151,9 +152,7 @@ export const MENU_LIST = <Record<string, typeMenuItem[]>>{
|
|||||||
label: '个人信息',
|
label: '个人信息',
|
||||||
routeName: 'ManagementPerson',
|
routeName: 'ManagementPerson',
|
||||||
requireLogin: true,
|
requireLogin: true,
|
||||||
activeMatch: [
|
activeMatch: ['ManagementPerson'],
|
||||||
'ManagementPerson',
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'ModManagementEnterprise',
|
key: 'ModManagementEnterprise',
|
||||||
@ -172,6 +171,6 @@ export const MENU_LIST = <Record<string, typeMenuItem[]>>{
|
|||||||
activeMatch: ['ManagementAccount'],
|
activeMatch: ['ManagementAccount'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
};
|
};
|
||||||
|
|||||||
@ -73,6 +73,20 @@ const COMPONENTS: AppRouteRecordRaw[] = [
|
|||||||
},
|
},
|
||||||
component: () => import('@/views/property-marketing/media-account/account-dashboard/index.vue'),
|
component: () => import('@/views/property-marketing/media-account/account-dashboard/index.vue'),
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
path: 'management-detail/:id',
|
||||||
|
name: 'managementDetail',
|
||||||
|
meta: {
|
||||||
|
locale: '任务详情',
|
||||||
|
requiresAuth: true,
|
||||||
|
requireLogin: true,
|
||||||
|
roles: ['*'],
|
||||||
|
hideInMenu: true,
|
||||||
|
activeMenu: 'MediaAccountAccountDashboard',
|
||||||
|
},
|
||||||
|
component: () => import('@/views/property-marketing/assignment-management/managementDetail.vue'),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: 'detail/:id',
|
path: 'detail/:id',
|
||||||
name: 'MediaAccountAccountDetails',
|
name: 'MediaAccountAccountDetails',
|
||||||
@ -159,6 +173,88 @@ const COMPONENTS: AppRouteRecordRaw[] = [
|
|||||||
// },
|
// },
|
||||||
// ],
|
// ],
|
||||||
// },
|
// },
|
||||||
|
{
|
||||||
|
path: '/assignmentManagement',
|
||||||
|
name: 'AssignmentManagement',
|
||||||
|
meta: {
|
||||||
|
locale: '任务管理',
|
||||||
|
requiresAuth: true,
|
||||||
|
requireLogin: true,
|
||||||
|
roles: ['*'],
|
||||||
|
},
|
||||||
|
component: () => import('@/views/property-marketing/assignment-management/index.vue'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/put-account',
|
||||||
|
name: 'PutAccount',
|
||||||
|
redirect: 'put-account/accountManagement',
|
||||||
|
meta: {
|
||||||
|
locale: '投放资源中心',
|
||||||
|
icon: IconPutAccount,
|
||||||
|
requiresAuth: true,
|
||||||
|
requireLogin: true,
|
||||||
|
roles: ['*'],
|
||||||
|
id: MENU_GROUP_IDS.PROPERTY_ID,
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: 'manage',
|
||||||
|
name: 'PutAccountAccountManagement',
|
||||||
|
meta: {
|
||||||
|
locale: '账户管理',
|
||||||
|
requiresAuth: true,
|
||||||
|
requireLogin: true,
|
||||||
|
roles: ['*'],
|
||||||
|
},
|
||||||
|
component: () => import('@/views/property-marketing/put-account/account-manage/index.vue'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'data',
|
||||||
|
name: 'PutAccountAccountData',
|
||||||
|
meta: {
|
||||||
|
locale: '账户数据',
|
||||||
|
requiresAuth: true,
|
||||||
|
requireLogin: true,
|
||||||
|
roles: ['*'],
|
||||||
|
},
|
||||||
|
component: () => import('@/views/property-marketing/put-account/account-data/index.vue'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'account-dashboard',
|
||||||
|
name: 'PutAccountAccountDashboard',
|
||||||
|
meta: {
|
||||||
|
locale: '投放表现分析',
|
||||||
|
requiresAuth: true,
|
||||||
|
requireLogin: true,
|
||||||
|
roles: ['*'],
|
||||||
|
},
|
||||||
|
component: () => import('@/views/property-marketing/put-account/account-dashboard/index.vue'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'investmentGuidelines',
|
||||||
|
name: 'PutAccountInvestmentGuidelines',
|
||||||
|
meta: {
|
||||||
|
locale: '投放指南',
|
||||||
|
requiresAuth: true,
|
||||||
|
requireLogin: true,
|
||||||
|
roles: ['*'],
|
||||||
|
},
|
||||||
|
component: () => import('@/views/property-marketing/put-account/investment-guidelines/index.vue'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'detail/:id',
|
||||||
|
name: 'guideDetail',
|
||||||
|
meta: {
|
||||||
|
locale: '投放指南详情',
|
||||||
|
requiresAuth: true,
|
||||||
|
hideInMenu: true,
|
||||||
|
roles: ['*'],
|
||||||
|
activeMenu: 'PutAccountInvestmentGuidelines',
|
||||||
|
},
|
||||||
|
component: () => import('@/views/property-marketing/put-account/investment-guidelines/detail.vue'),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
// {
|
// {
|
||||||
// path: '/intelligent-solution',
|
// path: '/intelligent-solution',
|
||||||
// name: 'IntelligentSolution',
|
// name: 'IntelligentSolution',
|
||||||
|
|||||||
@ -114,3 +114,129 @@
|
|||||||
// ],
|
// ],
|
||||||
// },
|
// },
|
||||||
// ];
|
// ];
|
||||||
|
import { MENU_GROUP_IDS } from '@/router/constants';
|
||||||
|
export const MENU_LIST = [
|
||||||
|
{
|
||||||
|
id: MENU_GROUP_IDS.WORK_BENCH_ID,
|
||||||
|
name: '工作台',
|
||||||
|
routeName: 'Home',
|
||||||
|
includeRouteNames: ['Home'],
|
||||||
|
requiresAuth: false,
|
||||||
|
permissionKey: '', // 权限key,如果为空,则表示该菜单不需要权限,与后端约定
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: MENU_GROUP_IDS.MANAGEMENT_ID,
|
||||||
|
name: '任务管理',
|
||||||
|
routeName: 'assignmentManagement',
|
||||||
|
includeRouteNames: ['assignmentManagement'],
|
||||||
|
requiresAuth: false,
|
||||||
|
permissionKey: '', // 权限key,如果为空,则表示该菜单不需要权限,与后端约定
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: MENU_GROUP_IDS.DATA_ENGINE_ID,
|
||||||
|
name: '全域数据分析',
|
||||||
|
permissionKey: 'data_analysis',
|
||||||
|
requiresAuth: true,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
name: '行业热门话题洞察',
|
||||||
|
routeName: 'DataEngineHotTranslation',
|
||||||
|
includeRouteNames: ['DataEngineHotTranslation'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '行业词云',
|
||||||
|
routeName: 'DataEngineHotCloud',
|
||||||
|
includeRouteNames: ['DataEngineHotCloud'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '行业关键词动向',
|
||||||
|
routeName: 'DataEngineKeyWord',
|
||||||
|
includeRouteNames: ['DataEngineKeyWord'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '用户痛点观察',
|
||||||
|
routeName: 'DataEngineUserPainPoints',
|
||||||
|
includeRouteNames: ['DataEngineUserPainPoints'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '重点品牌动向',
|
||||||
|
routeName: 'DataEngineKeyBrandMovement',
|
||||||
|
includeRouteNames: ['DataEngineKeyBrandMovement'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '用户画像',
|
||||||
|
routeName: 'DataEngineUserPersona',
|
||||||
|
includeRouteNames: ['DataEngineUserPersona'],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: MENU_GROUP_IDS.CREATIVE_GENERATION_WORKSHOP_ID,
|
||||||
|
name: '创意生成工坊',
|
||||||
|
permissionKey: '',
|
||||||
|
requiresAuth: true,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
name: '内容稿件',
|
||||||
|
routeName: 'ManuscriptList',
|
||||||
|
includeRouteNames: [
|
||||||
|
'ManuscriptList',
|
||||||
|
'ManuscriptUpload',
|
||||||
|
'ManuscriptEdit',
|
||||||
|
'ManuscriptDetail',
|
||||||
|
'ManuscriptCheckList',
|
||||||
|
'ManuscriptCheckListDetail',
|
||||||
|
'ManuscriptCheck',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: MENU_GROUP_IDS.PROPERTY_ID,
|
||||||
|
name: '营销资产中台',
|
||||||
|
permissionKey: 'marketing_asset',
|
||||||
|
requiresAuth: true,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
name: '品牌资产管理',
|
||||||
|
routeName: 'RepositoryBrandMaterials',
|
||||||
|
includeRouteNames: ['RepositoryBrandMaterials'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '账号资源中心',
|
||||||
|
routeName: 'MediaAccountAccountManagement',
|
||||||
|
includeRouteNames: [
|
||||||
|
'MediaAccountAccountManagement',
|
||||||
|
'MediaAccountAccountDashboard',
|
||||||
|
'MediaAccountAccountDetails',
|
||||||
|
'assignmentManagement',
|
||||||
|
'managementDetail',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '投放资源中心',
|
||||||
|
routeName: 'PutAccountAccountManagement',
|
||||||
|
includeRouteNames: [
|
||||||
|
'PutAccountAccountManagement',
|
||||||
|
'PutAccountAccountData',
|
||||||
|
'PutAccountAccountDashboard',
|
||||||
|
'PutAccountInvestmentGuidelines',
|
||||||
|
'guideDetail',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// name: '智能方案管理',
|
||||||
|
// routeName: 'IntelligentSolutionBusinessAnalysisReport',
|
||||||
|
// includeRouteNames: [
|
||||||
|
// 'IntelligentSolutionBusinessAnalysisReport',
|
||||||
|
// 'IntelligentSolutionCompetitiveProductAnalysisReport',
|
||||||
|
// ],
|
||||||
|
// },
|
||||||
|
{
|
||||||
|
name: '项目管理',
|
||||||
|
routeName: 'ProjectList',
|
||||||
|
includeRouteNames: ['ProjectList'],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|||||||
382
src/utils/DateUtils.ts
Normal file
382
src/utils/DateUtils.ts
Normal file
@ -0,0 +1,382 @@
|
|||||||
|
/**
|
||||||
|
* 日期工具类
|
||||||
|
* 提供月维度和周维度的开始结束日期获取功能
|
||||||
|
* 周以星期日开始,星期六结束
|
||||||
|
* 只返回日期部分,不包含时间
|
||||||
|
*/
|
||||||
|
class DateUtils {
|
||||||
|
/**
|
||||||
|
* 获取当前时间的月开始日期和结束日期
|
||||||
|
* @returns 包含开始和结束日期的对象
|
||||||
|
*/
|
||||||
|
static getMonthRange(): {
|
||||||
|
start: Date;
|
||||||
|
end: Date;
|
||||||
|
startFormatted: string;
|
||||||
|
endFormatted: string;
|
||||||
|
} {
|
||||||
|
const now = new Date();
|
||||||
|
|
||||||
|
// 月开始日期(当月第一天)
|
||||||
|
const start = new Date(now.getFullYear(), now.getMonth(), 1);
|
||||||
|
start.setHours(0, 0, 0, 0);
|
||||||
|
|
||||||
|
// 月结束日期(当月最后一天)
|
||||||
|
const end = new Date(now.getFullYear(), now.getMonth() + 1, 0);
|
||||||
|
end.setHours(0, 0, 0, 0);
|
||||||
|
|
||||||
|
return {
|
||||||
|
start,
|
||||||
|
end,
|
||||||
|
startFormatted: this.formatDate(start),
|
||||||
|
endFormatted: this.formatDate(end),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static MonthStrToDate(dateStr: string): Date {
|
||||||
|
const year = parseInt(dateStr.split('年')[0]);
|
||||||
|
const month = parseInt(dateStr.split('年')[1].split('月')[0]) - 1; // 月份从0开始
|
||||||
|
|
||||||
|
const date = new Date(year, month, 1);
|
||||||
|
return date;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指定年份和月的范围
|
||||||
|
* @param year 年份
|
||||||
|
* @param month 月份(1-12)
|
||||||
|
*/
|
||||||
|
static getMonthRangeByYearMonth(
|
||||||
|
year: number,
|
||||||
|
month: number,
|
||||||
|
): {
|
||||||
|
start: Date;
|
||||||
|
end: Date;
|
||||||
|
startFormatted: string;
|
||||||
|
endFormatted: string;
|
||||||
|
} {
|
||||||
|
// 月开始日期
|
||||||
|
const start = new Date(year, month - 1, 1);
|
||||||
|
start.setHours(0, 0, 0, 0);
|
||||||
|
|
||||||
|
// 月结束日期
|
||||||
|
const end = new Date(year, month, 0);
|
||||||
|
end.setHours(0, 0, 0, 0);
|
||||||
|
|
||||||
|
return {
|
||||||
|
start,
|
||||||
|
end,
|
||||||
|
startFormatted: this.formatDate(start),
|
||||||
|
endFormatted: this.formatDate(end),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前时间的周范围(以星期日开始)
|
||||||
|
* @returns 包含开始和结束日期的对象
|
||||||
|
*/
|
||||||
|
static getWeekRange(): {
|
||||||
|
start: Date;
|
||||||
|
end: Date;
|
||||||
|
startFormatted: string;
|
||||||
|
endFormatted: string;
|
||||||
|
} {
|
||||||
|
const today = new Date();
|
||||||
|
today.setHours(0, 0, 0, 0);
|
||||||
|
const dayOfWeek = today.getDay(); // 0是周日,1是周一,...,6是周六
|
||||||
|
|
||||||
|
// 周开始日期(周日)
|
||||||
|
const start = new Date(today);
|
||||||
|
start.setDate(today.getDate() - dayOfWeek);
|
||||||
|
start.setHours(0, 0, 0, 0);
|
||||||
|
|
||||||
|
// 周结束日期(周六)
|
||||||
|
const end = new Date(start);
|
||||||
|
end.setDate(start.getDate() + 6);
|
||||||
|
end.setHours(0, 0, 0, 0);
|
||||||
|
|
||||||
|
return {
|
||||||
|
start,
|
||||||
|
end,
|
||||||
|
startFormatted: this.formatDate(start),
|
||||||
|
endFormatted: this.formatDate(end),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指定日期的周范围
|
||||||
|
* @param date 指定日期
|
||||||
|
*/
|
||||||
|
static getWeekRangeByDate(date: Date): {
|
||||||
|
start: Date;
|
||||||
|
end: Date;
|
||||||
|
startFormatted: string;
|
||||||
|
endFormatted: string;
|
||||||
|
} {
|
||||||
|
const inputDate = new Date(date);
|
||||||
|
inputDate.setHours(0, 0, 0, 0);
|
||||||
|
const dayOfWeek = inputDate.getDay();
|
||||||
|
|
||||||
|
// 周开始日期(周日)
|
||||||
|
const start = new Date(inputDate);
|
||||||
|
start.setDate(inputDate.getDate() - dayOfWeek);
|
||||||
|
start.setHours(0, 0, 0, 0);
|
||||||
|
|
||||||
|
// 周结束日期(周六)
|
||||||
|
const end = new Date(start);
|
||||||
|
end.setDate(start.getDate() + 6);
|
||||||
|
end.setHours(0, 0, 0, 0);
|
||||||
|
|
||||||
|
return {
|
||||||
|
start,
|
||||||
|
end,
|
||||||
|
startFormatted: this.formatDate(start),
|
||||||
|
endFormatted: this.formatDate(end),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 格式化日期(只返回日期部分)
|
||||||
|
* @param date 日期对象
|
||||||
|
* @returns 格式化后的日期字符串 (YYYY-MM-DD)
|
||||||
|
*/
|
||||||
|
static formatDate(date: Date): string {
|
||||||
|
const year = date.getFullYear();
|
||||||
|
const month = (date.getMonth() + 1).toString().padStart(2, '0');
|
||||||
|
const day = date.getDate().toString().padStart(2, '0');
|
||||||
|
|
||||||
|
return `${year}-${month}-${day}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前日期信息
|
||||||
|
* @returns 包含各种格式的当前日期信息
|
||||||
|
*/
|
||||||
|
static getCurrentDateInfo() {
|
||||||
|
const now = new Date();
|
||||||
|
now.setHours(0, 0, 0, 0);
|
||||||
|
|
||||||
|
const monthRange = this.getMonthRange();
|
||||||
|
const weekRange = this.getWeekRange();
|
||||||
|
|
||||||
|
return {
|
||||||
|
current: {
|
||||||
|
date: now,
|
||||||
|
formatted: this.formatDate(now),
|
||||||
|
dayOfWeek: this.getChineseDayOfWeek(now),
|
||||||
|
},
|
||||||
|
month: {
|
||||||
|
start: monthRange.start,
|
||||||
|
end: monthRange.end,
|
||||||
|
startFormatted: monthRange.startFormatted,
|
||||||
|
endFormatted: monthRange.endFormatted,
|
||||||
|
totalDays: this.getDaysInMonth(now.getFullYear(), now.getMonth() + 1),
|
||||||
|
},
|
||||||
|
week: {
|
||||||
|
start: weekRange.start,
|
||||||
|
end: weekRange.end,
|
||||||
|
startFormatted: weekRange.startFormatted,
|
||||||
|
endFormatted: weekRange.endFormatted,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指定月份的天数
|
||||||
|
* @param year 年份
|
||||||
|
* @param month 月份(1-12)
|
||||||
|
* @returns 该月的天数
|
||||||
|
*/
|
||||||
|
static getDaysInMonth(year: number, month: number): number {
|
||||||
|
return new Date(year, month, 0).getDate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取中文星期几
|
||||||
|
* @param date 日期对象
|
||||||
|
* @returns 中文星期几
|
||||||
|
*/
|
||||||
|
static getChineseDayOfWeek(date: Date): string {
|
||||||
|
const days = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
|
||||||
|
return days[date.getDay()];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取中文月份名称
|
||||||
|
* @param month 月份(1-12)
|
||||||
|
* @returns 中文月份名称
|
||||||
|
*/
|
||||||
|
static getChineseMonthName(month: number): string {
|
||||||
|
const months = ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'];
|
||||||
|
return months[month - 1] || '';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否为同一天
|
||||||
|
* @param date1 日期1
|
||||||
|
* @param date2 日期2
|
||||||
|
* @returns 是否为同一天
|
||||||
|
*/
|
||||||
|
static isSameDay(date1: Date, date2: Date): boolean {
|
||||||
|
return this.formatDate(date1) === this.formatDate(date2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取日期差(天数)
|
||||||
|
* @param date1 日期1
|
||||||
|
* @param date2 日期2
|
||||||
|
* @returns 相差的天数
|
||||||
|
*/
|
||||||
|
static getDaysDifference(date1: Date, date2: Date): number {
|
||||||
|
const d1 = new Date(date1);
|
||||||
|
const d2 = new Date(date2);
|
||||||
|
d1.setHours(0, 0, 0, 0);
|
||||||
|
d2.setHours(0, 0, 0, 0);
|
||||||
|
|
||||||
|
const diffTime = Math.abs(d2.getTime() - d1.getTime());
|
||||||
|
return Math.ceil(diffTime / (1000 * 60 * 60 * 24));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 获取当前周的所有日期及星期几
|
||||||
|
* @param startDay 周起始日(0-6,0表示周日,默认1表示周一)
|
||||||
|
* @returns 当前周的日期数组
|
||||||
|
*/
|
||||||
|
static getWeekDaysByDate(targetDate: Date, startDay: number = 1) {
|
||||||
|
const weekdays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
|
||||||
|
const currentDay = targetDate.getDay();
|
||||||
|
const firstDayOffset = (currentDay - startDay + 7) % 7;
|
||||||
|
const firstDayOfWeek = new Date(targetDate);
|
||||||
|
firstDayOfWeek.setDate(targetDate.getDate() - firstDayOffset);
|
||||||
|
return Array.from({ length: 7 }).map((_, i) => {
|
||||||
|
const date = new Date(firstDayOfWeek);
|
||||||
|
date.setDate(firstDayOfWeek.getDate() + i);
|
||||||
|
return {
|
||||||
|
date,
|
||||||
|
day: date.getDate(),
|
||||||
|
weekday: weekdays[date.getDay()] + ' ' + date.getDate(),
|
||||||
|
month: date.getMonth() + 1, // 添加月份信息(1-12)
|
||||||
|
year: date.getFullYear(),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取某个月每一天的星期几
|
||||||
|
static getDaysAndWeekdays(year: number, month: number): Array<{ day: number; weekday: string }> {
|
||||||
|
const daysInMonth = new Date(year, month + 1, 0).getDate(); // 获取当月总天数
|
||||||
|
const weekdays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']; // 中文星期数组
|
||||||
|
const days: Array<{ day: number; weekday: string }> = []; // 结果数组
|
||||||
|
|
||||||
|
for (let day = 1; day <= daysInMonth; day++) {
|
||||||
|
const date = new Date(year, month, day);
|
||||||
|
const weekdayIndex = date.getDay(); // 获取星期几的索引(0-6)
|
||||||
|
days.push({
|
||||||
|
day,
|
||||||
|
weekday: weekdays[weekdayIndex] + ' ' + day,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return days;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 获取当前的年份
|
||||||
|
* @returns 当前年份
|
||||||
|
*/
|
||||||
|
static getCurrentYear(): number {
|
||||||
|
return new Date().getFullYear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前的月份
|
||||||
|
* @returns 当前月份 (1-12)
|
||||||
|
*/
|
||||||
|
static getCurrentMonth(): number {
|
||||||
|
return new Date().getMonth() + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前的年份和月份
|
||||||
|
* @returns 包含当前年份和月份的对象
|
||||||
|
*/
|
||||||
|
static getCurrentYearMonth(): { year: number; month: number } {
|
||||||
|
const now = new Date();
|
||||||
|
return {
|
||||||
|
year: now.getFullYear(),
|
||||||
|
month: now.getMonth() + 1,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取格式化的当前年月字符串
|
||||||
|
* @param separator 分隔符,默认为 '-'
|
||||||
|
* @returns 格式化的年月字符串 (YYYY-MM)
|
||||||
|
*/
|
||||||
|
static getFormattedYearMonth(separator: string = '-'): string {
|
||||||
|
const now = new Date();
|
||||||
|
const year = now.getFullYear();
|
||||||
|
const month = (now.getMonth() + 1).toString().padStart(2, '0');
|
||||||
|
return `${year}${separator}${month}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取中文格式的当前年月
|
||||||
|
* @returns 中文年月字符串 (YYYY年MM月)
|
||||||
|
*/
|
||||||
|
static getChineseYearMonth(): string {
|
||||||
|
const now = new Date();
|
||||||
|
const year = now.getFullYear();
|
||||||
|
const month = (now.getMonth() + 1).toString().padStart(2, '0');
|
||||||
|
return `${year}年${month}月`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前季度
|
||||||
|
* @returns 当前季度 (1-4)
|
||||||
|
*/
|
||||||
|
static getCurrentQuarter(): number {
|
||||||
|
const month = new Date().getMonth() + 1;
|
||||||
|
return Math.ceil(month / 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前季度的开始和结束月份
|
||||||
|
* @returns 包含季度开始和结束月份的对象
|
||||||
|
*/
|
||||||
|
static getCurrentQuarterRange(): { startMonth: number; endMonth: number } {
|
||||||
|
const quarter = this.getCurrentQuarter();
|
||||||
|
return {
|
||||||
|
startMonth: (quarter - 1) * 3 + 1,
|
||||||
|
endMonth: quarter * 3,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指定年份的所有月份信息
|
||||||
|
* @param year 年份
|
||||||
|
* @returns 包含所有月份信息的数组
|
||||||
|
*/
|
||||||
|
static getYearMonths(year: number): Array<{
|
||||||
|
month: number;
|
||||||
|
name: string;
|
||||||
|
days: number;
|
||||||
|
formatted: string;
|
||||||
|
}> {
|
||||||
|
return Array.from({ length: 12 }, (_, i) => {
|
||||||
|
const month = i + 1;
|
||||||
|
return {
|
||||||
|
month,
|
||||||
|
name: this.getChineseMonthName(month),
|
||||||
|
days: this.getDaysInMonth(year, month),
|
||||||
|
formatted: `${year}-${month.toString().padStart(2, '0')}`,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
static formatDateToWeekdayDay(date: Date): string {
|
||||||
|
const day = date.getDate();
|
||||||
|
const weekday = this.getChineseDayOfWeek(date).replace('星期', '周');
|
||||||
|
return `${weekday} ${day}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DateUtils;
|
||||||
@ -0,0 +1,105 @@
|
|||||||
|
<template>
|
||||||
|
<div class="flex flex-col items-start cell-detail">
|
||||||
|
<div class="flex items-center" @click="gotoDetail">
|
||||||
|
<img
|
||||||
|
:src="getPlatformIcon(record.platform)"
|
||||||
|
style="border-radius: 8px; width: 16px; height: 16px; margin-right: 8px; font-size: 14px"
|
||||||
|
/>
|
||||||
|
{{ record.name || '-' }}
|
||||||
|
</div>
|
||||||
|
<div class="size-12px color-#939499 mt-2px" @click="gotoDetail">
|
||||||
|
{{ timestampToTime1(task.execution_time) }}
|
||||||
|
</div>
|
||||||
|
<div class="size-14px color-#211F24 mt-12px color-#6D4CFE" @click="gotoDetail">{{ task.name || '未命名' }}</div>
|
||||||
|
<div class="flex items-center mt-12px">
|
||||||
|
<div class="custom-time-picker">
|
||||||
|
<a-time-picker
|
||||||
|
format="HH:mm"
|
||||||
|
size="small"
|
||||||
|
:visible="isPanelVisible"
|
||||||
|
@visible-change="handleVisibleChange"
|
||||||
|
@change="handleTimeChange"
|
||||||
|
placeholder="修改发布时间"
|
||||||
|
class="hide-input-container opt-btn mr-12px"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="opt-btn" @click.stop="handleDelete" style="margin-right: 0px">删除</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { defineProps, defineEmits } from 'vue';
|
||||||
|
import { ref, computed } from 'vue';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
task: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
record: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
getPlatformIcon: {
|
||||||
|
type: Function,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const isPanelVisible = ref(false);
|
||||||
|
const toggleTimePanel = () => {
|
||||||
|
isPanelVisible.value = !isPanelVisible.value;
|
||||||
|
};
|
||||||
|
const handleVisibleChange = (visible: boolean) => {
|
||||||
|
isPanelVisible.value = visible;
|
||||||
|
};
|
||||||
|
const handleTimeChange = (time: string) => {
|
||||||
|
if (time) {
|
||||||
|
emit('edit-time', props.task, timestampToTime1() + ' ' + time + ':00');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const timestampToTime1 = (): string => {
|
||||||
|
const timestamp = Date.now();
|
||||||
|
const date = new Date(timestamp);
|
||||||
|
|
||||||
|
const year = date.getFullYear();
|
||||||
|
const month = String(date.getMonth() + 1).padStart(2, '0'); // 补零
|
||||||
|
const day = String(date.getDate()).padStart(2, '0'); // 补零
|
||||||
|
|
||||||
|
return `${year}-${month}-${day}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
const emit = defineEmits(['edit-time', 'delete', 'gotoDetail']);
|
||||||
|
|
||||||
|
const handleDelete = () => {
|
||||||
|
emit('delete', props.task);
|
||||||
|
};
|
||||||
|
|
||||||
|
const gotoDetail = () => {
|
||||||
|
console.log('跳转详情');
|
||||||
|
emit('gotoDetail', props.task);
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.cell-detail {
|
||||||
|
background-color: #fff;
|
||||||
|
border: 1px solid #d9d9d9;
|
||||||
|
border-radius: 4px;
|
||||||
|
box-shadow: #00000010 0px 2px 8px;
|
||||||
|
padding: 8px 16px;
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.opt-btn {
|
||||||
|
font-size: 12px;
|
||||||
|
width: 138px;
|
||||||
|
height: 28px;
|
||||||
|
background-color: #f2f3f5;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 28px;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-right: 12px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
1031
src/views/property-marketing/assignment-management/index.vue
Normal file
1031
src/views/property-marketing/assignment-management/index.vue
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,101 @@
|
|||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="table-wrap bg-#fff rounded-8px px-24px py-24px flex flex-col justify-start items-center"
|
||||||
|
style="height: 90%"
|
||||||
|
>
|
||||||
|
<!-- 使用 flex 布局实现整体居中 -->
|
||||||
|
<div class="flex justify-center" style="width: 100%">
|
||||||
|
<div class="flex flex-col items-start">
|
||||||
|
<div class="font-bold color-#211F24" style="font-size: 28px">{{ task.name }}</div>
|
||||||
|
<div class="color-#666666 mt-8px">{{ timestampToDayNumber(task.created_at) }}</div>
|
||||||
|
<div class="color-#666666 mt-8px">{{ task.content }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex justify-end mt-24px">
|
||||||
|
<a-button type="outline" @click="handleBack">返回</a-button>
|
||||||
|
<a-button type="outline" class="ml-12px">编辑</a-button>
|
||||||
|
<a-button type="primary" class="ml-12px">去审核</a-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import router from '@/router';
|
||||||
|
import { ref, onMounted } from 'vue';
|
||||||
|
import { useRoute } from 'vue-router';
|
||||||
|
import { getTaskSchedulesDetail } from '@/api/all/assignment-management';
|
||||||
|
import DateUtils from '@/utils/DateUtils';
|
||||||
|
const task = ref({});
|
||||||
|
// 时间戳转日期格式,并提取日期数字
|
||||||
|
const timestampToDayNumber = (timestamp: number) => {
|
||||||
|
const date = new Date(timestamp * 1000); // 假设时间戳是秒级
|
||||||
|
const year = date.getFullYear();
|
||||||
|
const month = String(date.getMonth() + 1).padStart(2, '0');
|
||||||
|
const day = String(date.getDate()).padStart(2, '0');
|
||||||
|
return `${month}月${day}日`;
|
||||||
|
};
|
||||||
|
const handleBack = () => {
|
||||||
|
router.go(-1);
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
const route = useRoute();
|
||||||
|
const noteId = route.params.id; // 从路由参数中获取笔记ID
|
||||||
|
|
||||||
|
if (noteId) {
|
||||||
|
getTaskSchedulesDetail(noteId)
|
||||||
|
.then((response) => {
|
||||||
|
if (response.data) {
|
||||||
|
// 根据API响应结构调整
|
||||||
|
const apiData = response.data.data || response.data;
|
||||||
|
console.log(apiData);
|
||||||
|
task.value = apiData;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((error) => {});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.management-detail {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.van-card__title {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.van-card__desc {
|
||||||
|
margin-top: 8px;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.van-card__price {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 新增样式 */
|
||||||
|
.text-center {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 添加新的样式规则 */
|
||||||
|
.flex {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.justify-center {
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.items-start {
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mt-8px {
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -44,6 +44,7 @@ export default defineConfig(({ mode }: ConfigEnv): UserConfig => {
|
|||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
rewrite: (path) => path.replace(/^\/api/, ''),
|
rewrite: (path) => path.replace(/^\/api/, ''),
|
||||||
target: 'https://lingjiapi.lvfunai.com/api',
|
target: 'https://lingjiapi.lvfunai.com/api',
|
||||||
|
// target: 'http://192.168.40.7/api',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user