CreateOrganize.vue 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619
  1. <template>
  2. <div class="manage-root personnel-create">
  3. <Header />
  4. <div class="manage-root-contain">
  5. <nav-menu class="manage-root-contain-left" :activeMenuIndex="activeMenuIndex"></nav-menu>
  6. <div class="manage-root-contain-right">
  7. <breadcrumb :breadcrumbList="breadcrumbList" class="breadcrumb-box"></breadcrumb>
  8. <div class="create-top">
  9. <div class="common-title-box">
  10. <h3>{{id?'编辑机构':'创建机构'}}</h3>
  11. <div class="btn-box" v-if="id||!id&&stepIndex!==2">
  12. <el-button size="small" @click="handleStep('-')" :disabled="stepIndex===0">上一步</el-button>
  13. <el-button type="primary" size="small" @click="handleStep('+')" :disabled="stepIndex===2" :loading="loading">下一步</el-button>
  14. </div>
  15. </div>
  16. <el-steps :active="stepIndex" align-center>
  17. <el-step title="机构信息" :description="id?'修改机构基本信息':'完善机构基本信息'">
  18. <svg-icon icon-class="dot" slot="icon" class="svg-dot"></svg-icon>
  19. </el-step>
  20. <el-step title="设置管理账号" description="设置机构默认管理账号" v-if="!id">
  21. <svg-icon icon-class="dot" slot="icon" class="svg-dot"></svg-icon>
  22. </el-step>
  23. <el-step :title="id?'完成修改':'完成创建'" :description="id?'机构修改完成':'机构创建完成'">
  24. <svg-icon icon-class="dot" slot="icon" class="svg-dot"></svg-icon>
  25. </el-step>
  26. </el-steps>
  27. </div>
  28. <div class="create-bottom">
  29. <el-form :model="organizeForm" :rules="rulesOrganize" ref="organizeForm" label-width="100px" class="registerForm" key="organizeForm" v-if="stepIndex===0">
  30. <el-form-item label="机构名称" prop="name">
  31. <el-input v-model="organizeForm.name" placeholder="请输入机构名称" @blur="handleTrim('organizeForm','name')" maxlength="200"></el-input>
  32. </el-form-item>
  33. <el-form-item label="机构代码" prop="sn">
  34. <el-input v-model="organizeForm.sn" placeholder="请输入机构代码" @blur="handleTrim('organizeForm','sn')" maxlength="200"></el-input>
  35. <p class="tips">4-8位英文或数字</p>
  36. </el-form-item>
  37. <el-form-item label="机构类型" prop="orgType">
  38. <el-select v-model="organizeForm.orgType" placeholder="请选择">
  39. <el-option
  40. v-for="item in $orgType"
  41. :key="item.type"
  42. :label="item.type_name"
  43. :value="item.type">
  44. </el-option>
  45. </el-select>
  46. </el-form-item>
  47. <el-form-item label="所在地区" prop="selectedOptions">
  48. <el-cascader
  49. size="medium"
  50. :options="$provinceCityList"
  51. v-model="organizeForm.selectedOptions"
  52. @change="handleCity">
  53. </el-cascader>
  54. </el-form-item>
  55. <el-form-item label="人员上限" prop="personalCeil">
  56. <el-input-number v-model="organizeForm.personalCeil" @change="handleChange" :min="1" size="small" class="personal-ceil" maxlength="20"></el-input-number>
  57. </el-form-item>
  58. <el-form-item label="机构有效期" prop="validity">
  59. <el-date-picker
  60. v-model="organizeForm.validity"
  61. type="daterange"
  62. size="small"
  63. range-separator="-"
  64. start-placeholder="开始日期"
  65. end-placeholder="结束日期"
  66. value-format="yyyy-MM-dd">
  67. </el-date-picker>
  68. </el-form-item>
  69. </el-form>
  70. <el-form :model="managerForm" :rules="rulesManager" ref="managerForm" label-width="100px" class="registerForm" key="managerForm" v-if="stepIndex===1">
  71. <el-form-item label="用户名" prop="name">
  72. <el-input v-model="managerForm.name" placeholder="请输入用户名" @blur="handleTrim('managerForm','name')" maxlength="20"></el-input>
  73. </el-form-item>
  74. <el-form-item label="真实姓名" prop="realName">
  75. <el-input v-model="managerForm.realName" placeholder="请输入真实姓名" @blur="handleTrim('managerForm','realName')" maxlength="20"></el-input>
  76. </el-form-item>
  77. <el-form-item label="手机号" prop="phone">
  78. <el-input v-model="managerForm.phone" autocomplete="off" placeholder="请输入完整手机号" @blur="handleTrim('managerForm','phone')" maxlength="20">
  79. <template slot="prepend">+86</template>
  80. </el-input>
  81. </el-form-item>
  82. <el-form-item label="邮箱" prop="email">
  83. <el-input v-model="managerForm.email" autocomplete="off" placeholder="请输入邮箱地址" @blur="handleTrim('managerForm','email')" maxlength="100">
  84. </el-input>
  85. </el-form-item>
  86. <el-form-item label="账号密码" prop="newPwd">
  87. <el-input v-model="managerForm.newPwd" :type="newPwdFlag?'text':'password'" autocomplete="off" placeholder="请输入密码" @blur="handleTrim('managerForm','newPwd')" maxlength="200">
  88. <i slot="suffix" class="el-icon-view show-icon" @click="changeIcon('newPwdFlag')" v-if="newPwdFlag"></i>
  89. <i slot="suffix" class="show-icon" @click="changeIcon('newPwdFlag')" v-else>
  90. <svg-icon icon-class="eye-invisible"></svg-icon>
  91. </i>
  92. </el-input>
  93. <p class="tips">不少于6位,且必须同时包含数字和大小写字母</p>
  94. </el-form-item>
  95. <el-form-item label="再次输入" prop="confirmPwd">
  96. <el-input v-model="managerForm.confirmPwd" :type="comfirmPwdFlag?'text':'password'" autocomplete="off" placeholder="请输入密码" @blur="handleTrim('managerForm','confirmPwd')" maxlength="200">
  97. <i slot="suffix" class="el-icon-view show-icon" @click="changeIcon('comfirmPwdFlag')" v-if="comfirmPwdFlag"></i>
  98. <i slot="suffix" class="show-icon" @click="changeIcon('comfirmPwdFlag')" v-else>
  99. <svg-icon icon-class="eye-invisible"></svg-icon>
  100. </i>
  101. </el-input>
  102. <p class="tips">再次输入密码,两次输入保持一致</p>
  103. </el-form-item>
  104. </el-form>
  105. <div v-if="stepIndex===2">
  106. <el-result icon="success" :subTitle="id?'机构编辑成功':'机构创建成功'">
  107. <template slot="extra">
  108. <el-button size="small" @click="handleback">返回列表</el-button>
  109. <el-button type="primary" size="small" @click="handleCreate">继续创建</el-button>
  110. </template>
  111. </el-result>
  112. </div>
  113. </div>
  114. </div>
  115. </div>
  116. </div>
  117. </template>
  118. <script>
  119. //这里可以导入其它文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
  120. //例如:import 《组件名称》from ‘《组件路径》';
  121. import Header from "../../components/Header.vue";
  122. import NavMenu from "../../components/NavMenu.vue"
  123. import Breadcrumb from '../../components/Breadcrumb.vue';
  124. import { getLogin } from "@/api/ajax";
  125. import { mapState } from 'vuex';
  126. export default {
  127. //import引入的组件需要注入到对象中才能使用
  128. components: { Header, NavMenu, Breadcrumb },
  129. props: {},
  130. data() {
  131. //这里存放数据
  132. const validatePhone = (rule, value, callback) => {
  133. if (value === '') {
  134. callback(new Error('请输入手机号'));
  135. } else {
  136. let reg = /^1[3-9]\d{9}$/;
  137. let result = reg.test(value);
  138. if (result) {
  139. callback();
  140. } else {
  141. callback(new Error('请输入正确的手机号'));
  142. }
  143. }
  144. };
  145. const validatePass = (rule, value, callback) => {
  146. if (value === '') {
  147. callback(new Error('请输入密码'));
  148. } else {
  149. let reg = /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])[a-zA-Z\d]{6,16}$/;
  150. let result = reg.test(value);
  151. if (result) {
  152. callback();
  153. } else {
  154. callback(new Error('密码必须同时包含数字和大小写字母'));
  155. }
  156. }
  157. };
  158. const validatePass2 = (rule, value, callback) => {
  159. if (value === '') {
  160. callback(new Error('请再次输入密码'));
  161. } else if (value !== this.managerForm.newPwd) {
  162. callback(new Error('两次输入密码不一致!'));
  163. } else {
  164. callback();
  165. }
  166. };
  167. const validateEmail = (rule, value, callback) => {
  168. if (value === '') {
  169. callback(new Error('请输入邮箱地址'));
  170. } else {
  171. let reg = /^[a-zA-Z0-9_\.-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/;
  172. let result = reg.test(value);
  173. if (result) {
  174. callback();
  175. } else {
  176. callback(new Error('请输入正确的邮箱地址'));
  177. }
  178. }
  179. };
  180. const validateCode = (rule, value, callback) => {
  181. if (value === '') {
  182. callback(new Error('请输入机构代码'));
  183. } else {
  184. let reg = /^[\da-zA-Z]{4,8}$/;
  185. let result = reg.test(value);
  186. if (result) {
  187. callback();
  188. } else {
  189. callback(new Error('机构代码只能包含英文或数字'));
  190. }
  191. }
  192. };
  193. const validateProvince = (rule, value, callback) => {
  194. if(value===[]){
  195. callback(new Error('请选择所在省市'));
  196. }else if(value.length===2){
  197. if(value[0]===''||value[1]===''){
  198. callback(new Error('请选择所在省市'));
  199. }else{
  200. callback();
  201. }
  202. }else {
  203. callback();
  204. }
  205. };
  206. const validateName = (rule, value, callback) => {
  207. if (value === '') {
  208. callback(new Error('请输入用户名'));
  209. } else {
  210. let reg = /^[a-zA-Z0-9_]{1,20}$/;
  211. let result = reg.test(value);
  212. if (result) {
  213. callback();
  214. } else {
  215. callback(new Error('不超过 20 位,可包含英文字符、数字、下划线'));
  216. }
  217. }
  218. };
  219. return {
  220. activeMenuIndex: "organize_manage",
  221. breadcrumbList:[
  222. {
  223. icon:'school-line',
  224. url:'',
  225. text:''
  226. },
  227. {
  228. icon:'',
  229. url:'/organize_manage',
  230. text:'机构管理'
  231. }
  232. ],
  233. id:this.$route.query.id?this.$route.query.id:'',
  234. stepIndex:0, // 步骤索引
  235. newPwdFlag: false, // 查看新密码
  236. comfirmPwdFlag: false, // 查看确认密码
  237. organizeForm:{
  238. name: '',
  239. sn: '',
  240. orgType: '',
  241. selectedOptions: [],
  242. personalCeil: 50,
  243. validity:''
  244. },
  245. managerForm:{
  246. name: '',
  247. realName: '',
  248. phone:'',
  249. email:'',
  250. newPwd:'', // 密码
  251. confirmPwd:'', // 确认密码
  252. },
  253. rulesOrganize:{
  254. name:[
  255. { required: true, message: '请输入机构名称', trigger: 'blur' }
  256. ],
  257. sn: [
  258. { required: true, validator: validateCode, trigger: 'blur' },
  259. { min: 4, max: 8, message: '请输入 4-8 位英文或数字', trigger:'change' }
  260. ],
  261. orgType: [
  262. { required: true, message: '请选择机构类型', trigger: 'change' }
  263. ],
  264. selectedOptions: [
  265. { type: 'array', required: true, validator: validateProvince, message: '请选择所在地区', trigger: 'change' }
  266. ],
  267. personalCeil:[
  268. { required: true, message: '请输入人员上限', trigger: 'blur' }
  269. ],
  270. validity:[
  271. { required: true, message: '请选择机构有效期', trigger: 'blur' }
  272. ]
  273. },
  274. rulesManager:{
  275. name:[
  276. { required: true, validator: validateName, trigger: 'blur' },
  277. { max: 20, message: '用户名最多20位', trigger:'change' },
  278. ],
  279. phone:[
  280. { required: true, validator: validatePhone, trigger: 'blur' }
  281. ],
  282. newPwd:[
  283. { required: true, validator: validatePass, trigger: 'blur' },
  284. { min: 6, max: 16, message: '请输入 6-16 位密码,且必须同时包含数字和大小写字母', trigger:'change' }
  285. ],
  286. confirmPwd:[
  287. { required: true, validator: validatePass2, trigger: 'blur' }
  288. ],
  289. email:[
  290. { required: true, validator: validateEmail, trigger: 'blur' },
  291. ]
  292. },
  293. province_list:[],
  294. props: {
  295. lazy: true,
  296. lazyLoad (node, resolve) {
  297. let MethodName = "/OrgServer/DictManager/GetCityList";
  298. let list = []
  299. if(node&&node.data){
  300. getLogin(MethodName, {province_id:node.data.id})
  301. .then((res) => {
  302. if(res.status===1){
  303. res.city_list.forEach(item=>{
  304. item.leaf = true
  305. item.label = item.name
  306. item.value = item.id
  307. })
  308. list = res.city_list
  309. resolve(list);
  310. }
  311. })
  312. }
  313. }
  314. },
  315. loading: false
  316. }
  317. },
  318. //计算属性 类似于data概念
  319. computed: {
  320. ...mapState(['$orgType','$provinceCityList']),
  321. },
  322. //监控data中数据变化
  323. watch: {
  324. },
  325. //方法集合
  326. methods: {
  327. // 上一步下一步
  328. handleStep(type){
  329. if(type=='-'){
  330. if(this.id){
  331. if(this.stepIndex===2){
  332. this.stepIndex = 0
  333. }
  334. }else{
  335. if(this.stepIndex>0) this.stepIndex--
  336. }
  337. }else{
  338. if(this.id){
  339. if(this.stepIndex===0){
  340. this.$refs['organizeForm'].validate((valid) => {
  341. if (!valid) {
  342. return false;
  343. }else{
  344. // this.handleSetDefaultOrg()
  345. this.editInfo()
  346. }
  347. });
  348. }
  349. }else{
  350. if(this.stepIndex===0){
  351. this.$refs['organizeForm'].validate((valid) => {
  352. if (!valid) {
  353. return false;
  354. }else{
  355. this.stepIndex++
  356. }
  357. });
  358. }else if(this.stepIndex===1){
  359. this.$refs['managerForm'].validate((valid) => {
  360. if (!valid) {
  361. return false;
  362. }else{
  363. this.handleSubmit()
  364. }
  365. });
  366. }
  367. }
  368. }
  369. },
  370. // 级联选择器
  371. handleCity(value){
  372. console.log(value)
  373. },
  374. changeIcon(flag){
  375. this[flag] = !this[flag]
  376. },
  377. // 返回列表
  378. handleback(){
  379. localStorage.setItem("pageNumber",1)
  380. this.$router.push({
  381. path: "/organize_manage",
  382. query: {
  383. },
  384. });
  385. },
  386. //继续创建
  387. handleCreate(){
  388. this.$router.replace('/createOrganize')
  389. location.reload()
  390. },
  391. handleChange(value) {
  392. // console.log(value);
  393. },
  394. // 获取省份列表
  395. getProvinceList(){
  396. let MethodName = "/OrgServer/DictManager/GetProvinceList";
  397. getLogin(MethodName, {})
  398. .then((res) => {
  399. if(res.status===1){
  400. res.province_list.forEach(item => {
  401. item.children = []
  402. item.label = item.name
  403. item.value = item.id
  404. });
  405. this.province_list = res.province_list
  406. }
  407. })
  408. .catch(() => {
  409. this.loading = false
  410. });
  411. },
  412. // 提交
  413. handleSubmit(){
  414. this.loading = true
  415. let MethodName = "/OrgServer/Manager/OrgManager/AddOrg";
  416. let data = {
  417. org:{
  418. name: this.organizeForm.name,
  419. sn: this.organizeForm.sn,
  420. type: this.organizeForm.orgType,
  421. city_id: this.organizeForm.selectedOptions[1],
  422. max_person_count: this.organizeForm.personalCeil*1,
  423. effective_date_begin: this.organizeForm.validity[0],
  424. effective_date_end: this.organizeForm.validity[1]
  425. },
  426. manager:{
  427. user_name: this.managerForm.name,
  428. real_name: this.managerForm.realName,
  429. phone: this.managerForm.phone,
  430. email: this.managerForm.email,
  431. password: this.managerForm.newPwd
  432. }
  433. }
  434. getLogin(MethodName, data)
  435. .then((res) => {
  436. this.loading = false
  437. if(res.status===1){
  438. this.stepIndex++
  439. }
  440. })
  441. .catch(() => {
  442. this.loading = false
  443. });
  444. },
  445. // 去掉前后空格
  446. handleTrim(form,fild){
  447. this[form][fild] = this[form][fild].trim()
  448. },
  449. // 获取机构信息
  450. getInfo(){
  451. let MethodName = "/OrgServer/Manager/OrgManager/GetOrgInfo";
  452. let data = {
  453. id: this.id
  454. }
  455. getLogin(MethodName, data)
  456. .then((res) => {
  457. if(res.status===1){
  458. let form = this.organizeForm
  459. let result = res.org
  460. form.name = result.name
  461. form.sn = result.sn
  462. form.orgType = result.type
  463. form.selectedOptions = [result.province_id,result.city_id]
  464. form.personalCeil = result.max_person_count
  465. form.validity = [result.effective_date_begin,result.effective_date_end]
  466. }
  467. })
  468. .catch(() => {
  469. });
  470. },
  471. // 编辑信息
  472. editInfo(){
  473. this.loading = true
  474. let MethodName = "/OrgServer/Manager/OrgManager/UpdateOrg";
  475. let data = {
  476. id: this.id,
  477. name: this.organizeForm.name,
  478. sn: this.organizeForm.sn,
  479. type: this.organizeForm.orgType,
  480. city_id: this.organizeForm.selectedOptions[1],
  481. max_person_count: this.organizeForm.personalCeil*1,
  482. effective_date_begin: this.organizeForm.validity[0],
  483. effective_date_end: this.organizeForm.validity[1]
  484. }
  485. getLogin(MethodName, data)
  486. .then((res) => {
  487. this.loading = false
  488. if(res.status===1){
  489. this.stepIndex = 2
  490. }
  491. })
  492. .catch(() => {
  493. this.loading = false
  494. });
  495. },
  496. // 设置默认机构
  497. handleSetDefaultOrg(){
  498. let MethodName = "/OrgServer/Manager/OrgManager/SetIsDefaultOrg";
  499. let data = {
  500. id: this.id,
  501. is_default: 'true',
  502. }
  503. getLogin(MethodName, data)
  504. .then((res) => {
  505. })
  506. }
  507. },
  508. //生命周期 - 创建完成(可以访问当前this实例)
  509. created() {
  510. let obj = {
  511. icon:'',
  512. url:'',
  513. text:'创建机构'
  514. }
  515. if(this.id){
  516. obj.text = '编辑机构'
  517. this.getInfo()
  518. }
  519. this.breadcrumbList.push(obj)
  520. this.getProvinceList()
  521. },
  522. //生命周期 - 挂载完成(可以访问DOM元素)
  523. mounted() {
  524. },
  525. //生命周期-创建之前
  526. beforeCreated() { },
  527. //生命周期-挂载之前
  528. beforeMount() { },
  529. //生命周期-更新之前
  530. beforUpdate() { },
  531. //生命周期-更新之后
  532. updated() { },
  533. //生命周期-销毁之前
  534. beforeDestory() { },
  535. //生命周期-销毁完成
  536. destoryed() { },
  537. //如果页面有keep-alive缓存功能,这个函数会触发
  538. activated() { }
  539. }
  540. </script>
  541. <style lang="scss" scoped>
  542. /* @import url(); 引入css类 */
  543. .create-top{
  544. background: #FFFFFF;
  545. border-radius: 4px;
  546. padding: 24px;
  547. .common-title-box{
  548. margin-bottom: 4px;
  549. }
  550. }
  551. .create-bottom{
  552. padding: 40px 40px;
  553. margin-top: 16px;
  554. background: #FFFFFF;
  555. border-radius: 4px;
  556. height: calc(100vh - 292px);
  557. overflow: auto;
  558. .tips{
  559. margin: 0;
  560. color: #86909C;
  561. font-size: 12px;
  562. line-height: 20px;
  563. }
  564. .step-table{
  565. border: 1px solid #E5E6EB;
  566. border-collapse: collapse;
  567. font-size: 14px;
  568. line-height: 22px;
  569. color: #1D2129;
  570. text-align: center;
  571. margin-bottom: 24px;
  572. &-header{
  573. background: #F7F8FA;
  574. width: 120px !important;
  575. color: #86909C;
  576. font-weight: 500;
  577. }
  578. td{
  579. height: 40px;
  580. width: 260px;
  581. border: 1px solid #E5E6EB;
  582. &.td1{
  583. width: 130px;
  584. }
  585. }
  586. .step-cascader{
  587. width: 250px;
  588. height: 32px;
  589. line-height: 32px;
  590. }
  591. }
  592. }
  593. </style>
  594. <style lang="scss">
  595. .registerForm{
  596. .show-icon{
  597. color: #4E5969;
  598. }
  599. .personal-ceil{
  600. .el-input__inner{
  601. width: 130px;
  602. }
  603. }
  604. .el-range-input{
  605. background: #F2F3F5;
  606. }
  607. }
  608. </style>