AccountModal1.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  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="请输入登录名" />
  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. } else {
  144. //如果字符串 string 中含有与 RegExpObject 匹配的文本,则返回 true,否则返回 false。
  145. if (!phoneRegexp.test(value)) {
  146. // callback(new Error("手机号格式不正确"));
  147. return Promise.reject("手机号格式不正确")
  148. } else {
  149. // callback();
  150. return Promise.resolve()
  151. // IsPhoneExist(value).then(({ data }) => {
  152. // if (data != null) {
  153. // callback(new Error("手机号已存在"));
  154. // } else {
  155. // callback();
  156. // }
  157. // });
  158. }
  159. }
  160. };
  161. const checkRole = (rule, value, callback) => {
  162. if (!value.length) {
  163. // callback(new Error("请选择角色"));
  164. return Promise.reject("请选择角色")
  165. } else {
  166. // callback()
  167. return Promise.resolve()
  168. }
  169. };
  170. const rules = {
  171. loginName: [
  172. { validator: checkLoginName, trigger: "change" },
  173. ],
  174. userName: [{
  175. required: true,
  176. message: '请输入姓名',
  177. trigger: 'blur'
  178. }],
  179. pwd: [
  180. { required: true, message: '密码不能为空' },
  181. { pattern: /^(?=.*[A-Z])(?=.*[a-z])(?=.*\d)(?=.*\W)[\S]{8,30}$/, message: '密码中必须包含大小写字母、数字、特殊字符,至少8个字符,最多30个字符' }
  182. ],
  183. mobile: [
  184. { validator: checkMobile, trigger: "change" },
  185. ],
  186. sex: [{
  187. required: true,
  188. message: '请选择性别',
  189. trigger: 'blur'
  190. }],
  191. sszw: [{
  192. required: true,
  193. message: '请选择职位',
  194. trigger: 'blur'
  195. }],
  196. ssgw: [{
  197. required: true,
  198. message: '请选择岗位',
  199. trigger: 'blur'
  200. }],
  201. userjsArr: [
  202. { validator: checkRole, trigger: "change" },
  203. ],
  204. };
  205. const title = ref(props.title)
  206. const formRef = ref()
  207. onMounted(() => {
  208. if (Object.keys(props.formData).length) {
  209. for (let key in form) {
  210. form[key] = props.formData[key]
  211. }
  212. }
  213. structureList().then(res => {
  214. data.treeData = res
  215. })
  216. roleList().then(res => {
  217. if (res.length) {
  218. res.forEach(item => {
  219. data.jsOption.push({
  220. label: item.groupName,
  221. value: item.groupid
  222. })
  223. })
  224. } else {
  225. message.error('角色数据查询失败')
  226. }
  227. })
  228. if (props.title === '修改用户') {
  229. let params1 = {
  230. departmentId: form.ssjg
  231. }
  232. getPostsList(params1).then(res => {
  233. if (res.datas && res.datas?.length) {
  234. res.datas.forEach(item => {
  235. data.zwOption.push({
  236. label: item.departName,
  237. value: item.departid
  238. })
  239. })
  240. } else {
  241. message.info('该部门下无职位数据')
  242. data.zwOption = []
  243. }
  244. })
  245. let params = {
  246. zwId: form.sszw
  247. }
  248. getPositionList(params).then(res => {
  249. if (res.datas && res.datas.length) {
  250. res.datas.forEach(item => {
  251. data.gwOption.push({
  252. label: item.name,
  253. value: item.id
  254. })
  255. })
  256. } else {
  257. message.info('该职位下无岗位数据')
  258. data.gwOption = []
  259. }
  260. })
  261. }
  262. })
  263. watch(
  264. () => [props.formData, props.title],
  265. ([newF, newD]) => {
  266. for (let key in form) {
  267. form[key] = newF[key]
  268. }
  269. title.value = newD
  270. },
  271. {
  272. immediate: true,
  273. deep: true
  274. }
  275. )
  276. // 查职位
  277. watch(
  278. () => form.ssjg,
  279. (val) => {
  280. data.gwOption = []
  281. if (val !== '') {
  282. //查询职位
  283. let params = {
  284. departmentId: val
  285. }
  286. getPostsList(params).then(res => {
  287. if (res.datas && res.datas?.length) {
  288. res.datas.forEach(item => {
  289. data.zwOption.push({
  290. label: item.departName,
  291. value: item.departid
  292. })
  293. })
  294. } else {
  295. message.info('该部门下无职位数据')
  296. data.zwOption = []
  297. }
  298. })
  299. } else {
  300. data.zwOption = []
  301. }
  302. }
  303. )
  304. // 查岗位
  305. watch(
  306. () => form.sszw,
  307. (val) => {
  308. if (val !== '') {
  309. //查询岗位
  310. let params = {
  311. zwId: val
  312. }
  313. getPositionList(params).then(res => {
  314. if (res.datas && res.datas.length) {
  315. res.datas.forEach(item => {
  316. data.gwOption.push({
  317. label: item.name,
  318. value: item.id
  319. })
  320. })
  321. } else {
  322. message.info('该职位下无岗位数据')
  323. data.gwOption = []
  324. }
  325. })
  326. } else {
  327. data.gwOption = []
  328. }
  329. }
  330. )
  331. // 关闭请求弹窗
  332. const onClose = () => {
  333. emit('closeModal')
  334. resetForm()
  335. };
  336. const onSubmit = () => {
  337. formRef.value.validate().then(() => {
  338. //此处调用新增
  339. if (title.value === '新增用户') {
  340. form.userid = uuidv4();
  341. }
  342. form.loginName = form.loginName.toUpperCase();
  343. form.userjs = form.userjsArr.join(';');
  344. form.pwd = md5(form.pwd)
  345. SaveOrUpdateUserInfo(form).then(res => {
  346. if (res) {
  347. message.success('操作成功')
  348. emit('onSubmit', true)
  349. } else {
  350. message.success('操作失败')
  351. emit('onSubmit', false)
  352. }
  353. })
  354. }).catch((error) => {
  355. console.log('error', error);
  356. });
  357. };
  358. const resetForm = () => {
  359. formRef.value.resetFields();
  360. };
  361. return {
  362. form,
  363. rules,
  364. title,
  365. formRef,
  366. ...toRefs(data),
  367. labelCol: { span: 6 },
  368. wrapperCol: { span: 16 },
  369. //func
  370. onClose,
  371. onSubmit
  372. };
  373. },
  374. });
  375. </script>
  376. <style lang="less" scoped>
  377. .modal-wrap {
  378. .content {
  379. padding: 20px 10px 10px 20px;
  380. margin-top: 10px;
  381. .basic-info {
  382. .small-title {
  383. margin-bottom: 10px;
  384. font-family: Source Han Sans CN;
  385. font-size: 14px;
  386. font-weight: bold;
  387. color: #333333;
  388. }
  389. }
  390. }
  391. ::v-deep .ant-modal-footer {
  392. .btn {
  393. width: 64px;
  394. height: 34px;
  395. background-color: red;
  396. }
  397. }
  398. }
  399. </style>