| | |
| | | "svg-sprite-loader": "^6.0.11", |
| | | "vue": "^2.6.14", |
| | | "vue-i18n": "^8.26.7", |
| | | "vue-router": "^3.6.5", |
| | | "vue-router": "^3.0.7", |
| | | "vuex": "^3.6.2", |
| | | "web-storage-cache": "^1.1.1" |
| | | }, |
| | |
| | | "svg-sprite-loader": "^6.0.11", |
| | | "vue": "^2.6.14", |
| | | "vue-i18n": "^8.26.7", |
| | | "vue-router": "^3.6.5", |
| | | "vue-router": "^3.0.7", |
| | | "vuex": "^3.6.2", |
| | | "web-storage-cache": "^1.1.1" |
| | | }, |
| | |
| | | <template> |
| | | <div class="sales-lead"> |
| | | <div class="header-title">{{ headerTitle }}</div> |
| | | <div class="header-user-info"> |
| | | <div class="avatar"><el-avatar icon="el-icon-user-solid"></el-avatar></div> |
| | | <el-dropdown @command="handleCommand"> |
| | | <div class="el-dropdown-link">用户名<i class="el-icon-arrow-down el-icon--right"></i></div> |
| | | <el-dropdown-menu slot="dropdown"> |
| | | <el-dropdown-item command="logout">退出</el-dropdown-item> |
| | | </el-dropdown-menu> |
| | | </el-dropdown> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | |
| | | name: "SalesLead", |
| | | props: { |
| | | headerTitle: String |
| | | }, |
| | | data() { |
| | | return {} |
| | | }, |
| | | methods: { |
| | | handleCommand(command) { |
| | | console.log(command) |
| | | if (command === "logout") { |
| | | this.$router.push({ path: "/login" }) |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | |
| | | <!-- Add "scoped" attribute to limit CSS to this component only --> |
| | | <style lang="scss" scoped> |
| | | .sales-lead { |
| | | display: flex; |
| | | height: 55px; |
| | | line-height: 55px; |
| | | background-color: #fff; |
| | |
| | | font-size: 16px; |
| | | color: #475059; |
| | | } |
| | | .header-user-info { |
| | | margin-left: auto; |
| | | margin-right: 20px; |
| | | display: flex; |
| | | .avatar { |
| | | margin-top: 8px; |
| | | margin-right: 10px; |
| | | } |
| | | } |
| | | } |
| | | </style> |
| | |
| | | <i class="el-icon-tickets"></i> |
| | | </div> |
| | | <!-- 地图 --> |
| | | <div v-if="mapButton" class="btn-icon" @click="mapBtnClick"> |
| | | <div v-if="mapButton" class="btn-icon" title="地图" @click="mapBtnClick"> |
| | | <i class="el-icon-location-information"></i> |
| | | </div> |
| | | <!-- 统计 --> |
| | | <div v-if="statistics" class="btn-icon" @click="statisticsBtnClick"> |
| | | <div v-if="statistics" class="btn-icon" title="统计" @click="statisticsBtnClick"> |
| | | <i class="el-icon-data-line"></i> |
| | | </div> |
| | | <!-- 客户漏斗 --> |
| | | <div v-if="customFunnel" class="btn-icon" @click="statisticsBtnClick" style="color: #666"> |
| | | <i class="el-icon-postcard" title="客户漏斗"></i> |
| | | <div v-if="customFunnel" class="btn-icon" title="客户漏斗" @click="statisticsBtnClick" style="color: #666"> |
| | | <i class="el-icon-postcard"></i> |
| | | </div> |
| | | </div> |
| | | </div> |
| | |
| | | border-radius: 4px; |
| | | color: rgb(0, 102, 255); |
| | | background-color: #f2f4fb; |
| | | cursor: pointer; |
| | | } |
| | | .view-scope { |
| | | display: flex; |
| | |
| | | <el-option v-for="item in queryClassOptions" :key="item.value" :label="item.label" :value="item.value"> |
| | | </el-option> |
| | | </el-select> |
| | | <div class="query-class-btn"> |
| | | <div class="query-class-btn" @click="queryClassClick"> |
| | | <i class="el-icon-setting"></i> |
| | | </div> |
| | | </div> |
| | |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <!-- 查询分类弹窗 --> |
| | | <QueryClassSettingDialog v-if="queryClassSetConfig.visible" :editCommonConfig="queryClassSetConfig" /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import QueryClassSettingDialog from "@/views/other/QueryClassSettingDialog.vue" |
| | | |
| | | export default { |
| | | name: "SearchCommonView", |
| | | components: { QueryClassSettingDialog }, |
| | | props: { |
| | | queryClass: { |
| | | type: String, |
| | |
| | | }, |
| | | data() { |
| | | return { |
| | | queryClassSetConfig: { |
| | | visible: false, |
| | | infomation: {} |
| | | }, |
| | | queryClassValue: this.queryClass, |
| | | searchInput: "", |
| | | searchSelValue: this.searchSel, |
| | |
| | | } |
| | | }, |
| | | methods: { |
| | | queryClassClick() { |
| | | this.queryClassSetConfig = { |
| | | visible: true |
| | | } |
| | | }, |
| | | searchClick() { |
| | | console.log("sssssssssss") |
| | | }, |
| | |
| | | font-size: 16px; |
| | | margin-left: 10px; |
| | | color: #bebebe; |
| | | cursor: pointer; |
| | | } |
| | | } |
| | | .search { |
| | |
| | | margin-left: 20px; |
| | | .other-search-high { |
| | | display: flex; |
| | | cursor: pointer; |
| | | .high-icon { |
| | | font-size: 18px; |
| | | } |
| | |
| | | .other-search-tile, |
| | | .other-search-label { |
| | | display: flex; |
| | | cursor: pointer; |
| | | margin-left: 20px; |
| | | .high-icon { |
| | | font-size: 18px; |
| | |
| | | :label="item.label" |
| | | :width="item.width" |
| | | :min-width="item.min" |
| | | show-overflow-tooltip="true" |
| | | show-overflow-tooltip |
| | | sortable |
| | | > |
| | | <template slot-scope="scope"> |
| | |
| | | </template> |
| | | </el-table-column> |
| | | <slot name="tableButton" /> |
| | | <div slot="empty"> |
| | | <el-empty description="暂无数据"></el-empty> |
| | | </div> |
| | | </el-table> |
| | | </div> |
| | | </template> |
| | |
| | | name: "salesLead", |
| | | component: salesLead, |
| | | meta: { |
| | | title: "销售线索" |
| | | title: "销售线索", |
| | | requireAuth: true |
| | | } |
| | | }, |
| | | { |
| | |
| | | name: "customManage", |
| | | component: customManage, |
| | | meta: { |
| | | title: "客户管理" |
| | | title: "客户管理", |
| | | requireAuth: true |
| | | } |
| | | }, |
| | | { |
| | |
| | | name: "contacts", |
| | | component: contacts, |
| | | meta: { |
| | | title: "联系人" |
| | | title: "联系人", |
| | | requireAuth: true |
| | | } |
| | | }, |
| | | { |
| | |
| | | name: "followupRecords", |
| | | component: followupRecords, |
| | | meta: { |
| | | title: "跟进记录" |
| | | title: "跟进记录", |
| | | requireAuth: true |
| | | } |
| | | } |
| | | ] |
| | |
| | | |
| | | const router = createRouter() |
| | | |
| | | // router.beforeEach((to, from, next) => { |
| | | // must call `next` |
| | | // console.log(to, from) |
| | | // if (to.path === "/custom/salesLead") { |
| | | // next() |
| | | // } else { |
| | | // if (to.meta.requireAuth) { |
| | | // next({ |
| | | // path: "/login", |
| | | // query: { redirect: to.fullPath } |
| | | // }) |
| | | // } else { |
| | | // next() |
| | | // } |
| | | // } |
| | | // }) |
| | | |
| | | export default router |
| | |
| | | <template> |
| | | <div class="login"> |
| | | <h1>login</h1> |
| | | <div class="page-login"> |
| | | <div class="page-login--layer"> |
| | | <div class="page-login--content" flex="dir:top cross:stretch box:justify"> |
| | | <div class="page-login--content-header"> |
| | | <p class="page-login--content-header-motto"> |
| | | <!-- 时间是一切财富中最宝贵的财富 --> |
| | | </p> |
| | | </div> |
| | | <div class="page-login--content-main" flex="dir:top main:center cross:center"> |
| | | <!-- logo --> |
| | | <!-- <img class="page-login--logo" src="./image/logo@2x.png" /> --> |
| | | <!-- form --> |
| | | <div class="page-login--form"> |
| | | <span style="font-family: PingFangSC-Medium, sans-serif">登录</span> |
| | | <el-card shadow="never"> |
| | | <el-form ref="loginForm" label-position="top" :rules="rules" :model="formLogin" size="default"> |
| | | <el-form-item prop="username"> |
| | | <el-input type="text" v-model="formLogin.username" placeholder="用户名"> </el-input> |
| | | </el-form-item> |
| | | <el-form-item prop="password"> |
| | | <el-input type="password" v-model="formLogin.password" placeholder="密码" show-password id="password"> |
| | | </el-input> |
| | | <i id="iconfont" class="iconfont icon-biyanjing" @click="clickeye()"></i> |
| | | </el-form-item> |
| | | <!-- <el-form-item prop="code"> |
| | | <el-input type="text" v-model="formLogin.code" placeholder="验证码"> |
| | | <template slot="append"> |
| | | <img class="login-code" :src="captcha" @click="getCaptchaData" /> |
| | | </template> |
| | | </el-input> |
| | | </el-form-item> --> |
| | | <el-button size="default" @click="submit" type="primary" class="button-login"> 登录 </el-button> |
| | | </el-form> |
| | | </el-card> |
| | | <div class="error" style="font-size: 14px; float: left"> |
| | | {{ this.error }} |
| | | </div> |
| | | <p class="page-login--options"> |
| | | <span> 注册</span> |
| | | <span>|</span> |
| | | <span>忘记密码</span> |
| | | </p> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | // import { mapActions } from "vuex" |
| | | // import "@/assets/font/iconfont" |
| | | |
| | | export default { |
| | | name: "LoginOn", |
| | | props: {} |
| | | name: "LoginView", |
| | | data() { |
| | | return { |
| | | captcha: "", |
| | | // timeInterval: null, |
| | | // time: dayjs().format("HH:mm:ss"), |
| | | // 快速选择用户 |
| | | dialogVisible: false, |
| | | // 表单 |
| | | formLogin: { |
| | | username: "admin", |
| | | password: "123456", |
| | | code: "" |
| | | }, |
| | | // 表单校验 |
| | | rules: { |
| | | username: [ |
| | | { |
| | | required: true, |
| | | message: "请输入用户名", |
| | | trigger: "blur" |
| | | } |
| | | ], |
| | | password: [ |
| | | { |
| | | required: true, |
| | | message: "请输入密码", |
| | | trigger: "blur" |
| | | } |
| | | ], |
| | | code: [ |
| | | { |
| | | required: true, |
| | | message: "请输入验证码", |
| | | trigger: "blur" |
| | | } |
| | | ] |
| | | }, |
| | | error: "" |
| | | } |
| | | }, |
| | | mounted() { |
| | | this.timeInterval = setInterval(() => { |
| | | // this.refreshTime() |
| | | }, 1000) |
| | | this.getCaptchaData() |
| | | }, |
| | | beforeDestroy() { |
| | | clearInterval(this.timeInterval) |
| | | }, |
| | | methods: { |
| | | getCaptchaData() {}, |
| | | |
| | | /** |
| | | * @description 提交表单 |
| | | */ |
| | | // 提交登录信息 |
| | | submit() { |
| | | this.$refs.loginForm.validate((valid) => { |
| | | if (valid) { |
| | | // 登录 |
| | | // 注意 这里的演示没有传验证码 |
| | | // 具体需要传递的数据请自行修改代码 |
| | | // this.login({ |
| | | // username: this.formLogin.username, |
| | | // password: this.formLogin.password, |
| | | // captcha: this.formLogin.code |
| | | // }).then((rsp) => { |
| | | // // 重定向对象不存在则返回顶层路径 |
| | | // if (rsp != "") { |
| | | // // this.$message.warning(rsp); |
| | | // this.error = "填入信息错误,请检查!" |
| | | // let _this = this |
| | | // setTimeout(function () { |
| | | // _this.error = "" |
| | | // }, 3000) |
| | | // return |
| | | // } |
| | | this.$router.replace(this.$route.query.redirect || "/").catch((err) => { |
| | | console.log(err) |
| | | }) |
| | | // }) |
| | | } else { |
| | | // 登录表单校验失败 |
| | | // this.$message.error("表单校验失败,请检查"); |
| | | this.error = "填入信息错误,请检查!" |
| | | var _this = this |
| | | setTimeout(function () { |
| | | _this.error = "" |
| | | }, 3000) |
| | | } |
| | | }) |
| | | }, |
| | | //点击眼睛 |
| | | clickeye() { |
| | | // let eye = document.getElementById("iconfont") |
| | | let pwd = document.getElementById("password") |
| | | if (pwd.type == "password") { |
| | | // ;(pwd.type = "text"), (eye.className = "iconfont icon-yanjing") |
| | | } else { |
| | | // ;(pwd.type = "password"), (eye.className = "iconfont icon-biyanjing") |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <!-- Add "scoped" attribute to limit CSS to this component only --> |
| | | <style scoped> |
| | | h3 { |
| | | margin: 40px 0 0; |
| | | <style lang="scss"> |
| | | .el-icon-view:before { |
| | | content: ""; |
| | | } |
| | | ul { |
| | | list-style-type: none; |
| | | padding: 0; |
| | | .iconfont:before { |
| | | line-height: 48px; |
| | | position: absolute; |
| | | right: 19px; |
| | | font-size: 18px; |
| | | color: rgba(0, 0, 0, 0.4); |
| | | } |
| | | li { |
| | | display: inline-block; |
| | | margin: 0 10px; |
| | | } |
| | | a { |
| | | color: #42b983; |
| | | .page-login { |
| | | background-size: 100%; |
| | | height: 100%; |
| | | position: relative; |
| | | .page-login--layer-area { |
| | | overflow: hidden; |
| | | } |
| | | // 时间 |
| | | .page-login--layer-time { |
| | | font-size: 24em; |
| | | font-weight: bold; |
| | | color: rgba(0, 0, 0, 0.03); |
| | | overflow: hidden; |
| | | } |
| | | // 登陆页面控件的容器 |
| | | .page-login--content { |
| | | height: 100%; |
| | | min-height: 500px; |
| | | position: relative; |
| | | top: 0; |
| | | left: 0; |
| | | } |
| | | // header |
| | | .page-login--content-header { |
| | | padding: 1em 0; |
| | | .page-login--content-header-motto { |
| | | margin: 0px; |
| | | padding: 0px; |
| | | color: beige; |
| | | text-align: center; |
| | | font-size: 12px; |
| | | } |
| | | } |
| | | // main |
| | | .page-login--logo { |
| | | width: 240px; |
| | | margin-bottom: 2em; |
| | | margin-top: -2em; |
| | | position: absolute; |
| | | top: 7%; |
| | | left: 3%; |
| | | } |
| | | // 登录表单 |
| | | .page-login--form { |
| | | width: 431px; |
| | | height: 400px; |
| | | left: 50%; |
| | | top: 30%; |
| | | transform: translate(-50%, 0%); |
| | | position: absolute; |
| | | background: #fafbff; |
| | | opacity: 0.9; |
| | | border-radius: 24px; |
| | | padding: 35px 36px; |
| | | text-align: center; |
| | | font-size: 36px; |
| | | line-height: 48px; |
| | | color: #181f30; |
| | | .el-form { |
| | | display: flex; |
| | | flex-direction: column; |
| | | justify-content: center; |
| | | align-items: center; |
| | | .el-form-item { |
| | | margin-bottom: 24px; |
| | | width: 359px; |
| | | height: 48px; |
| | | background: #fff; |
| | | border: 8px; |
| | | .el-input__inner { |
| | | font-size: 14px; |
| | | height: 48px; |
| | | line-height: 20px; |
| | | padding-left: 16px; |
| | | color: #181f30; |
| | | } |
| | | } |
| | | } |
| | | // 卡片 |
| | | .el-card { |
| | | margin-bottom: 15px; |
| | | background: transparent; |
| | | border: 0; |
| | | } |
| | | // 登录按钮 |
| | | .button-login { |
| | | width: 359px; |
| | | height: 48px; |
| | | font-size: 16px; |
| | | line-height: 20px; |
| | | font-family: PingFangSC-Medium, sans-serif; |
| | | } |
| | | // 输入框左边的图表区域缩窄 |
| | | .el-input-group__prepend { |
| | | padding: 0px 14px; |
| | | } |
| | | .login-code { |
| | | height: 40px - 2px; |
| | | display: block; |
| | | margin: 0px -20px; |
| | | border-top-right-radius: 2px; |
| | | border-bottom-right-radius: 2px; |
| | | } |
| | | // 登陆选项 |
| | | .page-login--options { |
| | | font-family: PingFangSC-Medium, sans-serif; |
| | | color: #181f30 !important; |
| | | margin: 0px; |
| | | padding: 0px; |
| | | font-size: 14px; |
| | | line-height: 20px; |
| | | color: #2a78fb; |
| | | margin-right: 34px; |
| | | margin-bottom: 15px; |
| | | font-weight: bold; |
| | | float: right; |
| | | :nth-child(2) { |
| | | margin: 0px 5px; |
| | | } |
| | | } |
| | | .page-login--quick { |
| | | width: 100%; |
| | | } |
| | | } |
| | | .error { |
| | | float: left; |
| | | font-size: 14px; |
| | | line-height: 20px; |
| | | margin-left: 35px; |
| | | color: #f62f2f; |
| | | font-family: PingFangSC-Medium, sans-serif; |
| | | } |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <div class="query-class-set"> |
| | | <el-dialog title="查询分类设置" :visible.sync="editConfig.visible" :width="dialogWidth" :before-close="handleClose"> |
| | | <el-table :data="tableData" style="width: 100%" :header-cell-style="{ background: '#f4f8fe' }"> |
| | | <el-table-column label="分类名称" prop="className"> </el-table-column> |
| | | <el-table-column label="操作" width="200px"> |
| | | <template slot-scope="scope"> |
| | | <i class="el-icon-edit common-style first" title="编辑" @click="editClick(scope.$index, scope.row)"></i> |
| | | <i class="el-icon-document-copy common-style" title="复制" @click="copyClick(scope.$index, scope.row)"></i> |
| | | <i |
| | | v-if="scope.$index !== 0 && scope.$index !== tableData.length - 1" |
| | | class="el-icon-bottom common-style" |
| | | title="下移" |
| | | @click="moveDownClick(scope.$index, scope.row)" |
| | | ></i> |
| | | <i |
| | | v-if="scope.$index !== 0 && scope.$index !== 1" |
| | | class="el-icon-top common-style" |
| | | title="上移" |
| | | @click="moveUpClick(scope.$index, scope.row)" |
| | | ></i> |
| | | <i |
| | | v-if="scope.$index !== 0" |
| | | class="el-icon-delete common-style" |
| | | title="删除" |
| | | @click="deleteClick(scope.$index, scope.row)" |
| | | ></i> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <div style="padding: 10px"> |
| | | <el-button type="primary" size="mini">新建分类</el-button> |
| | | </div> |
| | | <div slot="footer" class="dialog-footer"> |
| | | <el-button type="primary" size="small" @click="editConfig.visible = false">保存</el-button> |
| | | <el-button size="small" @click="editConfig.visible = false">取消</el-button> |
| | | </div> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | name: "QueryClassSettingDialog", |
| | | props: { |
| | | editCommonConfig: { |
| | | type: Object, |
| | | default: () => { |
| | | return { |
| | | visible: false, |
| | | infomation: {} |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | components: {}, |
| | | computed: {}, |
| | | data() { |
| | | return { |
| | | dialogWidth: "30%", |
| | | editConfig: this.editCommonConfig, |
| | | tableData: [ |
| | | { |
| | | className: "全部" |
| | | }, |
| | | { |
| | | className: "过期未满60天" |
| | | }, |
| | | { |
| | | className: "过期未满30天" |
| | | }, |
| | | { |
| | | className: "已过期" |
| | | } |
| | | ] |
| | | } |
| | | }, |
| | | created() {}, |
| | | methods: { |
| | | handleClose() { |
| | | this.editConfig.visible = false |
| | | }, |
| | | // 编辑 |
| | | editClick(index, row) { |
| | | console.log(index, row) |
| | | }, |
| | | // 复制 |
| | | copyClick() {}, |
| | | // 上移 |
| | | moveUpClick(index) { |
| | | var that = this |
| | | if (index > 1) { |
| | | const upData = that.tableData[index - 1] |
| | | that.tableData.splice(index - 1, 1) |
| | | that.tableData.splice(index, 0, upData) |
| | | } |
| | | }, |
| | | // 下移 |
| | | moveDownClick(index) { |
| | | var that = this |
| | | const downData = that.tableData[index + 1] |
| | | that.tableData.splice(index + 1, 1) |
| | | that.tableData.splice(index, 0, downData) |
| | | }, |
| | | // 删除 |
| | | deleteClick() {} |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <!-- Add "scoped" attribute to limit CSS to this component only --> |
| | | <style lang="scss" scoped> |
| | | .query-class-set { |
| | | .common-style { |
| | | font-size: 16px; |
| | | margin-left: 10px; |
| | | cursor: pointer; |
| | | } |
| | | .first { |
| | | margin-left: 0px; |
| | | } |
| | | .dialog-footer { |
| | | background-color: #f5f5f5; |
| | | height: 55px; |
| | | line-height: 55px; |
| | | } |
| | | } |
| | | ::v-deep { |
| | | .el-dialog__header { |
| | | padding: 12.5px 10px; |
| | | border-bottom: 1px solid #e5e5e5; |
| | | .el-dialog__title { |
| | | font-size: 15px; |
| | | color: #323232; |
| | | font-weight: bold; |
| | | } |
| | | } |
| | | .el-dialog__body { |
| | | padding: 0px; |
| | | } |
| | | .el-dialog__footer { |
| | | padding: 0px; |
| | | text-align: center; |
| | | box-sizing: border-box; |
| | | border-top: 1px solid #dadee5; |
| | | } |
| | | } |
| | | </style> |