Merge branch 'master' of http://120.76.84.145:10101/gitblit/r/H5/shehong-vehicle-supervision
New file |
| | |
| | | <template> |
| | | <div> |
| | | <video id="video" width="100%" height="100%" muted controls></video> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import { playDetection, closeRealVideo } from './service' |
| | | import flvjs from 'flv.js' |
| | | export default { |
| | | props: { |
| | | serverIp: { |
| | | type: String, |
| | | required: '' |
| | | }, |
| | | serverPort: { |
| | | type: Number, |
| | | required: null |
| | | }, |
| | | carId: { |
| | | type: Number, |
| | | required: null |
| | | }, |
| | | }, |
| | | data() { |
| | | return { |
| | | flvPlayer: null, |
| | | timer: null, |
| | | } |
| | | }, |
| | | mounted() { |
| | | this.playDetection() |
| | | }, |
| | | beforeDestroy() { |
| | | this.destroyPlayer(); |
| | | }, |
| | | methods: { |
| | | playDetection() { |
| | | if (flvjs.isSupported()) { |
| | | playDetection(this.carId).then(res => { |
| | | this.flvPlayer = flvjs.createPlayer({ |
| | | type: 'flv',//视频类型 |
| | | isLive: true,//是否为直播 |
| | | cors: true,//是否开启跨域 |
| | | hasAudio: false,//是否开启音频 |
| | | hasVideo: true,//是否开启视频 |
| | | url: `http://${this.serverIp}:${this.serverPort}/live?port=1935&app=flv&stream=${this.carId}`, // 后端拿到的视频路径 |
| | | enableWorker: true, //启用 Web Worker 进程来加速视频的解码和处理过程 |
| | | enableStashBuffer: false, // 启用数据缓存机制,提高视频的流畅度和稳定性。 |
| | | stashInitialSize: 1024, // 初始缓存大小。单位:字节。建议针对直播:调整为1024kb |
| | | stashInitialTime: 0.2, // 缓存初始时间。单位:秒。建议针对直播:调整为200毫秒 |
| | | seekType: 'range', // 建议将其设置为“range”模式,以便更快地加载视频数据,提高视频的实时性。 |
| | | lazyLoad: false, //关闭懒加载模式,从而提高视频的实时性。建议针对直播:调整为false |
| | | lazyLoadMaxDuration: 0.2, // 懒加载的最大时长。单位:秒。建议针对直播:调整为200毫秒 |
| | | deferLoadAfterSourceOpen: false // 不预先加载视频数据,在 MSE(Media Source Extensions)打开后立即加载数据,提高视频的实时性。建议针对直播:调整为false |
| | | }); |
| | | let video = document.getElementById('video'); |
| | | this.flvPlayer.attachMediaElement(video); // video容器 |
| | | this.flvPlayer.load(); |
| | | this.flvPlayer.play().then(res => { |
| | | this.timer = setInterval(() => { |
| | | playDetection(this.carId) |
| | | }, 5000) |
| | | }).catch(err => { |
| | | this.destroyPlayer(); |
| | | }) |
| | | // 错误监听 |
| | | this.flvPlayer.on('error', (err) => { |
| | | this.destroyPlayer(); |
| | | }); |
| | | }) |
| | | } |
| | | }, |
| | | destroyPlayer() { |
| | | // 销毁播放器释放资源 |
| | | if (this.flvPlayer) { |
| | | if (this.timer) clearInterval(this.timer) |
| | | closeRealVideo(this.carId).then(res => { |
| | | this.flvPlayer.pause(); |
| | | this.flvPlayer.unload(); |
| | | this.flvPlayer.detachMediaElement(); |
| | | this.flvPlayer.destroy(); |
| | | this.flvPlayer = null; |
| | | }) |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style></style> |
New file |
| | |
| | | import axios from '@/utils/request'; |
| | | |
| | | // 通知后端开始获取视频流 |
| | | export const playDetection = (id) => { |
| | | return axios.get(`/system/car/playDetection/${id}`) |
| | | } |
| | | |
| | | // 通知后端开始关闭视频流 |
| | | export const closeRealVideo = (id) => { |
| | | return axios.get(`/system/car/closeRealVideo/${id}`) |
| | | } |
| | |
| | | <template>
|
| | | <div class="sticky top0 layout">
|
| | | <div class="header relative pointer">
|
| | | <div class="header relative">
|
| | | <div @click="$router.push('/home')" class="title">
|
| | | <img src="@/assets/logo.png" alt="">
|
| | | 射洪“两客一危”监管平台
|
| | |
| | | <div></div>
|
| | | <div class="flex a-center pr--40">
|
| | | <div class="flex a-center mr--72">
|
| | | <img src="@/assets/header/photo.png" class="w--32 h--32 shrink0 mr--10" />
|
| | | <div class="fs-- 18 lh--25 color2">admin</div>
|
| | | <img src="@/assets/header/photo.png" class="w--32 h--32 shrink0 mr--10"
|
| | | style="border-radius: 50%;" />
|
| | | <div class="fs-- 18 lh--25 color2">{{ $store.state.userInfo.nickName }}</div>
|
| | | </div>
|
| | | <div class="dropdown" @mouseenter="toggleDropdown(true)" @mouseleave="toggleDropdown(false)">
|
| | | <img src="@/assets/header/more.png" class="w--16 h--16" />
|
| | | <div v-if="isOpen" class="dropdown-menu">
|
| | | <div class="dropdown-item" v-for="item in menuItems" :key="item.text">
|
| | | <div @click="clickItem(item)" class="dropdown-item" v-for="item in menuItems" :key="item.text">
|
| | | <i :class="item.icon"></i> {{ item.text }}
|
| | | </div>
|
| | | </div>
|
| | |
| | | <div class="main">
|
| | | <router-view></router-view>
|
| | | </div>
|
| | | <ResetPassword v-if="passwordVisible" :row="row" :dialogVisible="passwordVisible"
|
| | | @close="passwordVisible = false, row = {}" @confirm="passwordConfirm" />
|
| | | </div>
|
| | | </template>
|
| | |
|
| | | <script>
|
| | | import routes from '@/router/router'
|
| | | import { mapMutations } from 'vuex';
|
| | | import ResetPassword from '@/view/systemManage/user/components/resetPassWord.vue'
|
| | | import { updatePwd } from '@/view/systemManage/user/service'
|
| | | export default {
|
| | | components: {
|
| | | ResetPassword,
|
| | | },
|
| | | data() {
|
| | | return {
|
| | | routesList: routes,
|
| | |
| | | menuItems: [
|
| | | { text: '密码设置' },
|
| | | { text: '退出登录' },
|
| | | ]
|
| | | ],
|
| | | passwordVisible: false,
|
| | | row: {}
|
| | | };
|
| | | },
|
| | | created() {
|
| | | },
|
| | | methods: {
|
| | | ...mapMutations(['clearToken']),
|
| | | passwordConfirm(form) {
|
| | | updatePwd(form).then(() => {
|
| | | this.row = {}
|
| | | this.passwordVisible = false
|
| | | this.msgsuccess('修改密码成功')
|
| | | })
|
| | | },
|
| | | clickItem(item) {
|
| | | switch (item.text) {
|
| | | case '密码设置':
|
| | | this.row = this.$store.state.userInfo
|
| | | this.passwordVisible = true
|
| | | break;
|
| | | case '退出登录':
|
| | | this.clearToken()
|
| | | window.location.replace(`/`);
|
| | | break;
|
| | | default:
|
| | | break;
|
| | | }
|
| | | },
|
| | | pushPath(path) {
|
| | | this.$router.push(path)
|
| | | if (this.routerIsOpen) this.routerIsOpen = false
|
| | |
| | | display: flex;
|
| | | flex-direction: column;
|
| | | height: 100%;
|
| | |
|
| | | .main {
|
| | | flex: 1;
|
| | | overflow: auto;
|
| | | }
|
| | | }
|
| | |
|
| | | .bgColor1 {
|
| | | background-color: #0E6EFD;
|
| | | }
|
| | |
| | | import {
|
| | | Message
|
| | | } from 'element-ui'
|
| | | import PlayLive from '@/components/PlayLive'
|
| | |
|
| | | Vue.use(ElementUI)
|
| | | Vue.prototype.$cookies = cookies;
|
| | | Vue.prototype.$baseURL = apiConfig.baseURL
|
| | | Vue.prototype.$mapKey = apiConfig.mapKey
|
| | | Vue.prototype.$secretKey = apiConfig.secretKey
|
| | | Vue.prototype.$store = store
|
| | | Vue.config.productionTip = false
|
| | | Vue.component('PlayLive', PlayLive)
|
| | | /* 全局TableHeight */
|
| | | Vue.prototype.$baseTableHeight = (formType) => {
|
| | | let height = window.innerHeight
|
| | |
| | | export default new Vuex.Store({
|
| | | state: {
|
| | | token: localStorage.getItem('token') || sessionStorage.getItem('token') || '',
|
| | | userInfo: localStorage.getItem('userInfo') || {}
|
| | | userInfo: JSON.parse(localStorage.getItem('userInfo')) || {}
|
| | | },
|
| | | mutations: {
|
| | | setToken(state, token) {
|
| | |
| | | const service = axios.create({
|
| | | baseURL: apiConfig.baseURL,
|
| | | withCredentials: false, // 当跨域请求时发送cookie
|
| | | timeout: 30000, // request timeout
|
| | | timeout: 60000, // request timeout
|
| | | })
|
| | | // 对 POST 请求参数进行排序
|
| | | const sortPostParams = (params) => {
|
| | |
| | | <div v-if="showWarnDetail" class="fixed"> |
| | | <div class="card"> |
| | | <div class="title fs--18 color2">视频信号遮挡报警</div> |
| | | <div id="mapContainer"></div> |
| | | <div id="mapContainers"></div> |
| | | <div class=""> |
| | | <div class="flex mt--15"> |
| | | <div class="w--100 shrink0 color1">司机:</div> |
| | |
| | | ], |
| | | }) |
| | | .then((AMap) => { |
| | | this.map = new AMap.Map("mapContainer", { |
| | | this.map = new AMap.Map("mapContainers", { |
| | | center: [row.lon, row.lat], |
| | | zoom: 15, |
| | | }); |
| | |
| | | width: 100%; |
| | | height: 600px; |
| | | } |
| | | #mapContainers { |
| | | width: 100%; |
| | | height: 500px; |
| | | margin: 20px 0; |
| | | } |
| | | |
| | | ::v-deep .el-drawer__body { |
| | | position: relative; |
| | | |
| | | .fixed { |
| | | right: 470px; |
| | | top: 0; |
| | | bottom: 0; |
| | | margin: auto; |
| | | display: flex; |
| | | align-items: center; |
| | | |
| | | .card { |
| | | background: #fff; |
| | | width: 500px; |
| | | max-height: 1000px; |
| | | padding: 15px; |
| | | } |
| | | } |
| | | } |
| | | .color1 { |
| | | color: #0E6EFD; |
| | | } |
| | | |
| | | .color2 { |
| | | color: rgb(52, 52, 52); |
| | | } |
| | | |
| | | ::v-deep .pagination-popper { |
| | | position: fixed !important; |
| | | transform: |
| | | scale(calc(1 / var(--scale))) translate(calc(100px * (1 - 1 / var(--scale))), |
| | | calc(5px * (1 - 1 / var(--scale)))) !important; |
| | | transform-origin: right top !important; |
| | | right: calc(30px * (1 - 1 / var(--scale))) !important; |
| | | margin-top: 5px; |
| | | min-width: 100px !important; |
| | | } |
| | | </style> |
| | |
| | | size="small">重置</el-button> |
| | | </div> |
| | | </div> |
| | | <div class="table-box-btn mt--23 ml--30"> |
| | | <el-button class="search-button h--40 w--90 fs--14" icon="el-icon-top" type="primary" size="small" |
| | | @click="exportExcell">导出</el-button> |
| | | </div> |
| | | <div class="table-box ml--30 mt--23 mr--30"> |
| | | <el-table :data="tableData" border stripe style="width: 100%"> |
| | | <el-table-column type="index" label="序号" width="60"></el-table-column> |
| | |
| | | //获取车辆详情实时视频 |
| | | export const getCarVideo = (data) => { |
| | | return axios.get(`/system/car/getRealVideo/${data.id}`) |
| | | } |
| | | |
| | | // 获取车辆预警详情 |
| | | export const getDetail = (params) => { |
| | | console.log(params) |
| | | return axios.get('/system/warn/getCarWarnInfo', {params}) |
| | | } |
| | |
| | | <template> |
| | | <div> |
| | | <div class="bgImg"> |
| | | <div class="login_box"> |
| | | <div class="fs--40 fw-bold"> |
| | | <h1> |
| | | 射洪“两客一危”监管平台 |
| | | </h1> |
| | | </div> |
| | | <div class="mt--20 txt-center py--20 px--20 br--10 box-s1"> |
| | | <div class="mt--20 txt-center py--20 px--20"> |
| | | <div class="fs--20 fw-bold">登陆</div> |
| | | <div class="mt--20"> |
| | | <el-input class="w100" prefix-icon="el-icon-user" placeholder="账号" v-model="username" /> |
| | |
| | | document.removeEventListener("keydown", this.handleKeyDown); |
| | | }, |
| | | methods: { |
| | | ...mapMutations(['setToken', 'clearToken', 'setUserInfo']), |
| | | ...mapMutations(['setToken', 'setUserInfo']), |
| | | login() { |
| | | if (!this.rulesLogin()) return |
| | | this.loginLoading = true; |
| | | loginPwd({ |
| | | username: this.username, |
| | | password: CryptoJS.HmacMD5(this.password, 'password').toString( |
| | | CryptoJS.enc.Hex, |
| | | ) |
| | | password: CryptoJS.MD5(this.password).toString() |
| | | }).then(res => { |
| | | localStorage.setItem('client', generateRandomString(16)); |
| | | this.loginLoading = false; |
| | |
| | | }; |
| | | </script> |
| | | <style scoped lang="less"> |
| | | .bgImg { |
| | | background-image: url('../../assets/loginBG.png'); |
| | | background-size: cover; |
| | | background-position: center; |
| | | background-repeat: no-repeat; |
| | | width: 100%; |
| | | height: 100%; |
| | | } |
| | | |
| | | .login_box { |
| | | position: absolute; |
| | | top: 50%; |
| | | left: 50%; |
| | | transform: translate(-50%, -50%); |
| | | } |
| | | |
| | | .box-s1 { |
| | | background-color: #fff; |
| | | box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.2); |
| | | border-radius: 10px; |
| | | padding: 20px; |
| | | } |
| | | |
| | | .code_box { |
| | |
| | | <template> |
| | | <div> |
| | | <el-dialog title="订单详情" :visible.sync="dialogVisible" width="50%" :modal-append-to-body="false"> |
| | | <el-dialog title="订单详情" :visible.sync="dialogVisible" width="50%" :modal-append-to-body="false" |
| | | @close="closeClick"> |
| | | <el-radio-group v-model="tabPosition" style="margin-bottom: 30px;"> |
| | | <el-radio-button label="order">订单信息</el-radio-button> |
| | | <el-radio-button label="track">行程轨迹</el-radio-button> |
| | |
| | | </el-descriptions> |
| | | </div> |
| | | <!-- 行程轨迹 --> |
| | | <div v-show="tabPosition == 'track'"> |
| | | <div v-if="tabPosition == 'track'"> |
| | | <div class="mapContainer" id="mapContainer"></div> |
| | | </div> |
| | | <!-- 行程监控 --> |
| | | <div v-show="tabPosition == 'monitoring'"></div> |
| | | <div v-if="tabPosition == 'monitoring'"> |
| | | <PlayLive :serverIp="monitoringData.serverIp" :serverPort="monitoringData.serverPort" |
| | | :carId="orderData.carId" /> |
| | | </div> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | |
| | | tabPosition: 'order', |
| | | orderData: {}, |
| | | monitoringData: {}, |
| | | travelData: [] |
| | | travelData: [], |
| | | }; |
| | | }, |
| | | computed: {}, |
| | | watch: {}, |
| | | created() { }, |
| | | watch: { |
| | | tabPosition(val) { |
| | | if (val == 'track') { |
| | | this.$nextTick(() => { |
| | | this.initMap(); |
| | | }) |
| | | return |
| | | } |
| | | } |
| | | }, |
| | | methods: { |
| | | initData(orderData = {}, monitoringData = {}, travelData = {},) { |
| | | initData(orderData = {}, monitoringData = {}, travelData = []) { |
| | | this.orderData = orderData |
| | | this.monitoringData = monitoringData |
| | | this.travelData = travelData |
| | | this.dialogVisible = true |
| | | this.initMap(); |
| | | }, |
| | | initMap() { |
| | | window._AMapSecurityConfig = { |
| | |
| | | .then((AMap) => { |
| | | this.map = new AMap.Map("mapContainer", { |
| | | center: [this.travelData[this.travelData.length / 2].longitude, this.travelData[this.travelData.length / 2].latitude], |
| | | zoom: 15, |
| | | zoom: 12, |
| | | }); |
| | | this.map.addControl(new AMap.ToolBar()); |
| | | let path = this.travelData.map(item => { |
| | | return new AMap.LngLat(item.longitude, item.latitude) |
| | | }) |
| | | const content = `<div class="custom-content-marker"> |
| | | <img src="${require("@/assets/logo.png")}"> |
| | | 起点 |
| | | </div>`; |
| | | const marker = new AMap.Marker({ |
| | | content: content, //自定义点标记覆盖物内容 |
| | | position: [this.travelData[0].longitude, this.travelData[0].latitude], //基点位置 |
| | | offset: new AMap.Pixel(-30, -15), //相对于基点的偏移位置 |
| | | }); |
| | | |
| | | const contentTwo = `<div class="custom-content-marker-two"> |
| | | 终点 |
| | | </div>`; |
| | | const marker = [ |
| | | new AMap.Marker({ |
| | | content: content, //自定义点标记覆盖物内容 |
| | | position: [this.travelData[0].longitude, this.travelData[0].latitude], //基点位置 |
| | | offset: new AMap.Pixel(-35, -25), //相对于基点的偏移位置 |
| | | }), |
| | | new AMap.Marker({ |
| | | content: contentTwo, //自定义点标记覆盖物内容 |
| | | position: [this.travelData[this.travelData.length - 1].longitude, this.travelData[this.travelData.length - 1].latitude], //基点位置 |
| | | offset: new AMap.Pixel(-35, -25), //相对于基点的偏移位置 |
| | | }) |
| | | ] |
| | | this.map.add(marker); |
| | | let polyline = new AMap.Polyline({ |
| | | path: path, |
| | | strokeWeight: 2, //线条宽度 |
| | | strokeWeight: 3, //线条宽度 |
| | | strokeColor: "red", //线条颜色 |
| | | lineJoin: "round", //折线拐点连接处样式 |
| | | }); |
| | | this.map.add(polyline); |
| | | // 强制刷新地图 |
| | | this.$nextTick(() => { |
| | | this.map.resize(); |
| | | }); |
| | | }) |
| | | .catch((e) => { |
| | | }); |
| | | }, |
| | | closeClick() { |
| | | this.dialogVisible = false |
| | | } |
| | | this.tabPosition = 'order' |
| | | this.orderData = {} |
| | | this.monitoringData = {} |
| | | this.travelData = [] |
| | | }, |
| | | }, |
| | | }; |
| | | </script> |
| | | <style> |
| | | .custom-content-marker { |
| | | width: 30px; |
| | | height: 30px; |
| | | width: 50px; |
| | | height: 50px; |
| | | background-color: blue; |
| | | color: #fff; |
| | | border-radius: 50%; |
| | | line-height: 50px; |
| | | text-align: center; |
| | | } |
| | | |
| | | .custom-content-marker-two { |
| | | width: 50px; |
| | | height: 50px; |
| | | background-color: orange; |
| | | color: #fff; |
| | | border-radius: 50%; |
| | | line-height: 50px; |
| | | text-align: center; |
| | | } |
| | | |
| | | .custom-content-marker img { |
| | |
| | | |
| | | #mapContainer { |
| | | width: 100%; |
| | | height: 300px; |
| | | height: 500px; |
| | | } |
| | | </style> |
| | |
| | | <template> |
| | | <div> |
| | | <div v-loading="loading" element-loading-text="加载中..."> |
| | | <div class="form flex a-center j-between mt--23"> |
| | | <div class="form-left ml--30"> |
| | | <el-form :inline="true" :model="searchForm"> |
| | |
| | | <script> |
| | | import DetailModal from "./component/detailModal" |
| | | import { exportExcell } from '@/utils/utils' |
| | | import { getOrderList, getOrderInfo, getOrderMonitoring, getOrderTravel } from './service' |
| | | import { getOrderList, getOrderInfo, getOrderMonitoring, getOrderTravel, } from './service' |
| | | import moment from "moment/moment"; |
| | | |
| | | export default { |
| | |
| | | pageSize: 10 |
| | | }, |
| | | tableData: [], |
| | | loading: false, |
| | | }; |
| | | }, |
| | | computed: { |
| | |
| | | obj.orderDeliveryTimeEnd = moment(obj.orderDeliveryTime[1]).format('YYYY-MM-DD HH-mm-ss') |
| | | delete obj.orderDeliveryTime |
| | | } |
| | | exportExcell('投诉记录导出', obj, '/system/order/exportOrderList') |
| | | exportExcell('订单记录导出', obj, '/system/order/exportOrderList') |
| | | }, |
| | | handleSizeChange(e) { |
| | | this.searchForm.pageSize = e |
| | |
| | | }) |
| | | }, |
| | | showDetail(row) { |
| | | // Promise.all([getOrderInfo(row.id), getOrderMonitoring({ id: row.id }), getOrderTravel({ id: row.id })]).then(res => { |
| | | Promise.all([getOrderInfo(row.id), getOrderTravel({ id: row.id })]).then(res => { |
| | | this.$refs.detailModal.initData(res[0], {}, res[2]) |
| | | this.loading = true |
| | | Promise.all([getOrderInfo(row.id), getOrderMonitoring({ id: row.id }), getOrderTravel({ id: row.id })]).then(res => { |
| | | // Promise.all([getOrderInfo(row.id), getOrderTravel({ id: row.id })]).then(res => { |
| | | this.$refs.detailModal.initData(res[0], res[1], res[2]) |
| | | this.loading = false |
| | | }).catch(err => { |
| | | this.loading = false |
| | | }) |
| | | }, |
| | | } |
| | |
| | | width: 100% !important; |
| | | } |
| | | } |
| | | |
| | | ::v-deep .el-loading-mask { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | |
| | | .el-loading-spinner { |
| | | width: unset; |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | } |
| | | } |
| | | </style> |
| | |
| | | <template> |
| | | <div> |
| | | <el-dialog :visible.sync="dialogVisible" @close="$emit('close')" :title="row.deptId ? '编辑人员' : '添加人员'" |
| | | width="30%"> |
| | | width="30%" :modal-append-to-body="false"> |
| | | <el-form ref="form" :model="form" :rules="rules" label-width="80px"> |
| | | <el-form-item label="姓名" prop="nickName"> |
| | | <el-input v-model="form.nickName" placeholder="请输入" style="width: 50%;"></el-input> |
| | |
| | | <template> |
| | | <div> |
| | | <el-dialog :visible.sync="dialogVisible" @close="$emit('close')" title="禁用人员" width="30%"> |
| | | <el-dialog :visible.sync="dialogVisible" @close="$emit('close')" title="禁用人员" width="30%" :modal-append-to-body="false"> |
| | | <el-form ref="form" :model="form" label-width="80px"> |
| | | <el-form-item label="姓名" prop="nickName"> |
| | | {{ form.nickName }} |
| | |
| | | <template> |
| | | <div> |
| | | <el-dialog :visible.sync="dialogVisible" @close="$emit('close')" title="重置密码" |
| | | width="30%"> |
| | | <el-dialog :visible.sync="dialogVisible" @close="$emit('close')" title="重置密码" width="30%" |
| | | :modal-append-to-body="false"> |
| | | <el-form ref="form" :model="form" :rules="rules" label-width="80px"> |
| | | <el-form-item label="姓名" prop="nickName"> |
| | | <el-input :disabled="true" v-model="form.nickName" placeholder="请输入" style="width: 50%;"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="登陆账号" prop="account"> |
| | | <el-input :disabled="true" v-model="form.account" placeholder="请输入" style="width: 50%;"></el-input> |
| | | <el-input :disabled="true" v-model="form.userName" placeholder="请输入" style="width: 50%;"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="新密码" prop="password"> |
| | | <el-input v-model="form.password" placeholder="请输入" style="width: 50%;"></el-input> |
| | |
| | | </template> |
| | | |
| | | <script> |
| | | import CryptoJS from 'crypto-js'; |
| | | export default { |
| | | props: { |
| | | dialogVisible: { |
| | |
| | | form: { status: true }, |
| | | rules: { |
| | | password: [{ required: true, message: '请新密码', trigger: 'blur' }], |
| | | confirmPassword: [{ required: true, message: '请确认密码', trigger: 'blur' },{ |
| | | confirmPassword: [{ required: true, message: '请确认密码', trigger: 'blur' }, { |
| | | validator: (rule, value, callback) => { |
| | | if (value !== this.form.password) { |
| | | callback(new Error('两次输入密码不一致!')); |
| | | } else { |
| | | callback(); |
| | | } |
| | | }}], |
| | | } |
| | | }], |
| | | } |
| | | }; |
| | | }, |
| | |
| | | this.form = { |
| | | userId: this.row.userId, |
| | | nickName: this.row.nickName, |
| | | account: this.row.userName, |
| | | userName: this.row.userName, |
| | | } |
| | | } |
| | | }, |
| | |
| | | this.form.orderNum = 0 |
| | | this.form.ancestors = 0 |
| | | this.form.parentId = 100 |
| | | this.form.password = CryptoJS.MD5(this.form.password).toString() |
| | | this.$emit('confirm', this.form) |
| | | } |
| | | }) |