HeaderElement.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405
  1. <template>
  2. <div class="headers" :style="{backgroundColor: color}">
  3. <el-row :gutter="20" style="height: 100%">
  4. <el-col :span="1" style="height: 100%">
  5. <div class="logo"></div>
  6. </el-col>
  7. <el-col :span="4" style="height: 100%">
  8. <span class="title">数智牧场管理系统</span>
  9. </el-col>
  10. <el-col :span="10" :offset="9" style="height: 100%">
  11. <div class="flex">
  12. <div class="user" style="width: 180px;">
  13. <div>
  14. <el-select @change="onChange" size="mini" v-model="farmId">
  15. <el-option v-for="item in getFarmList" :key="item.id" :label="item.farmName" :value="item.id"></el-option>
  16. </el-select>
  17. </div>
  18. </div>
  19. <el-divider direction="vertical"></el-divider>
  20. <div class="user" style="width: 250px;">
  21. <div>
  22. <el-switch
  23. style="display: block"
  24. v-model="$store.state.mode"
  25. active-color="#13ce66"
  26. inactive-color="#ff4949"
  27. active-text="多级导航"
  28. inactive-text="折叠导航"
  29. @change="changeMode">
  30. </el-switch>
  31. </div>
  32. </div>
  33. <el-divider direction="vertical"></el-divider>
  34. <div class="user" style="width: 100px;">
  35. <div>
  36. <i class="el-icon-user-solid" style="font-size: 28px"></i>
  37. </div>
  38. <div>
  39. <el-popover
  40. placement="bottom"
  41. width="400"
  42. trigger="hover">
  43. <div style="padding: 10px">
  44. <div style="width: 100%;">
  45. <span style="color: #BBBBBB;">账户信息</span>
  46. <span class="user-right">账户设置</span>
  47. </div>
  48. <el-divider></el-divider>
  49. <el-button type="text" @click="dialogVisible = true">修改密码</el-button>
  50. <!-- <ul>-->
  51. <!-- <li>职位: <span class="user-color">厂长</span></li>-->
  52. <!-- <li>本次登录: <span class="user-color">厂长</span></li>-->
  53. <!-- <li>本次登录: <span class="user-color">厂长</span></li>-->
  54. <!-- <li>上次登录: <span class="user-color">厂长</span></li>-->
  55. <!-- </ul>-->
  56. </div>
  57. <span slot="reference">{{userName}}</span>
  58. </el-popover>
  59. </div>
  60. </div>
  61. <el-divider direction="vertical"></el-divider>
  62. <div class="user">
  63. <div style="width: 100%; text-align: center">
  64. <router-link to="/">
  65. <i class="home" title="首页"></i>
  66. </router-link>
  67. </div>
  68. </div>
  69. <el-divider direction="vertical"></el-divider>
  70. <div class="user">
  71. <div style="width: 100%; text-align: center">
  72. <el-popover
  73. placement="bottom"
  74. width="270"
  75. trigger="hover">
  76. <div class="color_flex">
  77. <chrome-picker :value="color" @input="cut"></chrome-picker>
  78. <!-- <div v-for="item in colorList" :style="{backgroundColor: item.color}" :key="item.id" class="box" @click="cut(item.color)">-->
  79. <!-- <span>点击换肤</span>-->
  80. <!-- </div>-->
  81. </div>
  82. <i slot="reference" class="colour"></i>
  83. </el-popover>
  84. </div>
  85. </div>
  86. <el-divider direction="vertical"></el-divider>
  87. <div class="user">
  88. <div style="width: 100%; text-align: center">
  89. <i class="guanbi" @click="logout" title="退出登录"></i>
  90. </div>
  91. </div>
  92. </div>
  93. </el-col>
  94. </el-row>
  95. <el-dialog
  96. title="修改密码"
  97. ref="passForms"
  98. width="30%"
  99. :visible.sync="dialogVisible"
  100. @close="passReset"
  101. >
  102. <div>
  103. <el-form :model="passWordForm" :rules="passWordRules" label-width="80px" ref="passForms">
  104. <el-form-item label="原密码" prop="password">
  105. <el-input type="password" v-model="passWordForm.password"></el-input>
  106. </el-form-item>
  107. <el-form-item label="新密码" prop="onePassWord">
  108. <el-input type="password" v-model="passWordForm.onePassWord"></el-input>
  109. </el-form-item>
  110. <el-form-item label="确认密码" prop="checkPass">
  111. <el-input type="password" v-model="passWordForm.checkPass" autocomplete="off"></el-input>
  112. </el-form-item>
  113. </el-form>
  114. </div>
  115. <span slot="footer" class="dialog-footer">
  116. <el-button @click="passReset">取 消</el-button>
  117. <el-button type="primary" @click="onPassSubmit('passForms')">保 存</el-button>
  118. </span>
  119. </el-dialog>
  120. </div>
  121. </template>
  122. <script>
  123. import { mapState, mapActions } from 'vuex'
  124. import {findUpdate, getFarmId, findOne, editPassWord} from '../utils/api';
  125. import { Chrome } from 'vue-color';
  126. import { Debounce } from "../utils";
  127. export default {
  128. name: "HeaderElement",
  129. computed: {
  130. ...mapState(['color', 'farmList', 'farmId', 'userName'])
  131. },
  132. components: {
  133. // 'slider-picker': Slider,
  134. 'chrome-picker': Chrome
  135. },
  136. watch: {
  137. farmList: {
  138. handler(newVal) {
  139. if(newVal.length > 0) {
  140. this.getFarmList = []
  141. newVal.forEach(item => {
  142. if(item.rowStatus) {
  143. this.getFarmList.push(item)
  144. }
  145. })
  146. }
  147. },
  148. deep: true
  149. }
  150. },
  151. data() {
  152. let validPassword=(rule,value,callback)=>{
  153. let reg= /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,16}$/
  154. if(!reg.test(value)){callback(new Error('密码必须是字母+数字组合6-16位密码'))
  155. }else{
  156. callback()
  157. }
  158. };
  159. let validatePass2 = (rule, value, callback) => {
  160. if (value === '') {
  161. callback(new Error('请再次输入密码'));
  162. } else if (value !== this.passWordForm.onePassWord) {
  163. callback(new Error('两次输入密码不一致!'));
  164. } else {
  165. callback();
  166. }
  167. };
  168. let validatePass3 = (rule, value, callback) => {
  169. let password = localStorage.getItem('password')
  170. if(value === '') {
  171. callback(new Error('请输入原密码'));
  172. } else if (value !== password) {
  173. callback(new Error('原密码错误!'));
  174. } else {
  175. callback();
  176. }
  177. }
  178. return {
  179. getFarmList: [],
  180. dialogVisible: false,
  181. passWordForm: {
  182. account: '',
  183. password: '',
  184. onePassWord: '',
  185. checkPass: ''
  186. },
  187. passWordRules: {
  188. password: [
  189. { validator: validatePass3, trigger: 'blur' }
  190. ],
  191. onePassWord: [
  192. { validator: validPassword, trigger: 'blur' }
  193. ],
  194. checkPass: [
  195. { validator: validatePass2, trigger: 'blur' }
  196. ],
  197. },
  198. account: '',
  199. password: '',
  200. }
  201. },
  202. methods: {
  203. ...mapActions(['setModeAsync', 'setColorAsync', 'GetFarm', 'setFarmIdAsync']),
  204. cut: Debounce(function(data) {
  205. this.setColorAsync(data.hex)
  206. let params = {
  207. id: localStorage.getItem('UserId'),
  208. color: data.hex
  209. }
  210. findUpdate(params).then(res => {
  211. if(res.code === 10000) {
  212. console.log(res)
  213. }
  214. })
  215. }),
  216. changeMode(val) {
  217. let params = {
  218. id: localStorage.getItem('UserId'),
  219. mode: val
  220. }
  221. findUpdate(params).then(res => {
  222. console.log(res)
  223. })
  224. this.setModeAsync(val)
  225. },
  226. logout() {
  227. localStorage.removeItem('UserName');
  228. localStorage.removeItem('accessToken');
  229. localStorage.removeItem('UserId');
  230. localStorage.removeItem('lastFarmId')
  231. localStorage.removeItem('password')
  232. this.$router.replace('/login');
  233. },
  234. // 拿到farmid
  235. init() {
  236. getFarmId({}).then(res => {
  237. console.log(res)
  238. if(res.code == 10000) {
  239. this.setFarmIdAsync(res.data);
  240. localStorage.setItem('lastFarmId', res.data);
  241. }
  242. })
  243. let params = {
  244. id: localStorage.getItem('UserId'),
  245. }
  246. findOne(params).then(res => {
  247. if(res.code == 10000) {
  248. localStorage.setItem('password', res.data.password);
  249. }
  250. })
  251. },
  252. // 选择牧场
  253. onChange(val) {
  254. let params = {
  255. id: localStorage.getItem('UserId'),
  256. lastFarmId: val
  257. }
  258. localStorage.setItem('lastFarmId', val)
  259. findUpdate(params).then(res => {
  260. console.log(res.data)
  261. setTimeout(() => {
  262. location.reload();
  263. }, 1000)
  264. })
  265. this.setFarmIdAsync(val);
  266. },
  267. passReset() {
  268. this.dialogVisible = false;
  269. this.passWordForm = {
  270. account: '',
  271. password: '',
  272. onePassWord: '',
  273. checkPass: '',
  274. }
  275. },
  276. onPassSubmit(ElForm) {
  277. this.$refs[ElForm].validate((valid) => {
  278. if(valid) {
  279. let params = {
  280. account: localStorage.getItem('UserName'),
  281. password: this.passWordForm.password,
  282. newPassword: this.passWordForm.onePassWord
  283. }
  284. editPassWord(params).then(res => {
  285. if(res.code === 10000) {
  286. this.$message.success('修改密码成功!将重新登录')
  287. setTimeout(() => {
  288. this.logout()
  289. }, 1000);
  290. } else {
  291. this.$message.error('修改密码失败!')
  292. }
  293. }).finally(() => {
  294. this.passReset()
  295. })
  296. }
  297. })
  298. }
  299. },
  300. created() {
  301. this.GetFarm()
  302. },
  303. mounted() {
  304. this.init();
  305. }
  306. }
  307. </script>
  308. <style scoped>
  309. p {
  310. margin: 0;
  311. display: inline-block;
  312. position: relative;
  313. }
  314. /deep/.el-row {
  315. margin: 0 !important;
  316. }
  317. /deep/.el-divider--vertical {
  318. margin: 0 15px;
  319. }
  320. /deep/.el-switch__label {
  321. color: white;
  322. }
  323. .headers {
  324. width: 100%;
  325. height: 50px;
  326. }
  327. .logo {
  328. width: 50px;
  329. height: 50px;
  330. margin: 0 auto;
  331. background-image: url("../assets/logo.png");
  332. background-size: 100% 100%;
  333. }
  334. .title {
  335. font-size: 18px;
  336. font-weight: 700;
  337. line-height: 50px;
  338. color: #fff;
  339. }
  340. .flex {
  341. width: 100%;
  342. height: 50px;
  343. color: #fff;
  344. display: flex;
  345. align-items: center;
  346. }
  347. .user {
  348. width: 80px;
  349. height: 50px;
  350. display: flex;
  351. align-items: center;
  352. cursor: pointer;
  353. }
  354. .user-right {
  355. float: right;
  356. margin-right: 10px;
  357. cursor: pointer;
  358. color: #31C3A6;
  359. }
  360. li {
  361. margin-bottom: 10px;
  362. color: #BBBBBB;
  363. }
  364. .user-color {
  365. color: #000
  366. }
  367. .colour {
  368. display: inline-block;
  369. width: 32px;
  370. height: 32px;
  371. background-image: url("../assets/images/colour.png");
  372. background-size: 100% 100%;
  373. }
  374. .color_flex {
  375. width: 100%;
  376. height: 260px;
  377. padding: 10px;
  378. }
  379. .box {
  380. cursor: pointer;
  381. text-align: center;
  382. color: #fff;
  383. line-height: 80px;
  384. }
  385. .box:hover {
  386. content: '点击换肤';
  387. }
  388. .guanbi {
  389. display: inline-block;
  390. width: 32px;
  391. height: 32px;
  392. background-image: url("../assets/images/guanbi.png");
  393. background-size: 100% 100%;
  394. }
  395. .home {
  396. display: inline-block;
  397. width: 28px;
  398. height: 28px;
  399. background-image: url("../assets/images/home.png");
  400. background-size: 100% 100%;
  401. }
  402. </style>