diff --git a/admin/src/api/admin.js b/admin/src/api/admin.js index e25c360b..a47a3365 100644 --- a/admin/src/api/admin.js +++ b/admin/src/api/admin.js @@ -1,16 +1,55 @@ -import request from '@/utils/request' +import request from "@/utils/request"; // 获取路线列表 export function getProductsList() { - return request({ - url: 'admin/products/list', - method: 'get' - }) + return request({ + url: "admin/products/list", + method: "get", + }); } export function addProducts(data) { - return request({ - url: '/admin/products/add', - method: 'post', - data - }) -} \ No newline at end of file + return request({ + url: "/admin/products/add", + method: "post", + data, + }); +} +// 获取商品列表 +export function getProductsListsApi(data) { + return request({ + url: `/admin/products/list?page=${data.page}&limit=${data.limit}`, + method: "get", + }); +} +// 添加商品 +export function postAddProductApi(data) { + return request({ + url: `/admin/products/add`, + method: "post", + data, + }); +} + +// 商品排期详情 +export function getProductSchedules(data) { + return request({ + url: `/admin/products/productschedules?id=${data}`, + method: "get", + }); +} +// 添加商品排期 +export function addProductSchedulesApi(data) { + return request({ + url: `/admin/products/addproductschedules`, + method: "post", + data, + }); +} + +// 合同管理列表 +export function getContractListsApi() { + return request({ + url: `/admin/setting/getContractSetting`, + method: "get", + }); +} diff --git a/admin/src/layout/components/Sidebar/SidebarItem.vue b/admin/src/layout/components/Sidebar/SidebarItem.vue index 05ad7f6a..43241f14 100644 --- a/admin/src/layout/components/Sidebar/SidebarItem.vue +++ b/admin/src/layout/components/Sidebar/SidebarItem.vue @@ -7,7 +7,10 @@ !item.alwaysShow " > - + import('@/views/redirect/index') - } - ] + path: "/redirect/:path(.*)", + component: () => import("@/views/redirect/index"), + }, + ], }, { - path: '/login', - component: () => import('@/views/login/index'), - hidden: true + path: "/login", + component: () => import("@/views/login/index"), + hidden: true, }, { - path: '/home', - component: () => import('@/views/home/index'), - hidden: true + path: "/home", + component: () => import("@/views/home/index"), + hidden: true, }, { - path: '/line_on_sale', - component: () => import('@/views/home/line_on_sale'), - hidden: true + path: "/line_on_sale", + component: () => import("@/views/home/line_on_sale"), + hidden: true, }, { - path: '/auth-redirect', - component: () => import('@/views/login/auth-redirect'), - hidden: true + path: "/auth-redirect", + component: () => import("@/views/login/auth-redirect"), + hidden: true, }, { - path: '/404', - component: () => import('@/views/error-page/404'), - hidden: true + path: "/404", + component: () => import("@/views/error-page/404"), + hidden: true, }, { - path: '/401', - component: () => import('@/views/error-page/401'), - hidden: true + path: "/401", + component: () => import("@/views/error-page/401"), + hidden: true, }, { - path: '/', + path: "/", component: Layout, - redirect: '/dashboard', + redirect: "/dashboard", children: [ { - path: 'dashboard', - component: () => import('@/views/dashboard/index'), - name: 'Dashboard', - meta: { title: '系统面板', icon: 'dashboard', affix: true } - } - ] - } -] + path: "dashboard", + component: () => import("@/views/dashboard/index"), + name: "Dashboard", + meta: { title: "系统面板", icon: "dashboard", affix: true }, + }, + ], + }, +]; /** * asyncRoutes @@ -74,53 +74,82 @@ export const constantRoutes = [ */ export const asyncRoutes = [ { - path: '/system', + path: "/system", component: Layout, - redirect: '/system', + redirect: "/system", alwaysShow: true, - name: 'System', + name: "System", meta: { - title: '系统管理', - icon: 'el-icon-s-home', - roles: ['admin'] + title: "系统管理", + icon: "el-icon-s-home", + roles: ["admin"], }, children: [ { - path: 'admin', - component: () => import('@/views/admin/index'), - name: 'Admin', + path: "admin", + component: () => import("@/views/admin/index"), + name: "Admin", meta: { - title: '管理员', - roles: ['admin'] - } + title: "管理员", + roles: ["admin"], + }, }, { - path: 'works', - component: () => import('@/views/admin/works'), - name: 'Works', + path: "works", + component: () => import("@/views/admin/works"), + name: "Works", meta: { - title: '排班表', - roles: ['admin'] - } + title: "排班表", + roles: ["admin"], + }, }, { - path: 'scheduling', - component: () => import('@/views/scheduling/index'), - name: 'scheduling', + path: "scheduling", + component: () => import("@/views/scheduling/index"), + name: "scheduling", meta: { - title: '直播排班', - roles: ['admin'] - } + title: "直播排班", + roles: ["admin"], + }, }, { - path: 'onlines', - component: () => import('@/views/onlines/online.vue'), - name: 'onlines', + path: "onlines", + component: () => import("@/views/onlines/online.vue"), + name: "onlines", meta: { - title: '在线客服', - roles: ['admin'] - } - }/*, + title: "在线客服", + roles: ["admin"], + }, + }, + { + path: "proManagement", + component: () => import("@/views/proManagement/index"), + name: "ProManagement", + meta: { + title: "商品管理", + roles: ["admin"], + }, + }, + { + path: "contract", + component: () => import("@/views/proManagement/contract"), + name: "ProManagementContract", + meta: { + title: "合同管理", + roles: ["admin"], + }, + }, + { + path: "proScheduling", + component: () => import("@/views/proManagement/scheduling"), + name: "ProScheduling", + meta: { + title: "排班管理", + roles: ["admin"], + hidden: true, + }, + }, + /*, { path: 'shortcut', component: () => import('@/views/shortcut/shortcutContent.vue'), @@ -139,28 +168,28 @@ export const asyncRoutes = [ roles: ['admin'] } }*/ - ] + ], }, { - path: '/order', + path: "/order", component: Layout, - redirect: '/order/index', + redirect: "/order/index", alwaysShow: true, - name: 'Orders', + name: "Orders", meta: { - title: '订单管理', - icon: 'money', - roles: ['order_index', 'editor'] + title: "订单管理", + icon: "money", + roles: ["order_index", "editor"], }, children: [ { - path: 'index', - component: () => import('@/views/order/index'), - name: 'OrderList', + path: "index", + component: () => import("@/views/order/index"), + name: "OrderList", meta: { - title: '订单列表', - roles: ['order_pub', 'editor'] - } + title: "订单列表", + roles: ["order_pub", "editor"], + }, }, /* { path: 'pub', @@ -172,122 +201,122 @@ export const asyncRoutes = [ } },*/ { - path: 'back', - component: () => import('@/views/order/back'), - name: 'OrderBack', + path: "back", + component: () => import("@/views/order/back"), + name: "OrderBack", meta: { - title: '流转订单', - roles: ['order_back', 'editor'] - } + title: "流转订单", + roles: ["order_back", "editor"], + }, }, { - path: 'abandoned', - component: () => import('@/views/order/abandoned'), - name: 'OrderBack', + path: "abandoned", + component: () => import("@/views/order/abandoned"), + name: "OrderBack", meta: { - title: '已放弃订单', - roles: ['order_back', 'editor'] - } + title: "已放弃订单", + roles: ["order_back", "editor"], + }, }, { - path: 'used', - component: () => import('@/views/order/used'), - name: 'OrderBack', + path: "used", + component: () => import("@/views/order/used"), + name: "OrderBack", meta: { - title: '已使用订单', - roles: ['order_back', 'editor'] - } + title: "已使用订单", + roles: ["order_back", "editor"], + }, }, { - path: 'refunded', - component: () => import('@/views/order/refunded'), - name: 'OrderBack', + path: "refunded", + component: () => import("@/views/order/refunded"), + name: "OrderBack", meta: { - title: '已退款订单', - roles: ['order_back', 'editor'] - } + title: "已退款订单", + roles: ["order_back", "editor"], + }, }, { - path: 'appointment', - component: () => import('@/views/order/appointment'), - name: 'appointment', + path: "appointment", + component: () => import("@/views/order/appointment"), + name: "appointment", meta: { - title: '预约记录', - roles: ['order_back', 'editor'] - } + title: "预约记录", + roles: ["order_back", "editor"], + }, }, - ] + ], }, { - path: '/qa', + path: "/qa", component: Layout, - redirect: '/qa/qa', + redirect: "/qa/qa", alwaysShow: true, - name: 'Qa', + name: "Qa", meta: { - title: 'QA管理', - icon: 'el-icon-question', - roles: ['order_index', 'editor', 'franchisee'] + title: "QA管理", + icon: "el-icon-question", + roles: ["order_index", "editor", "franchisee"], }, children: [ { - path: 'problem', - component: () => import('@/views/qa/problem.vue'), - name: 'problem', + path: "problem", + component: () => import("@/views/qa/problem.vue"), + name: "problem", meta: { - title: 'QA常见问题', - roles: ['order_pub', 'editor', 'franchisee'] - } + title: "QA常见问题", + roles: ["order_pub", "editor", "franchisee"], + }, }, { - path: 'qa', - component: () => import('@/views/qa/qa.vue'), - name: 'qa', + path: "qa", + component: () => import("@/views/qa/qa.vue"), + name: "qa", meta: { - title: 'QA管理列表', - roles: ['admin'] - } + title: "QA管理列表", + roles: ["admin"], + }, }, { - path: 'city', - component: () => import('@/views/qa/city.vue'), - name: 'city', + path: "city", + component: () => import("@/views/qa/city.vue"), + name: "city", meta: { - title: '城市管理列表', - roles: ['admin'] - } - } - ] + title: "城市管理列表", + roles: ["admin"], + }, + }, + ], }, { - path: '/data', + path: "/data", component: Layout, - redirect: '/data/index', + redirect: "/data/index", alwaysShow: true, - name: 'Data', + name: "Data", meta: { - title: '数据统计', - icon: 'chart', - roles: ['data_index'] + title: "数据统计", + icon: "chart", + roles: ["data_index"], }, children: [ { - path: 'product', - component: () => import('@/views/order/product'), - name: 'productNameList', + path: "product", + component: () => import("@/views/order/product"), + name: "productNameList", meta: { - title: '产品统计', - roles: ['order_pub', 'editor'] - } + title: "产品统计", + roles: ["order_pub", "editor"], + }, }, { - path: 'index', - component: () => import('@/views/data/index'), - name: 'Index', + path: "index", + component: () => import("@/views/data/index"), + name: "Index", meta: { - title: '跟进统计', - roles: ['data_index'] - } + title: "跟进统计", + roles: ["data_index"], + }, }, /* { path: 'online', @@ -308,98 +337,100 @@ export const asyncRoutes = [ } },*/ { - path: 'sale', - component: () => import('@/views/data/sale'), - name: 'Sale', + path: "sale", + component: () => import("@/views/data/sale"), + name: "Sale", meta: { - title: '销售统计', - roles: ['data_sale'] - } - } - ] - }, { - path: '/log', + title: "销售统计", + roles: ["data_sale"], + }, + }, + ], + }, + { + path: "/log", component: Layout, - redirect: '/log/index', + redirect: "/log/index", alwaysShow: true, - name: 'Log', + name: "Log", meta: { - title: '日志记录', - icon: 'nested', - roles: ['follow_index', 'log_index', 'editor', 'franchisee'] + title: "日志记录", + icon: "nested", + roles: ["follow_index", "log_index", "editor", "franchisee"], }, children: [ { - path: 'follow', - component: () => import('@/views/log/follow'), - name: 'Follow', + path: "follow", + component: () => import("@/views/log/follow"), + name: "Follow", meta: { - title: '跟进记录', - roles: ['follow_index', 'editor', 'franchisee'] - } + title: "跟进记录", + roles: ["follow_index", "editor", "franchisee"], + }, }, { - path: 'index', - component: () => import('@/views/log/index'), - name: 'LogIndex', + path: "index", + component: () => import("@/views/log/index"), + name: "LogIndex", meta: { - title: '日志记录', - roles: ['log_index'] - } - } - ] + title: "日志记录", + roles: ["log_index"], + }, + }, + ], }, { - path: '/announcements', + path: "/announcements", component: Layout, - redirect: '/announcements/index', + redirect: "/announcements/index", alwaysShow: true, - name: 'announcements', + name: "announcements", meta: { - title: '公告管理', - icon: 'el-icon-s-promotion', - roles: ['admin'] + title: "公告管理", + icon: "el-icon-s-promotion", + roles: ["admin"], }, children: [ { - path: 'list', - component: () => import('@/views/announcements/list'), - name: 'list', + path: "list", + component: () => import("@/views/announcements/list"), + name: "list", meta: { - title: '公告列表', - roles: ['admin'] - } - } - ] + title: "公告列表", + roles: ["admin"], + }, + }, + ], }, { - path: '/icon', + path: "/icon", component: Layout, children: [ { - path: 'index', - component: () => import('@/views/icons/index'), - name: 'Icons', - meta: { title: 'Icons', icon: 'icon', noCache: true } - } - ] + path: "index", + component: () => import("@/views/icons/index"), + name: "Icons", + meta: { title: "Icons", icon: "icon", noCache: true }, + }, + ], }, // 404 page must be placed at the end !!! - { path: '*', redirect: '/404', hidden: true } -] + { path: "*", redirect: "/404", hidden: true }, +]; -const createRouter = () => new Router({ - // mode: 'history', // require service support - scrollBehavior: () => ({ y: 0 }), - routes: constantRoutes -}) +const createRouter = () => + new Router({ + // mode: 'history', // require service support + scrollBehavior: () => ({ y: 0 }), + routes: constantRoutes, + }); -const router = createRouter() +const router = createRouter(); // Detail see: https://github.com/vuejs/vue-router/issues/1234#issuecomment-357941465 export function resetRouter() { - const newRouter = createRouter() - router.matcher = newRouter.matcher // reset router + const newRouter = createRouter(); + router.matcher = newRouter.matcher; // reset router } -export default router +export default router; diff --git a/admin/src/utils/request.js b/admin/src/utils/request.js index 11ef1818..76d8a493 100644 --- a/admin/src/utils/request.js +++ b/admin/src/utils/request.js @@ -1,87 +1,89 @@ -import axios from 'axios' -import { MessageBox, Message } from 'element-ui' -import store from '@/store' -import { getToken,removeToken } from '@/utils/auth' - -// create an axios instance +import axios from "axios"; +import { MessageBox, Message } from "element-ui"; +import store from "@/store"; +import { getToken, removeToken } from "@/utils/auth"; const service = axios.create({ baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url // withCredentials: true, // send cookies when cross-domain requests - timeout: 10000 // request timeout -}) + timeout: 10000, // request timeout +}); // request interceptor service.interceptors.request.use( - config => { + (config) => { // do something before request is sent if (store.getters.token) { // let each request carry token // ['X-Token'] is a custom headers key // please modify it according to the actual situation - config.headers['X-Token'] = getToken() + config.headers["X-Token"] = getToken(); } - return config + return config; }, - error => { + (error) => { // do something with request error - return Promise.reject(error) + return Promise.reject(error); } -) +); // response interceptor service.interceptors.response.use( /** * If you want to get http information such as headers or status * Please return response => response - */ + */ /** * Determine the request status by custom code * Here is just an example * You can also judge the status by HTTP Status Code */ - response => { - const res = response.data + (response) => { + const res = response.data; // if the custom code is not 20000, it is judged as an error. if (res.error !== 0) { Message({ - message: res.msg || 'Error', - type: 'error', - duration: 5 * 1000 - }) + message: res.msg || "Error", + type: "error", + duration: 5 * 1000, + }); // 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired; if (res.code === 50008 || res.code === 50012 || res.code === 50014) { // to re-login - MessageBox.confirm('You have been logged out, you can cancel to stay on this page, or log in again', 'Confirm logout', { - confirmButtonText: 'Re-Login', - cancelButtonText: 'Cancel', - type: 'warning' - }).then(() => { - store.dispatch('user/resetToken').then(() => { - location.reload() - }) - }) + MessageBox.confirm( + "You have been logged out, you can cancel to stay on this page, or log in again", + "Confirm logout", + { + confirmButtonText: "Re-Login", + cancelButtonText: "Cancel", + type: "warning", + } + ).then(() => { + store.dispatch("user/resetToken").then(() => { + location.reload(); + }); + }); } if (res.code == 400) { - removeToken() + removeToken(); } - return Promise.reject(new Error(res.message || 'Error')) + return Promise.reject(new Error(res.message || "Error")); } else { - return res + return res; } }, - error => { - console.log('err' + error) // for debug + (error) => { + console.log("err" + error); // for debug Message({ message: error.message, - type: 'error', - duration: 5 * 1000 - }) - return Promise.reject(error) + type: "error", + duration: 5 * 1000, + }); + return Promise.reject(error); } -) +); -export default service +export default service; diff --git a/admin/src/views/proManagement/contract.vue b/admin/src/views/proManagement/contract.vue new file mode 100644 index 00000000..b41fd66a --- /dev/null +++ b/admin/src/views/proManagement/contract.vue @@ -0,0 +1,62 @@ + + + + diff --git a/admin/src/views/proManagement/index.vue b/admin/src/views/proManagement/index.vue new file mode 100644 index 00000000..b9b79d4f --- /dev/null +++ b/admin/src/views/proManagement/index.vue @@ -0,0 +1,463 @@ + + + diff --git a/admin/src/views/proManagement/scheduling.vue b/admin/src/views/proManagement/scheduling.vue new file mode 100644 index 00000000..7979960f --- /dev/null +++ b/admin/src/views/proManagement/scheduling.vue @@ -0,0 +1,178 @@ + + + + +