user.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386
  1. <template>
  2. <HcCard>
  3. <template #header>
  4. <div class="w-40">
  5. <el-select v-model="searchForm.deptId" placeholder="选择岗位类型" clearable size="large">
  6. <el-option v-for="item in searchOrganization" :label="item.deptName" :value="item.id"/>
  7. </el-select>
  8. </div>
  9. <div class="w-64 ml-3">
  10. <el-input v-model="searchForm.realName" size="large" placeholder="请输入名称搜索" clearable/>
  11. </div>
  12. <div class="ml-3">
  13. <el-button type="primary" @click="searchClick" size="large">
  14. <HcIcon name="search-2"/>
  15. <span>搜索</span>
  16. </el-button>
  17. </div>
  18. </template>
  19. <template #extra>
  20. <el-button type="primary" @click="addUserClick" size="large">
  21. <HcIcon name="add"/>
  22. <span>创建账户</span>
  23. </el-button>
  24. <el-button type="danger" @click="delClick" size="large" :disabled="tableCheckedKeys.length <= 0">
  25. <HcIcon name="delete-bin-2"/>
  26. <span>注销账户</span>
  27. </el-button>
  28. </template>
  29. <HcTable :column="tableColumn" :datas="tableData" isCheck @selection-change="tableSelectionChange" :loading="tableLoaing">
  30. <template #status="{row}">
  31. <span>{{row.status === 1 ? '启用': '停用'}}</span>
  32. </template>
  33. <template #action="{row}">
  34. <el-button size="small" type="primary" @click="rowEidtClick(row)">编辑</el-button>
  35. </template>
  36. </HcTable>
  37. <template #action>
  38. <HcPages :pages="searchForm" @change="pageChange"></HcPages>
  39. </template>
  40. <!--用户信息弹窗-->
  41. <HcDialog bgColor="#ffffff" isToBody isTable :show="formModal" saveText="确定创建" :title="formModel.id ? '编辑账户' : '创建账户'"
  42. @save="formModalSave" @close="formModalClose" widths="51rem"
  43. >
  44. <HcCardItem ui="hac-bg-grey" class="h-auto">
  45. <template #header>
  46. <div class="hac-card-title">基础信息</div>
  47. </template>
  48. <el-form ref="formRef" :model="formModel" :rules="formRules" size="large" label-width="auto" label-position="left">
  49. <el-form-item label="登录账号:" prop="account">
  50. <el-input v-model="formModel.account" placeholder="仅支持英文或拼音" autocomplete="new-password"/>
  51. </el-form-item>
  52. <el-form-item label="登录密码:" prop="password">
  53. <el-input v-model="formModel.password" placeholder="请输入密码" autocomplete="new-password" show-password type="password"/>
  54. </el-form-item>
  55. <el-form-item label="确认密码:" prop="password1">
  56. <el-input v-model="formModel.password1" placeholder="请输入确认密码" autocomplete="new-password" show-password type="password"/>
  57. </el-form-item>
  58. </el-form>
  59. </HcCardItem>
  60. <HcCardItem ui="hac-bg-grey" class="h-auto mt-4">
  61. <template #header>
  62. <div class="hac-card-title">机构信息</div>
  63. </template>
  64. <template v-for="(item, index) in formModel.deptList">
  65. <el-form :ref="(el) => setFormItemRefs(el, index)" class="mt-4" :model="item" :rules="formRules" label-position="top" size="large">
  66. <el-row :gutter="10">
  67. <el-col :span="7">
  68. <el-form-item prop="deptId">
  69. <el-select v-model="item.deptId" placeholder="选择部门" @change="initPostData($event, index)">
  70. <el-option v-for="item in sectionData" :label="item.deptName" :value="item.id"/>
  71. </el-select>
  72. </el-form-item>
  73. </el-col>
  74. <el-col :span="7">
  75. <el-form-item prop="postId">
  76. <el-select v-model="item.postId" placeholder="选择岗位">
  77. <el-option v-for="item in postData[index]" :label="item.deptName" :value="item.id"/>
  78. </el-select>
  79. </el-form-item>
  80. </el-col>
  81. <el-col :span="7">
  82. <el-form-item prop="principal">
  83. <el-select v-model="item.isLader" placeholder="是否为部门负责人">
  84. <el-option label="是" :value="1"/>
  85. <el-option label="否" :value="0"/>
  86. </el-select>
  87. </el-form-item>
  88. </el-col>
  89. <el-col :span="3">
  90. <div class="form-organization-row-btn">
  91. <el-button type="primary" :icon="Plus" circle size="small" @click="addOrganizationClick(item)"/>
  92. <el-button type="danger" :icon="Delete" circle size="small" :disabled="index===0" @click="delOrganizationClick(index)"/>
  93. </div>
  94. </el-col>
  95. </el-row>
  96. </el-form>
  97. </template>
  98. </HcCardItem>
  99. <HcCardItem ui="hac-bg-grey" class="h-auto mt-4">
  100. <template #header>
  101. <div class="hac-card-title">详细信息</div>
  102. </template>
  103. <el-form ref="formRef1" :model="formModel" :rules="formRules" label-position="left" label-width="auto" size="large">
  104. <el-form-item label="用户姓名:" prop="realName">
  105. <el-input v-model="formModel.realName"/>
  106. </el-form-item>
  107. <el-form-item prop="phone" label="手机号码:">
  108. <el-input v-model="formModel.phone" placeholder="请输入绑定手机"/>
  109. </el-form-item>
  110. <el-form-item label="身份证号:">
  111. <el-input v-model="formModel.idNumber"/>
  112. </el-form-item>
  113. <el-form-item label="日单价:">
  114. <el-input v-model="formModel.key2"/>
  115. </el-form-item>
  116. <el-form-item label="启用状态:">
  117. <el-select v-model="formModel.status" class="block">
  118. <el-option label="启用" :value="1"/>
  119. <el-option label="停用" :value="0"/>
  120. </el-select>
  121. </el-form-item>
  122. </el-form>
  123. </HcCardItem>
  124. </HcDialog>
  125. </HcCard>
  126. </template>
  127. <script setup>
  128. import {ref, onMounted} from "vue";
  129. import {arrIndex, arrToId, isPhone} from "js-fast-way"
  130. import mainApi from '~api/system/user';
  131. import organizationApi from '~api/system/organization';
  132. import {getArrValue} from "js-fast-way"
  133. import {Plus, Delete} from '@element-plus/icons-vue'
  134. import {delMessage} from "~uti/tools";
  135. onMounted(() => {
  136. getTableData()
  137. getOrganization()
  138. })
  139. //获取搜索时的组织结构节点
  140. const searchOrganization = ref([])
  141. const getOrganization = async () => {
  142. const { error, code, data } = await organizationApi.getList({
  143. deptType: 3
  144. })
  145. if (!error && code === 200) {
  146. searchOrganization.value = getArrValue(data)
  147. } else {
  148. searchOrganization.value = []
  149. }
  150. }
  151. const searchForm = ref({deptId: null, realName: '', current: 1, size: 20, total: 0})
  152. //分页被点击
  153. const pageChange = ({current, size}) => {
  154. searchForm.value.current = current
  155. searchForm.value.size = size
  156. getTableData()
  157. }
  158. const searchClick = () => {
  159. searchForm.value.current = 1
  160. getTableData()
  161. }
  162. //表格数据
  163. const tableColumn = [
  164. {key: 'name', name: '用户名称'},
  165. {key: 'account', name: '账号ID'},
  166. {key: 'plaintextPassword', name: '密码'},
  167. {key: 'deptName', name: '所属部门'},
  168. {key: 'postName', name: '岗位'},
  169. {key: 'createTime', name: '创建日期'},
  170. {key: 'status', name: '启用状态'},
  171. {key: 'action', name: '操作', width: 100}
  172. ]
  173. const tableData = ref([])
  174. //获取表格数据
  175. const tableLoaing = ref(false)
  176. const getTableData = async()=>{
  177. tableLoaing.value = true
  178. const { error, code, data } = await mainApi.page(searchForm.value)
  179. tableLoaing.value = false
  180. if (!error && code === 200) {
  181. tableData.value = getArrValue(data['records'])
  182. searchForm.value.total = data['total']
  183. } else {
  184. tableData.value = []
  185. searchForm.value.total = 0
  186. }
  187. }
  188. const tableCheckedKeys = ref([]);
  189. const tableSelectionChange = (rows) => {
  190. tableCheckedKeys.value = rows
  191. }
  192. //用户信息弹窗
  193. const formModal = ref(false)
  194. //用户信息表单
  195. const formRef = ref(null)
  196. const formRef1 = ref(null)
  197. //循环表单的ref
  198. const formRefs = ref([])
  199. const setFormItemRefs = (el, index) => {
  200. if (el) {
  201. let indexs = arrIndex(formRefs.value, 'index', index)
  202. if (indexs !== -1) {
  203. formRefs.value[index].ref = el
  204. } else {
  205. formRefs.value.push({index: index, ref: el});
  206. }
  207. }
  208. }
  209. //获取表单的ref
  210. const getFormRef = async (index) => {
  211. const indexs = arrIndex(formRefs.value, 'index', index)
  212. return formRefs.value[indexs].ref
  213. }
  214. const formModel = ref({
  215. deptList: [{}],
  216. })
  217. const formRules = {
  218. projectId: [{required: true, message: '请选择所属项目', trigger: 'change'}],
  219. phone: {
  220. required: true,
  221. validator: (rule, value, callback) => {
  222. if (!value) {
  223. callback(new Error('请输入手机号'))
  224. } else if (!isPhone(value)) {
  225. callback(new Error('手机号码格式错误'))
  226. } else {
  227. callback()
  228. }
  229. },
  230. trigger: "blur"
  231. },
  232. account: {
  233. required: true,
  234. validator: (rule, value, callback) => {
  235. if (!value) {
  236. callback(new Error('请输入登录账号'))
  237. } else {
  238. callback()
  239. }
  240. },
  241. trigger: "blur"
  242. },
  243. password: {
  244. required: true,
  245. validator: (rule, value, callback) => {
  246. if (!value) {
  247. callback(new Error('请输入新密码'))
  248. } else {
  249. callback()
  250. }
  251. },
  252. trigger: "blur"
  253. },
  254. password1: {
  255. required: true,
  256. validator: (rule, value, callback) => {
  257. if (!value) {
  258. callback(new Error('请确认新密码'))
  259. } else {
  260. callback()
  261. }
  262. },
  263. trigger: "blur"
  264. },
  265. }
  266. //添加用户
  267. const addUserClick = () => {
  268. formModel.value = {
  269. deptList: [{}],
  270. }
  271. postData.value = [{}]
  272. formModal.value = true
  273. getSectionData()
  274. }
  275. //编辑用户信息
  276. const rowEidtClick = (row) => {
  277. row.password = ''
  278. const deptList = getArrValue(row.deptList)
  279. row.deptList = deptList
  280. if (deptList.length > 0){
  281. deptList.forEach(() => {
  282. postData.value.push({})
  283. })
  284. } else {
  285. row.deptList = [{}]
  286. postData.value = [{}]
  287. }
  288. formModel.value = row
  289. formModal.value = true
  290. getSectionData()
  291. }
  292. //部门下拉数据
  293. const sectionData = ref([])
  294. const getSectionData = async () => {
  295. const { error, code, data } = await organizationApi.getList({deptType: 2})
  296. if (!error && code === 200) {
  297. sectionData.value = getArrValue(data)
  298. } else {
  299. sectionData.value = []
  300. }
  301. }
  302. //获取岗位数据
  303. const postData = ref([])
  304. const initPostData = async (id, index) => {
  305. if (id) {
  306. const { error, code, data } = await organizationApi.getList({parentId: id})
  307. if (!error && code === 200) {
  308. postData.value[index] = getArrValue(data)
  309. } else {
  310. postData.value[index] = []
  311. }
  312. }
  313. }
  314. //新增组织
  315. const addOrganizationClick = (row) => {
  316. formModel.value.deptList.push({})
  317. postData.value.push({})
  318. }
  319. //删除组织
  320. const delOrganizationClick = (index) => {
  321. formModel.value.deptList.splice(index, 1)
  322. postData.value.splice(index, 1)
  323. }
  324. //保存
  325. const formModalSave = () => {
  326. console.log(formModel.value)
  327. }
  328. //关闭用户信息弹窗
  329. const formModalClose = () => {
  330. formModal.value = false
  331. formModel.value = {}
  332. }
  333. //删除用户
  334. const delClick = () => {
  335. delMessage(async () => {
  336. const ids = arrToId(tableCheckedKeys.value)
  337. const { error, code, msg } = await mainApi.remove(ids)
  338. if (!error && code === 200) {
  339. window?.$message?.success(msg)
  340. getTableData().then()
  341. } else {
  342. window?.$message?.error(msg)
  343. }
  344. })
  345. }
  346. </script>
  347. <style lang="scss">
  348. .hc-card-item-box.h-auto {
  349. height: auto;
  350. }
  351. .form-organization-row-btn {
  352. position: relative;
  353. margin-left: 8px;
  354. top: 7px;
  355. .el-button + .el-button {
  356. margin-left: 18px;
  357. }
  358. }
  359. </style>