addUser.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. <template>
  2. <el-dialog v-model="showDialog" :title="dialogData.pageType == 'add' ? '新增用户' : dialogData.pageType == 'edit' ? '编辑用户' : ''" width="600px">
  3. <el-form :model="userForm" :rules="rules" ref="userFormRef">
  4. <el-form-item label="学校名称:" :label-width="formLabelWidth" prop="tenantName">
  5. <el-input v-model="userForm.tenantName" placeholder="请输入学校名称" />
  6. </el-form-item>
  7. <el-form-item label="学校简称:" :label-width="formLabelWidth" prop="abbreviation">
  8. <el-input v-model="userForm.abbreviation" placeholder="请输入学校名称" />
  9. </el-form-item>
  10. <el-form-item label="区域:" :label-width="formLabelWidth" required>
  11. <el-form-item prop="provinceCode">
  12. <el-select v-model="userForm.provinceCode" placeholder="请选择" @change="handleProvinceChange" style="width: 100px;">
  13. <el-option
  14. v-for="province in provinceTreeList || []"
  15. :key="province.provinceCode"
  16. :label="province.provinceName"
  17. :value="province.provinceCode"
  18. ></el-option>
  19. </el-select>
  20. <span class="margin_10">省</span>
  21. </el-form-item>
  22. <el-form-item prop="cityCode">
  23. <el-select v-model="userForm.cityCode" placeholder="请选择" @change="handleCityChange" style="width: 100px;">
  24. <el-option
  25. v-for="city in cityTreeList || []"
  26. :key="city.cityCode"
  27. :label="city.cityName"
  28. :value="city.cityCode"
  29. ></el-option>
  30. </el-select>
  31. <span class="margin_10">市</span>
  32. </el-form-item>
  33. <el-form-item prop="areaCode">
  34. <el-select v-model="userForm.areaCode" placeholder="请选择" @change="handleAreaChange" style="width: 100px;">
  35. <el-option
  36. v-for="district in areaList || []"
  37. :key="district.districtCode"
  38. :label="district.districtName"
  39. :value="district.districtCode"
  40. ></el-option>
  41. </el-select>
  42. <span class="margin_10">区/县</span>
  43. </el-form-item>
  44. </el-form-item>
  45. <el-form-item label="账号类型:" :label-width="formLabelWidth" prop="schoolType">
  46. <el-radio-group v-model="userForm.schoolType">
  47. <el-radio :value="0">单校版</el-radio>
  48. <el-radio :value="1">联考版</el-radio>
  49. </el-radio-group>
  50. </el-form-item>
  51. <el-form-item label="用户类型:" :label-width="formLabelWidth" prop="type">
  52. <el-radio-group v-model="userForm.type">
  53. <el-radio :value="1">正式用户</el-radio>
  54. <el-radio :value="0">体验用户</el-radio>
  55. </el-radio-group>
  56. </el-form-item>
  57. <el-form-item label="学校logo:" :label-width="formLabelWidth">
  58. <img v-if="userForm.image" :src="userForm.image" alt="" class="file_image">
  59. <img v-else src="@/assets/school/default_logo.svg" alt="" class="file_image">
  60. <el-upload :http-request="UploadLogo">
  61. <el-button size="small" type="primary">{{ userForm.image ? '重新上传' : '上传logo'}}</el-button>
  62. </el-upload>
  63. </el-form-item>
  64. <el-form-item label="有效时间:" :label-width="formLabelWidth" required>
  65. <el-form-item prop="startDate">
  66. <el-date-picker
  67. v-model="userForm.startDate"
  68. type="date"
  69. placeholder="请选择"
  70. format="YYYY/MM/DD"
  71. value-format="YYYY-MM-DD"
  72. /><span class="margin_10">至</span>
  73. </el-form-item>
  74. <el-form-item prop="endDate">
  75. <el-date-picker
  76. v-model="userForm.endDate"
  77. type="date"
  78. placeholder="请选择"
  79. format="YYYY/MM/DD"
  80. value-format="YYYY-MM-DD"
  81. />
  82. </el-form-item>
  83. </el-form-item>
  84. <el-form-item label="运维负责人:" :label-width="formLabelWidth" prop="sysUserId">
  85. <el-select v-model="userForm.sysUserId" placeholder="请选择" @change="handleUserChange" style="width: 320px;" multiple collapse-tags collapse-tags-tooltip>
  86. <el-option
  87. v-for="item in userList"
  88. :key="item.id"
  89. :label="item.nickname"
  90. :value="item.id"
  91. ></el-option>
  92. </el-select>
  93. </el-form-item>
  94. </el-form>
  95. <template #footer>
  96. <el-button class="button_border_gray cancel" @click="showDialog = false">取消</el-button>
  97. <el-button class="button_background" :loading="submitLoading" @click="SubmitForm(userFormRef)">确定</el-button>
  98. </template>
  99. </el-dialog>
  100. </template>
  101. <script lang="ts">
  102. export default {
  103. name: 'AddUser',
  104. }
  105. </script>
  106. <script lang="ts" setup>
  107. import { ref, reactive, inject, onMounted, nextTick } from 'vue'
  108. import type { FormInstance, FormRules } from 'element-plus'
  109. import { ElMessage } from 'element-plus'
  110. import { getUserList, addUser, uploadFile, provinceTree, getSchoolInfo, editSchoolInfo } from '@/api/school'
  111. interface DialogData {
  112. pageType: string
  113. id: string
  114. }
  115. let showDialog = inject('showDialog')
  116. let dialogData = inject<DialogData>('dialogData')
  117. const formLabelWidth = '120px'
  118. // 新增用户表单数据定义
  119. interface UserForm {
  120. id: string
  121. tenantName: string
  122. abbreviation: string
  123. provinceCode: string
  124. provinceName: string
  125. cityCode: string
  126. cityName: string
  127. areaCode: string
  128. areaName: string
  129. schoolType: number
  130. type: number
  131. image: string
  132. startDate: string
  133. endDate: string
  134. // selUserList: string[]
  135. sysUserId: string[]
  136. }
  137. // 新增用户表单数据初始化
  138. const userForm = reactive<UserForm>({
  139. id: '',
  140. tenantName: '',
  141. abbreviation: '',
  142. provinceCode: '',
  143. provinceName: '',
  144. cityCode: '',
  145. cityName: '',
  146. areaCode: '',
  147. areaName: '',
  148. schoolType: 0,
  149. type: 1,
  150. image: '',
  151. startDate: '',
  152. endDate: '',
  153. // selUserList: [],
  154. sysUserId: []
  155. })
  156. const userFormRef = ref<FormInstance>()
  157. // 表单校验规则
  158. const rules = reactive<FormRules<UserForm>>({
  159. tenantName: [
  160. { required: true, message: '请输入学校名称', trigger: 'blur' }
  161. ],
  162. // abbreviation: [
  163. // { required: true, message: '请输入学校简称', trigger: 'blur' }
  164. // ],
  165. provinceCode: [
  166. { required: true, message: '请选择省', trigger: 'change' }
  167. ],
  168. cityCode: [
  169. { required: true, message: '请选择市', trigger: 'change' }
  170. ],
  171. areaCode: [
  172. { required: true, message: '请选择区/县', trigger: 'change' }
  173. ],
  174. schoolType: [
  175. { required: true, message: '请选择账号类型', trigger: 'change' }
  176. ],
  177. type: [
  178. { required: true, message: '请选择用户类型', trigger: 'change' }
  179. ],
  180. startDate: [
  181. { required: true, message: '请选择开始时间', trigger: 'change' }
  182. ],
  183. endDate: [
  184. { required: true, message: '请选择结束时间', trigger: 'change' }
  185. ],
  186. // sysUserId: [
  187. // { required: true, message: '请选择运维人员', trigger: 'change' }
  188. // ]
  189. })
  190. // 省份列表
  191. const provinceTreeList = ref([])
  192. // 市列表
  193. const cityTreeList = ref([])
  194. // 区/县列表
  195. const areaList = ref([])
  196. // 运维人员列表
  197. const userList = ref([])
  198. // 提交按钮loading
  199. const submitLoading = ref(false)
  200. onMounted (async () => {
  201. await GetProvinceTree()
  202. await GetUserList()
  203. if(dialogData.pageType == 'edit') {
  204. await GetUserDetail()
  205. }
  206. })
  207. // 获取用户详情
  208. const GetUserDetail = () => {
  209. getSchoolInfo(dialogData.id).then(res => {
  210. if(res.code == 200 && res.data) {
  211. const { data } = res
  212. if(data.provinceCode) {
  213. cityTreeList.value = provinceTreeList.value.find(item => item.provinceCode == data.provinceCode).children
  214. }
  215. if(data.cityCode) {
  216. areaList.value = cityTreeList.value.find(item => item.cityCode == data.cityCode).children
  217. }
  218. userForm.id = data.id
  219. userForm.tenantName = data.tenantName
  220. userForm.abbreviation = data.abbreviation
  221. userForm.provinceCode = data.provinceCode
  222. userForm.provinceName = data.provinceName
  223. userForm.cityCode = data.cityCode
  224. userForm.cityName = data.cityName
  225. userForm.areaCode = data.areaCode
  226. userForm.areaName = data.areaName
  227. userForm.schoolType = data.schoolType
  228. userForm.type = data.type
  229. userForm.image = data.image
  230. userForm.startDate = data.startDate
  231. userForm.endDate = data.endDate
  232. // userForm.selUserList = data.selUserList
  233. userForm.sysUserId = data.sysUserId
  234. }
  235. })
  236. }
  237. // 获取运维人员列表
  238. const GetUserList = () => {
  239. getUserList({}).then(res => {
  240. if(res.code == 200 && res.data) {
  241. const { data } = res
  242. userList.value = data
  243. }
  244. })
  245. }
  246. // 获取省市区树列表
  247. const GetProvinceTree = (): Promise<void> => {
  248. return new Promise((resolve, reject) => {
  249. provinceTree().then(res => {
  250. if(res.code == 200 && res.data) {
  251. const { data } = res
  252. provinceTreeList.value = data
  253. resolve()
  254. }
  255. })
  256. })
  257. }
  258. const fileImageUrl = ref('')
  259. // 选择省份
  260. const handleProvinceChange = (val) => {
  261. userForm.provinceCode = val
  262. userForm.provinceName = provinceTreeList.value.find(item => item.provinceCode == val).provinceName
  263. cityTreeList.value = provinceTreeList.value.find(item => item.provinceCode == val).children
  264. areaList.value = []
  265. userForm.cityCode = ''
  266. userForm.areaCode = ''
  267. }
  268. // 选择市
  269. const handleCityChange = (val) => {
  270. userForm.cityCode = val
  271. userForm.cityName = cityTreeList.value.find(item => item.cityCode == val).cityName
  272. areaList.value = cityTreeList.value.find(item => item.cityCode == val).children
  273. userForm.areaCode = ''
  274. }
  275. // 选择区/县
  276. const handleAreaChange = (val) => {
  277. userForm.areaCode = val
  278. userForm.areaName = areaList.value.find(item => item.districtCode == val).districtName
  279. }
  280. // 上传学校logo
  281. const UploadLogo = (file) => {
  282. let formData = new FormData();
  283. formData.append("file", file.file);
  284. uploadFile(formData).then(res => {
  285. console.log(res)
  286. if(res.code == 200 && res.data) {
  287. const { data } = res
  288. userForm.image = data.url
  289. }
  290. })
  291. }
  292. // 选择运维人员
  293. const handleUserChange = (val) => {
  294. console.log(val)
  295. let result = userList.value.filter(item => val.includes(item.id)).map(item => {
  296. return { id: item.id }
  297. })
  298. console.log(result)
  299. // userForm.selUserList = val
  300. userForm.sysUserId = val
  301. }
  302. const emit = defineEmits(['AddUser'])
  303. // 表单提交
  304. const SubmitForm = async (formEl: FormInstance | undefined) => {
  305. if (!formEl) return
  306. await formEl.validate(async(valid, fields) => {
  307. if (valid) {
  308. submitLoading.value = true
  309. try {
  310. let res
  311. if(dialogData.pageType == 'add') {
  312. res = await addUser(userForm)
  313. }else if(dialogData.pageType == 'edit') {
  314. res = await editSchoolInfo(userForm)
  315. }
  316. if (res.code == 200) {
  317. ElMessage.success(res.msg)
  318. userFormRef.value.resetFields()
  319. emit('AddUser', false)
  320. } else {
  321. ElMessage.error(res.msg)
  322. }
  323. submitLoading.value = false
  324. }catch {
  325. submitLoading.value = false
  326. }
  327. }
  328. })
  329. }
  330. </script>
  331. <style lang="scss" scoped>
  332. .file_image {
  333. width: 48px;
  334. height: 48px;
  335. margin-right: 10px;
  336. border-radius: 50%;
  337. }
  338. .margin_10 {
  339. margin: 0 10px;
  340. }
  341. .el-input {
  342. width: 320px;
  343. }
  344. .el-upload .el-button {
  345. width: 76px;
  346. height: 32px;
  347. background: #2E64FA1A;
  348. color: #2E64FA;
  349. border: none;
  350. }
  351. </style>