AccountModal1.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423
  1. <template>
  2. <a-modal :visible="true" :maskClosable="false" centered :destroyOnClose="true" :title="title"
  3. :wrapClassName="wrapClassName" :width="width" @cancel="onClose" @ok="onSubmit">
  4. <div class="content">
  5. <a-form ref="formRef" :model="form" :rules="rules" :label-col="labelCol" :wrapper-col="wrapperCol">
  6. <div class="basic-info">
  7. <div class="small-title">基础信息</div>
  8. <a-form-item label="登录名" name="loginName">
  9. <a-input v-model:value="form.loginName" style="width: 100%" placeholder="请输入登录名" :disabled="title!=='新增用户'"/>
  10. </a-form-item>
  11. <a-form-item label="用户姓名" name="userName">
  12. <a-input v-model:value="form.userName" style="width: 100%" placeholder="请输入姓名" />
  13. </a-form-item>
  14. <a-form-item label="手机号" name="mobile">
  15. <a-input v-model:value="form.mobile" style="width: 100%" placeholder="请输入手机号" />
  16. </a-form-item>
  17. <a-form-item label="密码" name="pwd">
  18. <a-input-password v-model:value="form.pwd" style="width: 100%" placeholder="请输入密码" />
  19. </a-form-item>
  20. <a-form-item label="性别" name="sex">
  21. <a-select v-model:value="form.sex" style="width: 100%">
  22. <a-select-option value="0">女</a-select-option>
  23. <a-select-option value="1">男</a-select-option>
  24. </a-select>
  25. </a-form-item>
  26. </div>
  27. <div class="basic-info">
  28. <div class="small-title">岗位信息</div>
  29. <a-form-item label="所属机构" name="ssjg">
  30. <a-tree-select v-model:value="form.ssjg" style="width: 100%"
  31. :dropdown-style="{ maxHeight: '200px', overflow: 'auto' }" :tree-data="treeData"
  32. placeholder="请选择机构"
  33. :replaceFields="{ children: 'children', title: 'name', key: 'departid', value: 'departid' }">
  34. </a-tree-select>
  35. </a-form-item>
  36. <a-form-item label="所属职位" name="sszw">
  37. <a-select v-model:value="form.sszw" style="width: 100%" placeholder="请选择职位" :options="zwOption"
  38. :dropdown-style="{ maxHeight: '150px', overflow: 'auto' }">
  39. </a-select>
  40. </a-form-item>
  41. <a-form-item label="所属岗位" name="ssgw">
  42. <a-select v-model:value="form.ssgw" style="width: 100%" placeholder="请选择岗位" :options="gwOption"
  43. :dropdown-style="{ maxHeight: '150px', overflow: 'auto' }">
  44. </a-select>
  45. </a-form-item>
  46. <a-form-item label="角色" name="userjsArr">
  47. <a-select v-model:value="form.userjsArr" mode="multiple" style="width: 100%" placeholder="请选择角色"
  48. :dropdown-style="{ maxHeight: '150px', overflow: 'auto' }" :options="jsOption" :maxTagCount="4">
  49. </a-select>
  50. </a-form-item>
  51. </div>
  52. </a-form>
  53. </div>
  54. <template #footer>
  55. <div class="btns" style="display: flex;justify-content: center;">
  56. <a-button class="btn" @click="onClose"
  57. style="width: 64px;height: 34px;margin-right: 25px;color: #333333;">取消</a-button>
  58. <a-button class="btn" @click="onSubmit"
  59. style="width: 64px;height: 34px;background: #0671DD;color: #ffffff;">确定</a-button>
  60. </div>
  61. </template>
  62. </a-modal>
  63. </template>
  64. <script>
  65. import { defineComponent, reactive, ref, onMounted, watch, toRefs } from 'vue';
  66. import { message } from 'ant-design-vue';
  67. import moment from 'moment';
  68. import { v4 as uuidv4 } from 'uuid';
  69. import md5 from 'js-md5';
  70. import { savePosts } from '/@/api/sys/zhiwei';
  71. // 正则表达式验证
  72. import { ChineseRegexp, EmailRegexp, phoneRegexp } from '/@/utils/rules';
  73. // 验证手机号与登录名重复性
  74. import { isAccountExist, IsPhoneExist, SaveOrUpdateUserInfo } from '/@/api/system/system';
  75. // 导入接口
  76. import { structureList, getPostsList, getPositionList } from '/@/api/sys/position';
  77. //角色列表api
  78. import { roleList } from '/@/api/sys/user';
  79. const props = {
  80. formData: {
  81. type: Object,
  82. default: {}
  83. },
  84. title: {
  85. type: String,
  86. default: "新增职位"
  87. }
  88. }
  89. export default defineComponent({
  90. name: 'modal',
  91. components: {},
  92. props,
  93. setup(props, { emit }) {
  94. const data = reactive({
  95. width: '440px',
  96. wrapClassName: 'modal-wrap',
  97. treeData: [],//机构树,初始化时就获取
  98. zwOption: [],//职位选择
  99. gwOption: [],//岗位选择
  100. jsOption: []//角色选择
  101. })
  102. const form = reactive({
  103. loginName: "",
  104. userName: "",
  105. pwd: '',
  106. mobile: "",
  107. sex: '0',
  108. ssjg: "",
  109. sszw: "",
  110. ssgw: "",
  111. userjsArr: [],
  112. userjs: "",
  113. userid: ""
  114. });
  115. const checkLoginName = (rule, value, callback) => {
  116. if (!value) {
  117. // callback(new Error("请输入用户名"));
  118. return Promise.reject("请输入登录名")
  119. } else {
  120. //如果字符串 string 中含有与 RegExpObject 匹配的文本,则返回 true,否则返回 false。
  121. if (ChineseRegexp.test(value)) {
  122. // callback(new Error("不能输入中文"));
  123. return Promise.reject("不能输入中文")
  124. } else if (EmailRegexp.test(value)) {
  125. // callback(new Error("不能使用邮箱格式"));
  126. return Promise.reject("不能使用邮箱格式")
  127. } else {
  128. return Promise.resolve()
  129. // isAccountExist(value).then(({ data }) => {
  130. // if (data != null) {
  131. // callback(new Error('用户名已存在'));
  132. // } else {
  133. // callback()
  134. // }
  135. // });
  136. }
  137. }
  138. };
  139. const checkMobile = (rule, value, callback) => {
  140. if (!value) {
  141. // callback(new Error("请输入手机号"));
  142. // return Promise.reject("请输入手机号")
  143. return Promise.resolve()
  144. } else {
  145. //如果字符串 string 中含有与 RegExpObject 匹配的文本,则返回 true,否则返回 false。
  146. if (!phoneRegexp.test(value)) {
  147. // callback(new Error("手机号格式不正确"));
  148. return Promise.reject("手机号格式不正确")
  149. } else {
  150. // callback();
  151. return Promise.resolve()
  152. // IsPhoneExist(value).then(({ data }) => {
  153. // if (data != null) {
  154. // callback(new Error("手机号已存在"));
  155. // } else {
  156. // callback();
  157. // }
  158. // });
  159. }
  160. }
  161. };
  162. const checkRole = (rule, value, callback) => {
  163. console.log(value);
  164. if (value === undefined||!value.length) {
  165. // callback(new Error("请选择角色"));
  166. return Promise.reject("请选择角色")
  167. } else {
  168. // callback()
  169. return Promise.resolve()
  170. }
  171. };
  172. const rules = {
  173. loginName: [
  174. { required: true, validator: checkLoginName, trigger: "blur" },
  175. ],
  176. userName: [{
  177. required: true,
  178. message: '请输入姓名',
  179. trigger: 'blur'
  180. }],
  181. pwd: [
  182. { required: false, message: '未填时使用默认密码' },
  183. { pattern: /^(?=.*?[a-z])(?=.*?[A-Z])(?=.*?\d)(?=.*?[~!#@$%^*&()_+{}\[\]|\\;:'",<.>\/?])[a-zA-Z\d~!#@$%^*&()_+{}\[\]|\\;:'",<.>\/?]{8,10}$/, message: '密码中必须包含大小写字母、数字、特殊字符,至少8个字符,最多30个字符' }
  184. ],
  185. mobile: [
  186. { required: false, validator: checkMobile, trigger: "blur" },
  187. ],
  188. sex: [{
  189. required: true,
  190. message: '请选择性别',
  191. trigger: 'blur'
  192. }],
  193. ssjg: [{
  194. required: true,
  195. message: '请选择机构',
  196. trigger: 'change'
  197. }],
  198. sszw: [{
  199. required: true,
  200. message: '请选择职位',
  201. trigger: 'change'
  202. }],
  203. ssgw: [{
  204. required: true,
  205. message: '请选择岗位',
  206. trigger: 'change'
  207. }],
  208. userjsArr: [
  209. { required: true, validator: checkRole, trigger: "blur" },
  210. ],
  211. };
  212. const title = ref(props.title)
  213. const formRef = ref()
  214. onMounted(() => {
  215. structureList().then(res => {
  216. data.treeData = res
  217. })
  218. if (Object.keys(props.formData).length) {
  219. for (let key in form) {
  220. form[key] = props.formData[key]
  221. }
  222. }
  223. roleList().then(res => {
  224. if (res.length) {
  225. res.forEach(item => {
  226. data.jsOption.push({
  227. label: item.groupName,
  228. value: item.groupid
  229. })
  230. })
  231. } else {
  232. message.error('角色数据查询失败')
  233. }
  234. })
  235. if (props.title === '修改用户') {
  236. if (form.ssjg) {
  237. let params1 = {
  238. departmentId: form.ssjg
  239. }
  240. getPostsList(params1).then(res => {
  241. if (res.datas && res.datas?.length) {
  242. res.datas.forEach(item => {
  243. data.zwOption.push({
  244. label: item.departName,
  245. value: item.departid
  246. })
  247. })
  248. } else {
  249. message.info('该部门下无职位数据')
  250. data.zwOption = []
  251. }
  252. })
  253. } else {
  254. data.zwOption = []
  255. }
  256. if (form.sszw) {
  257. let params = {
  258. zwId: form.sszw
  259. }
  260. getPositionList(params).then(res => {
  261. if (res.datas && res.datas.length) {
  262. res.datas.forEach(item => {
  263. data.gwOption.push({
  264. label: item.name,
  265. value: item.id
  266. })
  267. })
  268. } else {
  269. message.info('该职位下无岗位数据')
  270. data.gwOption = []
  271. }
  272. })
  273. } else {
  274. data.gwOption = []
  275. }
  276. }
  277. })
  278. watch(
  279. () => [props.formData, props.title],
  280. ([newF, newD]) => {
  281. for (let key in form) {
  282. form[key] = newF[key]
  283. }
  284. title.value = newD
  285. },
  286. {
  287. immediate: true,
  288. deep: true
  289. }
  290. )
  291. // 查职位
  292. watch(
  293. () => form.ssjg,
  294. (val) => {
  295. form.sszw = ''
  296. data.gwOption = []
  297. if (val !== '') {
  298. //查询职位
  299. let params = {
  300. departmentId: val
  301. }
  302. getPostsList(params).then(res => {
  303. if (res.datas && res.datas?.length) {
  304. res.datas.forEach(item => {
  305. data.zwOption.push({
  306. label: item.departName,
  307. value: item.departid
  308. })
  309. })
  310. } else {
  311. message.info('该部门下无职位数据')
  312. data.zwOption = []
  313. }
  314. })
  315. } else {
  316. data.zwOption = []
  317. }
  318. }
  319. )
  320. // 查岗位
  321. watch(
  322. () => form.sszw,
  323. (val) => {
  324. form.ssgw = ''
  325. if (val !== '') {
  326. //查询岗位
  327. let params = {
  328. zwId: val
  329. }
  330. getPositionList(params).then(res => {
  331. if (res.datas && res.datas.length) {
  332. res.datas.forEach(item => {
  333. data.gwOption.push({
  334. label: item.name,
  335. value: item.id
  336. })
  337. })
  338. } else {
  339. message.info('该职位下无岗位数据')
  340. data.gwOption = []
  341. }
  342. })
  343. } else {
  344. data.gwOption = []
  345. }
  346. }
  347. )
  348. // 关闭请求弹窗
  349. const onClose = () => {
  350. emit('closeModal')
  351. resetForm()
  352. };
  353. const onSubmit = () => {
  354. formRef.value.validate().then(() => {
  355. //此处调用新增
  356. if (title.value === '新增用户') {
  357. form.userid = uuidv4();
  358. form.pwd = form.pwd ? md5(form.pwd) : md5('000000')
  359. }else{
  360. form.pwd = form.pwd ? md5(form.pwd) : ''
  361. }
  362. form.loginName = form.loginName.toUpperCase();
  363. form.userjs = form.userjsArr.join(';');
  364. SaveOrUpdateUserInfo(form).then(res => {
  365. if (res.resp_code === 0) {
  366. message.success('操作成功')
  367. emit('onSubmit', true)
  368. } else if(res.resp_code === 1) {
  369. message.info(res.resp_msg)
  370. emit('onSubmit', false)
  371. }
  372. })
  373. }).catch((error) => {
  374. console.log('error', error);
  375. });
  376. };
  377. const resetForm = () => {
  378. formRef.value.resetFields();
  379. };
  380. return {
  381. form,
  382. rules,
  383. title,
  384. formRef,
  385. ...toRefs(data),
  386. labelCol: { span: 6 },
  387. wrapperCol: { span: 16 },
  388. //func
  389. onClose,
  390. onSubmit
  391. };
  392. },
  393. });
  394. </script>
  395. <style lang="less" scoped>
  396. .modal-wrap {
  397. .content {
  398. padding: 20px 10px 10px 20px;
  399. margin-top: 10px;
  400. .basic-info {
  401. .small-title {
  402. margin-bottom: 10px;
  403. font-family: Source Han Sans CN;
  404. font-size: 14px;
  405. font-weight: bold;
  406. color: #333333;
  407. }
  408. }
  409. }
  410. ::v-deep .ant-modal-footer {
  411. .btn {
  412. width: 64px;
  413. height: 34px;
  414. background-color: red;
  415. }
  416. }
  417. }
  418. </style>